Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Помогите оптимизировать (http://www.flasher.ru/forum/showthread.php?t=118782)

vasko.da.gamo 03.12.2008 17:08

Помогите оптимизировать
 
Сделал программу для расчета числа линий по 1й формуле Эрланга:Формула для расчета
Дело в том, что при больших значениях нагрузки Y компьютер говорит, что ему не хватает памяти. Для расчетов используются такие числа как 10^1500 и больше. Я сделал так, что степень 10^X заносится в счетчик. Потому как в формуле мы делили бесконечность/бесконечность - получали мало.
Делаю с изменение шага (для оптимальности)
З.Ы. За синтакси пожалуйста не пинать...

Пример: Нагрузка Y=200 Эрл. Вероятность Р=0.005
Итоговое число линий - 227
[IMG]http://i019.***********/0812/ec/c4c90748adf3.jpg[/IMG]
Вот собственно код(можно просто вставить в фрейм и все)
Код AS1/AS2:

//Прогамма для расчета числа линий по 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);//получим конечное число линий

Результаты трассировки:
Цитата:

шаг № 1:к-во линий=100;вероятность=0.504814362301093;отн.дроби=0.504814362301093;сч.степеней=0
шаг № 2:к-во линий=200;вероятность=0.0543524228386104;отн.дроби=0.0543524228386104;сч.степеней=0
шаг № 3:к-во линий=300;вероятность=9.21084077342936e-12;отн.дроби=9.21084077342936;сч.степеней=-4
шаг № 4:к-во линий=250;вероятность=0.000077471107936553;отн.дроби=0.077471107936553;сч.степеней=-1
шаг № 5:к-во линий=225;вероятность=0.00615719796255427;отн.дроби=6.15719796255427;сч.степеней=-1
шаг № 6:к-во линий=250;вероятность=0.000077471107936553;отн.дроби=0.077471107936553;сч.степеней=-1
шаг № 7:к-во линий=237;вероятность=0.00103072516893974;отн.дроби=1.03072516893974;сч.степеней=-1
шаг № 8:к-во линий=230;вероятность=0.00313135020914853;отн.дроби=0.00313135020914853;сч.степеней=0
шаг № 9:к-во линий=226;вероятность=0.00541931871187882;отн.дроби=0.00541931871187882;сч.степеней=0
шаг № 10:к-во линий=230;вероятность=0.00313135020914853;отн.дроби=0.00313135020914853;сч.степеней=0
шаг № 11:к-во линий=228;вероятность=0.00415115262004001;отн.дроби=4.15115262004001;сч.степеней=-1
шаг № 12:к-во линий=227;вероятность=0.00475204043193517;отн.дроби=4.75204043193517;сч.степеней=-1
227
Добавлено через 9 часов 13 минут
Хмм...один из выходов писать в AS3.(Только что узнал, что намного производительнее AS2)

Просто вставил код и мне выдает единственную ошибку:

Цитата:

1084: Syntax error: expecting rightparen before and.
с сылкй на строку
Код AS1/AS2:

if(VPer>1 and E<P){E=1;V = VMax-Math.ceil(VPer*0.5);VPer=Math.ceil(VPer/2);}


Вот сижу и думаю что не так... пока ничего не делал на AS3(никак перейти не могу)
Сделал в AS3
Код AS1/AS2:

//задаем типы переменных
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);//Полученное число линий



Часовой пояс GMT +4, время: 11:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.