IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Оптимизация функции нескольких переменных, Метод градиентного дробления шага
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 28
Пол: Мужской

Репутация: -  0  +


Ребят, написал код по блок-схеме, вроде все правильно, НО тут мне выскакивает неизвестная мне ошибка( за год работы с паскалем впервые такую встретил) - 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.


Сообщение отредактировано: 3 kilos -


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 9)
сообщение
Сообщение #2


Гость






Цитата
выскакивает неизвестная мне ошибка( за год работы с паскалем впервые такую встретил) - Floating point overflov

Обычная ошибка - переполнение числа с плавающей точкой. Не хватает емкости Real для того, чтобы сохранить число, полученное в результате вычислений...

Переходи на сопроцессорные типы: Double или Extended, они гораздо более емкие...
Не забудь подключить использование сопроцессора:
{$N+}
первой строкой программы...

Кстати, после замены всех Real на Double выяснилось, что твоя программа зацикливается...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 28
Пол: Мужской

Репутация: -  0  +


volvo

Значит на паскале программу не написать (я просто не знаком с Delphi)? Или я ошибся где-то в написании программы по блок-схеме....
Возможно ошибка какимто образом связана с возведением 2 в степень j ( именно эта строчка выделяется j:=j*2; ).. может я чет не то делаю?

Сообщение отредактировано: 3 kilos -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата(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 - все значения неизменны, и цикл - бесконечен.

Где-то ты ошибся в реализации...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Новичок
*

Группа: Пользователи
Сообщений: 28
Пол: Мужской

Репутация: -  0  +


Чобы не постить заново весь код, поменял его в первом посте, теперь ошибка выскакивает на возведении 2 в степень j. Хотя может я чет не то передаю в функции и процедуры... вместо V надо V0....

Сообщение отредактировано: 3 kilos -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Зачем у тебя в процедуре GDH стоит while (j>=0) do ? Получается бесконечный цикл, т.к. j только увеличивается. Отсюда и переполнение.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Новичок
*

Группа: Пользователи
Сообщений: 28
Пол: Мужской

Репутация: -  0  +


Цитата(Malice @ 17.04.2006 10:57) *

Зачем у тебя в процедуре GDH стоит while (j>=0) do ? Получается бесконечный цикл, т.к. j только увеличивается. Отсюда и переполнение.


А как тогда задать цикл для возведения 2 в степень j ?
Например задал обычный цикл для 3ех итераций For j:=0 to 2 - все равно идет зацикливание...

Сообщение отредактировано: 3 kilos -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата(3 kilos @ 19.04.2006 0:55)
А как тогда задать цикл для возведения 2 в степень j ?

Вообще-то, чтобы возвести 2 в степень J вообще никакие циклы не нужны, достаточно сделать
{что-то} := 2 shl (j - 1)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


а почему не
что-то:=1 shl j
? У тебе не будет нулевой степени.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Новичок
*

Группа: Пользователи
Сообщений: 28
Пол: Мужской

Репутация: -  0  +


Сегодня с перподователем налаживали прогу, нашли пару багов, процедура ГДШ работает правильно, а вот в основной программе почемуто все зацикливается. На днях думаю скину правильный код, препод пообещал порыться на кафедре.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 28.03.2024 19:34
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name