Pascal, как убрать оператор goto и выполнить форматирование кода?

Добрый день. Дано задание
Реализовать метод Хука-Дживса с поиском по образцу и
проверить его работу на примере. Учесть возможность добавления
ограничений различного типа(>=<) при поиске экстремума.
F(x,y)=2(x-1)2+(y-2x)2 -> min
Сделал, но не могу понять как убрать оператор goto(Или его заменить) и выполнить форматирование кода

program HuDjMody;
uses crt;
label 0,1,2,3,4,5,6,7;
var k,h,z,ps,bs,fb,fi :real;
i,j,n,fe :integer;
x,y,b,p :array[1..10] of real;
procedure calculate;
 
begin
z:=2*sqr(x[1]-1)+sqr(x[2]-2*x[1]);
if (x[1]<0) or (x[2]<0) or ((x[1]+x[2])<4) then
z:=1.7e+38;
fe:=fe+1;
end;
 
begin
clrscr;
gotoxy(20,2);
writeln('Модифицированный метод Хука-Дживса');
gotoxy(23,3);
writeln('( при наличии ограничений )');
writeln;
writeln('Введите число переменных:');
readln(n);
writeln('Введите начальную точку x1,x2,…,xN');
for i:=1 to n do
readln(x[i]);
writeln;
writeln('Введите длину шага');
readln(h);
k:=h;
fe:=0;
for i:=1 to n do
  
begin
y[i]:=x[i];
p[i]:=x[i];
b[i]:=x[i];
end;
calculate;
fi:=z;
writeln('Начальное значение функции', z:2:3);
for i:=1 to n do
writeln(x[i]:2:3);
ps:=0;
bs:=1;
j:=1;
fb:=fi;
0: x[j]:=y[j]+k;
calculate;
if z<fi then goto 1;
x[j]:=y[j]-k;
calculate;
if z<fi then goto 1;
x[j]:=y[j];
goto 2;
1: y[j]:=x[j];
2: calculate;
fi:=z;
writeln('Пробный шаг',' ', z:2:3);
for i:=1 to n do
writeln(x[i]:2:3);
if j=n then goto 3;
j:=j+1;
goto 0;
3: if fi<fb-1e-08 then goto 6;
if (ps=1) and (bs=0) then
goto 4;
goto 5;
4: for i:=1 to n do
  
begin
p[i]:=b[i];
y[i]:=b[i];
x[i]:=b[i];
end;
calculate;
bs:=1;
ps:=0;
fi:=z;
fb:=z;
writeln('Замена базисной точки',' ',z:2:3);
for i:=1 to n do
writeln(x[i]:1:3);
j:=1;
goto 0;
5: k:=k/10;
writeln('Уменьшить длину шага');
if k<1e-08 then goto 7;
j:=1;
goto 0;
6: for i:=1 to n do
  
begin 
p[i]:=2*y[i]-b[i];
b[i]:=y[i];
x[i]:=p[i];
y[i]:=x[i];
end;
calculate;
fb:=fi;
ps:=1;
bs:=0;
fi:=z;
writeln('Поиск по образцу',' ',z:2:3);
for i:=1 to n do
writeln(x[i]:2:3);
j:=1;
goto 0;
7: writeln('Минимум найден');
for i:=1 to n do
writeln('x(',i,')=',p[i]:2:3);
writeln;
writeln('Минимум функции равен',' ',fb:2:3);
writeln('Количество вычислений функции равно',' ',fe);
repeat until keypressed;
end.

Форматирование отступами в Паскале

Для приведения уже имеющегося кода в более-менее норм вид можно засунуть его в какой-нибудь онлайн форматер или нажать соответствующую кнопку в некоторых редакторах кода/IDE.

Забыть о его существовании и искать другие способы в языке ) Циклы, функции/процедуры, …

Тут goto что-то много, и сложно разобраться что вообще программа делает, так что может проще переписать с нуля.

1 лайк

Кроме goto есть и другие операторы. Например case, else. Используйте их вместо goto.

1 лайк

Пытался использовать другие операторы, но не обвенчалось успехом(
Полностью переписывать просто по времени не выходит

АлексейSraster, Alex верно подсказывает. Если без goto весь код нужно кардинально переписывать.

1 лайк

Надо для начала разобраться что вообще этот метод Хука-Дживса делает, может быть найти псевдокод или примеры на других языках.

Вообще тут что-то очень странное с учебной программой, если просят реализовать что-то достаточно сложное математическое, а основы программирования еще не изучены… (раз возникают такие вопросы про goto и оформление кода) :dadparrot:


ЗЫ исправил ссылку выше

Если расчет в коде реализован верно, то для избавления от меток и менять то много не надо. Если без анализа и оптимизации кода, то просто один while и в нужных местах if, continue и break. От метки 0 до метки 7

  //0: x[j]:=y[j]+k;
  while True do begin
    x[j]:=y[j]+k;
    calculate;
    if z<fi then y[j]:=x[j]
    else begin
      x[j]:=y[j]-k;
      calculate;
      if z<fi then y[j]:=x[j]
              else x[j]:=y[j];
    end;
    calculate;
    fi:=z;
    writeln('Пробный шаг',' ', z:2:3);
    for i:=1 to n do writeln(x[i]:2:3);
    if j<>n then begin
      j:=j+1;
      Continue;
    end;
    if fi>=fb-1e-08 then begin
      if (ps=1) and (bs=0) then begin
        for i:=1 to n do begin
          p[i]:=b[i];
          y[i]:=b[i];
          x[i]:=b[i];
        end;
        calculate;
        bs:=1;
        ps:=0;
        fi:=z;
        fb:=z;
        writeln('Замена базисной точки',' ',z:2:3);
        for i:=1 to n do writeln(x[i]:1:3);
        j:=1;
      end
      else begin
        k:=k/10;
        writeln('Уменьшить длину шага');
        if k<1e-08 then Break;
        j:=1;
      end;
      Continue;
    end;
    for i:=1 to n do begin
      p[i]:=2*y[i]-b[i];
      b[i]:=y[i];
      x[i]:=p[i];
      y[i]:=x[i];
    end;
    calculate;
    fb:=fi;
    ps:=1;
    bs:=0;
    fi:=z;
    writeln('Поиск по образцу',' ',z:2:3);
    for i:=1 to n do writeln(x[i]:2:3);
    j:=1;
  end;
  writeln('Минимум найден');
  //7: writeln('Минимум найден');