![]() |
|
||||||||||
|
|||||
|
Регистрация: Jun 2007
Сообщений: 1
|
Сделал программу для расчета числа линий по 1й формуле Эрланга:Формула для расчета
Дело в том, что при больших значениях нагрузки Y компьютер говорит, что ему не хватает памяти. Для расчетов используются такие числа как 10^1500 и больше. Я сделал так, что степень 10^X заносится в счетчик. Потому как в формуле мы делили бесконечность/бесконечность - получали мало. Делаю с изменение шага (для оптимальности) З.Ы. За синтакси пожалуйста не пинать... Пример: Нагрузка Y=200 Эрл. Вероятность Р=0.005 Итоговое число линий - 227 [IMG]http://i019.***********/0812/ec/c4c90748adf3.jpg[/IMG] Вот собственно код(можно просто вставить в фрейм и все) //Прогамма для расчета числа линий по 1й формуле Эрланга var YM=[V];var YK=[V];//массивы для YM - чисел и YK - счетчиков YM[0]=1;YK[0]=0; Y = 200;//наша нагрузка P = 0.005;//требуемая вероятность - стремимся к этому значению E = 1;j = 1;//меряем шаги для оптимальности VPer = Math.ceil(Y/2); V=VPer;//VPer - для шага(меняем шаг, чтобы уменьшить число действий) //будем выполнять до тех пор пока вероятность не будет меньше нашей while (E>P) { f = 0; V1 = 1; Y1 = 1; //Далее следует функция для расчета числа V в степеени N F1 = 0;//F1 -счетчик степеней для показательной функции в числителе F2 = 0;//F2 - счетчик степеней для факториала //если число на шаге i больше 10 то мы делим его на 1000 для надежности(чтобы число не превысило 10^300) for (i=1; i<=V; i++) { Y1 = Y*Y1; if (Y1>10) { Y1 = Y1/1000; F1 = F1+1; } } //Факториал V for (w=1; w<=V; w++) { V1 = V1*(f+1); f = f+1; if (V1>10) { V1 = V1/1000; F2 = F2+1; } } B = Y1/V1;//Отношение верхней части дроби F3 = F1-F2;//F3 - счетчик для числителя) //производим суммирование от 0 до V,где V - число линий (нижняя часть дроби) D = 0;//D - переменная для суммирования for (i=1; i<=V; i++) { Y2 = 1; F4 = 0;//F4 - счетчик степеней для показательной функции в знаменателе for (m=1; m<=i; m++) { Y2 = Y*Y2; if (Y2>10) { Y2 = Y2/1000;F4 = F4+1;} ;} //расчеты для факториала в нижней дроби S = 1; f = 0; F5=0;//F5 - счетчик степеней для факториала в знаменателе for (g=1; g<=i; g++) { S = S*(f+1); f = f+1; if (S>10) { S = S/1000;F5 = F5+1;} ;} F6=F4-F5;T = Y2/S; //Для дальнейших расчетов вносим число и счетчик его степени в массивы(каждый по отдельности) YM[i]=T;YK[i]=F6; } //расчеты для суммирования закончены - результаты в МАССИВАХ!!! Max=0;//ищем максимальную степень и вычитаем ее из всех степеней for(i=0;i<=V;i++){if(YK[i]>Max){Max=YK[i];};} for(i=0;i<=V;i++){D=D+YM[i]*Math.pow(1000,YK[i]-Max);} F7=Max;//Делаем это для нашего удобства, чтобы не запутаться в переменных E1 = B/D;//итоговая дробь F8=F3-F7;//F8 - итоговая степень при 1000^X или 10^(3X) E=E1*Math.pow(1000,F8);//наша вероятность (число F8 Не превышает 100) //выводим результаты для поиска ошибок и сравнения E2="шаг № "+j+":к-во линий="+V.toString()+";вероятность="+E.toString()+";отн.дроби="+E1.toString()+";сч.степеней="+F8.toString(); trace(E2); VMax=V; //Измением величину шага для оптимальности; if(E<P and VPer>1){E=1;V = VMax-Math.ceil(VPer*0.5);VPer=Math.ceil(VPer/2);} else{V = V+VPer;} j=j+1;//считаем шаги дедовским способом } trace(V-1);//получим конечное число линий Цитата:
Хмм...один из выходов писать в AS3.(Только что узнал, что намного производительнее AS2) Просто вставил код и мне выдает единственную ошибку: Цитата:
Сделал в AS3 //задаем типы переменных var Y,P,i,w,j,f,F1,F2,F3,F4,F5,F6,Max,VMax,V,VPer:int;//счетчики var YN,VN,B,D,T,E,E1:Number;//значения для расчета var K,M:String; var YM,YK:Array; //Приступаем к решению Y = 100; P = 0.001; E = 1; j = 1;//меряем шаги для оптимальности VPer = Math.ceil(Y/2); V=VPer;//VPer - для шага(меняем шаг, чтобы уменьшить число действий) while (E>P) { YN=1; YM=[V]; YK=[V]; YM[0]=1; YK[0]=0; for (i=1; i<=V; i++) { YN = Y*YN; if (YN>10) { YN = YN/1000; F1 += 1; } } //Факториал V f = 0; VN = 1; for (i=1; i<=V; i++) { VN = VN*(f+1); f += 1; if (VN>10) { VN = VN/1000; F2 += 1; } } B = YN/VN;//Отношение верхней части дроби F3 = F1-F2;//F3 - счетчик для числителя //производим суммирование от 0 до V,где V - число линий (нижняя часть дроби) D = 0;//D - переменная для суммирования for (w=1; w<=V; w++) { YN = 1; F1 = 0;//F1 - счетчик степеней для показательной функции в знаменателе for (i=1; i<=w; i++) { YN = Y*YN; if (YN>10) { YN = YN/1000; F1 += 1; } } //расчеты для факториала в нижней дроби f = 0; VN = 1; F2=0;//F2 - счетчик степеней для факториала в знаменателе for (i=1; i<=w; i++) { VN = VN*(f+1); f += 1; if (VN>10) { VN = VN/1000; F2 += 1; } } F4=F1-F2; T = YN/VN; //Для дальнейших расчетов вносим число и счетчик его степени в массивы(каждый по отдельности) YM[w]=T; YK[w]=F4; } //расчеты для суммирования закончены - результаты в МАССИВАХ!!! Max=0;//ищем максимальную степень и вычитаем ее из всех степеней for(i=0;i<=V;i++) { if(YK[i]>Max) { Max=YK[i]; } } for(i=0;i<=V;i++) { D=D+YM[i]*Math.pow(1000,YK[i]-Max); } F5=Max;//Делаем это для нашего удобства, чтобы не запутаться в переменных E1=B/D;//итоговая дробь F6=F3-F5;//F6 - итоговая степень при 1000^X или 10^(3X) E=E1*Math.pow(1000,F6);//наша вероятность (число F6 Не превышает 100) //выводим результаты для поиска ошибок и сравнения K="шаг № "+j+":к-во линий="+V.toString()+";вероятность="+E.toString()+";отн.дроби="+E1.toString()+";сч.степеней="+F6.toString(); trace(K); VMax=V; //Измением величину шага для оптимальности; if(E<P && VPer>1) { E=1; V = VMax-Math.ceil(VPer*0.5); VPer=Math.ceil(VPer/2); } else { V = V+VPer; } j=j+1;//считаем шаги дедовским способом } trace(V-1);//Полученное число линий Последний раз редактировалось vasko.da.gamo; 12.06.2010 в 19:26. |
![]() |
![]() |
Часовой пояс GMT +4, время: 10:00. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|