Форум «Всё о Паскале» _ Задачи _ Оптимизация функции нескольких переменных
Автор: 3 kilos 16.04.2006 18:25
Ребят, написал код по блок-схеме, вроде все правильно, НО тут мне выскакивает неизвестная мне ошибка( за год работы с паскалем впервые такую встретил) - Floating point overflov. Аналитичесое решения данного уравнения 6*x*x+3*y*y+10 дает нам координаты точки минимума (0;0). Начальную точку можно выбрать с кординатами (1;1) V- шаг дробления можно взять за 2
Очень прошу помощи, разобраться осталась малость. Выкладываю блок-схему и код( код чуть чуть в целях личного удобства отличается от схемы, но разницы собсно значимой нету).
Код
Program MnogOptim; Uses Crt; var j,k:integer; x,y,s,V,V0,t,p,eps:real;
Function F(var x,y:real):real; begin f:=6*x*x+3*y*y+10; end;
Function G1(var x:real):real; {частная производная по Х} begin g1:=12*x; end;
Function G2(var y:real):real; {частная производная по Y} begin g2:=6*y; end;
procedure GDH(var x,y,V:real); var p,h1,h2,q,z:real; begin V:=V0; j:=0; s:=f(x,y); while (j>=0) do begin {цикл для возведения 2 в степень j} j:=j*2; repeat j:=j*2; if j=0 then j:=1 else h1:=g1(x); h2:=g2(y); q:=x-(V*h1)/j*2; z:=y-(V*h2)/j*2; p:=f(q,z); t:=((h1*h1+h2*h2)*V)/(j+1)*2; until (P<=(S-T)); V:=V/j*2; j:=j+1 end; end; Procedure Input(var x,y,V0,eps:real); begin writeln(''); writeln(' Vvedite koordinati na4alnoi to4ki (x,y)'); writeln(''); write(' x='); read(x); write(' y='); read(y); writeln(''); writeln('zadaite na4alnii shag V0'); readln(V0); writeln(''); writeln(' Zadaite to4nost eps'); writeln(''); write(' eps='); read(eps); end;
Procedure Otrezok(k: integer; var p,x,y,eps:real); var h1,h2,f1:real; begin writeln(''); k:=0; Repeat GDH(x,y,V); h1:=g1(x); h2:=g2(y); x:=x-V*h1; y:=y-V*h2; f1:=f(x,y); k:=k+1; until ((abs(h1)<eps) and (abs(h2)<eps)); writeln(''); writeln(' X = ',x:5:4); writeln(' Y = ',y:5:4); writeln(' Zna4enie funkcii F = ',f(x,y):0:0); readln; end;
begin TextBackGround(white); TextColor(blue); ClrScr; Input(x,y,V0,eps); Otrezok(k,p,x,y,eps); readln; end.
Эскизы прикрепленных изображений
Автор: volvo 16.04.2006 18:36
Цитата
выскакивает неизвестная мне ошибка( за год работы с паскалем впервые такую встретил) - Floating point overflov
Обычная ошибка - переполнение числа с плавающей точкой. Не хватает емкости Real для того, чтобы сохранить число, полученное в результате вычислений...
Переходи на сопроцессорные типы: Double или Extended, они гораздо более емкие... Не забудь подключить использование сопроцессора:
{$N+}
первой строкой программы...
Кстати, после замены всех Real на Double выяснилось, что твоя программа зацикливается...
Автор: 3 kilos 16.04.2006 18:38
volvo
Значит на паскале программу не написать (я просто не знаком с Delphi)? Или я ошибся где-то в написании программы по блок-схеме.... Возможно ошибка какимто образом связана с возведением 2 в степень j ( именно эта строчка выделяется j:=j*2; ).. может я чет не то делаю?
Автор: volvo 16.04.2006 18:46
Цитата(3 kilos @ 16.04.2006 14:38)
Значит на паскале программу не написать
Почему же сразу "не написать"? Еще как можно написать... Просто у тебя в процедуре Otrezok вот здесь:
Repeat GDH(x,y,V); h1:=g1(x); h2:=g2(y); x:=x-V*h1; y:=y-V*h2; f1:=f(x,y); k:=k+1; until ((abs(h1)<eps) and (abs(h2)<eps));
Значения H1 и H2 не изменяются (при приведенных тобой исходных данных), а остаются постоянно: H1 = 12 и H2 = 6 То же самое касается и X, Y, V - все значения неизменны, и цикл - бесконечен.
Где-то ты ошибся в реализации...
Автор: 3 kilos 16.04.2006 18:51
Чобы не постить заново весь код, поменял его в первом посте, теперь ошибка выскакивает на возведении 2 в степень j. Хотя может я чет не то передаю в функции и процедуры... вместо V надо V0....
Автор: Malice 17.04.2006 13:57
Зачем у тебя в процедуре GDH стоит while (j>=0) do ? Получается бесконечный цикл, т.к. j только увеличивается. Отсюда и переполнение.
Автор: 3 kilos 19.04.2006 4:55
Цитата(Malice @ 17.04.2006 10:57)
Зачем у тебя в процедуре GDH стоит while (j>=0) do ? Получается бесконечный цикл, т.к. j только увеличивается. Отсюда и переполнение.
А как тогда задать цикл для возведения 2 в степень j ? Например задал обычный цикл для 3ех итераций For j:=0 to 2 - все равно идет зацикливание...
Автор: volvo 19.04.2006 11:56
Цитата(3 kilos @ 19.04.2006 0:55)
А как тогда задать цикл для возведения 2 в степень j ?
Вообще-то, чтобы возвести 2 в степень J вообще никакие циклы не нужны, достаточно сделать
{что-то} := 2 shl (j - 1)
Автор: Malice 19.04.2006 12:14
а почему не
что-то:=1 shl j
? У тебе не будет нулевой степени.
Автор: 3 kilos 19.04.2006 19:53
Сегодня с перподователем налаживали прогу, нашли пару багов, процедура ГДШ работает правильно, а вот в основной программе почемуто все зацикливается. На днях думаю скину правильный код, препод пообещал порыться на кафедре.