Переписать программу с Pascal на С - C (СИ)
Формулировка задачи:
Собственно задача в заголовке темы.
Помоги пожалуйста, с паскалем не успеваю разобраться.
Для кого то это, возможно, будет тренировкой.
Листинг программы
- const
- eps = 0.00001; { Точность определения минимума }
- alfa = 1.0; { Коэффициент отражения }
- beta = 0.5; { Коэффициент сжатия }
- gamma = 2.0; { Коэффициент растяжения }
- t = 0.2;
- n_max = 6; { Макс. количество переменных }
- var
- x, y: array[0 .. n_max] of double;
- fh, fl, f4, f5, f6: double;
- h, l, it: integer;
- { *** Оптимизируемая функция *** }
- function f(k: integer): double;
- var r1, r2: double;
- begin
- r1 := y[k]-x[k]*x[k]; r2 := 1-x[k];
- f := 100*r1*r1+r2*r2;
- end;
- function maxf: double;
- var f1, f2, r: double;
- begin
- f1 := f(1); f2 := f(2); r := f(0);
- h := 0;
- if r < f1 then begin
- r := f1; h := 1;
- end;
- if r < f2 then begin
- r := f2; h := 2;
- end;
- maxf := r;
- end;
- function minf: double;
- var f1, f2, r: double;
- begin
- f1 := f(1); f2 := f(2); r := f(0);
- l := 0;
- if f1 < r then begin
- r := f1; l := 1;
- end;
- if f2 < r then begin
- r := f2; l := 2;
- end;
- minf := r;
- end;
- label TheEnd;
- var
- i, flag: integer;
- r, r1, x0, y0, x1, y1: double;
- begin
- x0 := -1.2; y0 := 1;
- x[0] := x0-0.5*t; y[0] := y0-t*sqrt(3)/6;
- x[1] := x0; y[1] := y0; r := f(1); y[1] := y0+t*sqrt(3)/3;
- x[2] := x0+0.5*t; y[2] := y[0];
- it := 0;
- writeln(' it=', it:5, ' x=', x0:8:4, ' y=', y0:8:4, ' f=', r:8:4);
- repeat
- fh := maxf; fl := minf;
- x[3] := 0.5*(x[0]+x[1]+x[2]-x[h]);
- y[3] := 0.5*(y[0]+y[1]+y[2]-y[h]);
- x[4] := (1+alfa)*x[3]-alfa*x[h];
- y[4] := (1+alfa)*y[3]-alfa*y[h];
- f4 := f(4);
- if (f4 < fl) then begin
- x[5]:=(1-gamma)*x[3]+gamma*x[4];
- y[5]:=(1-gamma)*y[3]+gamma*y[4];
- f5:=f(5);
- if (f5 < fl) then begin x[h]:=x[5]; y[h]:=y[5]; end
- else begin x[h]:=x[4]; y[h]:=y[4]; end;
- goto TheEnd;
- end;
- flag := 0;
- for i := 0 to pred(3) do begin
- if ((i <> h) and (f4 > f(i))) then inc(flag);
- end;
- if (flag = 2) then begin
- x[6]:=beta*x[h]+(1-beta)*x[3]; y[6]:=beta*y[h]+(1-beta)*y[3];
- x[h]:=x[6]; y[h]:=y[6];
- goto TheEnd;
- end;
- if (f(4) < fh) then begin
- for i := 0 to pred(3) do begin
- x[i]:=0.5*(x[i]+x[l]); y[i]:=0.5*(y[i]+y[l]);
- end;
- end
- else begin
- x[h]:=x[4]; y[h]:=y[4];
- end;
- TheEnd:;
- r := 0;
- for i := 0 to pred(3) do begin
- r1 := f(i)-f(3); r := r + r1*r1;
- end;
- r:=sqrt(r/3);
- inc(it);
- r1:=(f(0)+f(1)+f(2))/3;
- x0:=(x[0]+x[1]+x[2])/3;
- y0:=(y[0]+y[1]+y[2])/3;
- if it mod 20 = 0 then
- writeln(' it=', it:5, ' x=', x0:8:4, ' y=', y0:8:4, ' f=', r:8:4);
- until (r < eps);
- writeln(' it=', it:5, ' x=', x0:8:4, ' y=', y0:8:4, ' f=', r:8:4);
- end.
Решение задачи: «Переписать программу с Pascal на С»
textual
Листинг программы
- #include <stdio.h>
- #include <math.h>
- /*
- * Generated by TPTC - Translate Pascal to C
- * Version 1.7 03/26/88 (C) 1988 S.H.Smith
- */
- #define eps 0.00001 /* Точность определения минимума */
- #define alfa 1.0 /* Коэффициент отражения */
- #define beta 0.5 /* Коэффициент сжатия */
- #define gamma 2.0 /* Коэффициент растяжения */
- #define t 0.2
- #define n_max 6 /* Макс. количество переменных */
- double x[n_max+1], y[n_max+1];
- double fh, fl, f4, f5, f6;
- int h, l, it;
- /* *** Оптимизируемая функция *** */
- double f(int k)
- { double r1, r2;
- r1 = y[k] - x[k] * x[k]; r2 = 1 - x[k];
- return 100 * r1 * r1 + r2 * r2;
- }
- double maxf(void)
- { double f1, f2, r;
- f1 = f(1); f2 = f(2); r = f(0);
- h = 0;
- if (r < f1) {
- r = f1; h = 1;
- }
- if (r < f2) {
- r = f2; h = 2;
- }
- return r;
- }
- double minf(void)
- { double f1, f2, r;
- f1 = f(1); f2 = f(2); r = f(0);
- l = 0;
- if (f1 < r) {
- r = f1; l = 1;
- }
- if (f2 < r) {
- r = f2; l = 2;
- }
- return r;
- }
- void main(int argc,
- char *argv[])
- {
- int i, flag;
- double r, r1, x0, y0, x1, y1;
- x0 = -1.2; y0 = 1;
- x[0] = x0 - 0.5 * t; y[0] = y0 - t * sqrt(3) / 6;
- x[1] = x0; y[1] = y0; r = f(1); y[1] = y0 + t * sqrt(3) / 3;
- x[2] = x0 + 0.5 * t; y[2] = y[0];
- it = 0;
- printf(" it=%5d x=%8.4f y=%8.4f f=%8.4f\n",it,x0,y0,r);
- do {
- fh = maxf(); fl = minf();
- x[3] = 0.5 * (x[0] + x[1] + x[2] - x[h]);
- y[3] = 0.5 * (y[0] + y[1] + y[2] - y[h]);
- x[4] = (1 + alfa) * x[3] - alfa * x[h];
- y[4] = (1 + alfa) * y[3] - alfa * y[h];
- f4 = f(4);
- if ((f4 < fl)) {
- x[5] = (1 - gamma) * x[3] + gamma * x[4];
- y[5] = (1 - gamma) * y[3] + gamma * y[4];
- f5 = f(5);
- if ((f5 < fl)) { x[h] = x[5]; y[h] = y[5];
- }
- else { x[h] = x[4]; y[h] = y[4];
- }
- goto TheEnd;
- }
- flag = 0;
- for (i = 0; i <= 2; i++) {
- if (((i != h) && (f4 > f(i)))) flag++;
- }
- if ((flag == 2)) {
- x[6] = beta * x[h] + (1 - beta) * x[3]; y[6] = beta * y[h] + (1 - beta) * y[3];
- x[h] = x[6]; y[h] = y[6];
- goto TheEnd;
- }
- if ((f(4) < fh)) {
- for (i = 0; i <= 2; i++) {
- x[i] = 0.5 * (x[i] + x[l]); y[i] = 0.5 * (y[i] + y[l]);
- }
- }
- else {
- x[h] = x[4]; y[h] = y[4];
- }
- TheEnd: r = 0;
- for (i = 0; i <= 2; i++) {
- r1 = f(i) - f(3); r = r + r1 * r1;
- }
- r = sqrt(r / 3);
- it++;
- r1 = (f(0) + f(1) + f(2)) / 3;
- x0 = (x[0] + x[1] + x[2]) / 3;
- y0 = (y[0] + y[1] + y[2]) / 3;
- if (it % 20 == 0)
- printf(" it=%5d x=%8.4f y=%8.4f f=%8.4f\n",it,x0,y0,r);
- } while (!((r < eps)));
- printf(" it=%5d x=%8.4f y=%8.4f f=%8.4f\n",it,x0,y0,r);
- }
Объяснение кода листинга программы
- Переменные:
- x[i] - двойное значение, используемое для хранения значений x
- y[i] - двойное значение, используемое для хранения значений y
- fh, fl, f4, f5, f6 - двойные значения, используемые для хранения значений функций
- h, l, it - целочисленные значения, используемые для хранения индексов и счетчика итераций
- eps - десятичное значение, используемое для определения точности
- alfa, beta, gamma - десятичные значения, используемые как коэффициенты
- t - десятичное значение, используемое для смещения начала отсчета
- n_max - целочисленное значение, ограничивающее количество переменных
- r, r1 - десятичные значения, используемые для хранения значений функций и расстояний
- x0, y0 - десятичные значения, используемые как начальные значения
- x1, y1 - десятичные значения, используемые как значения после первой итерации
- i, flag - целочисленные значения, используемые для цикла и проверки условий
- TheEnd - метка окончания цикла
- Задачи:
- Оптимизация функции f(x) путем минимизации значения f(x)
- Подход к решению использует методы оптимизации, включая деление отрезка пополам и выбор следующей точки на основе значений функции в предыдущих точках
- Итерационный процесс продолжается до тех пор, пока изменение значения функции не станет достаточно малым
- Решение:
- Используется цикл do-while для выполнения итерационного процесса
- На каждой итерации выполняются следующие действия:
- Вычисляются значения функций fh и fl с помощью функций maxf и minf
- Вычисляются значения x[3], y[3], x[4], y[4], x[5], y[5] и x[6], y[6] с использованием коэффициентов alfa, beta и gamma, а также значений x[0], y[0], x[1], y[1], x[2] и y[2]
- Проверяются условия для перехода к следующей итерации или обновления значений x[h] и y[h]
- Вычисляются значения r1 и r для оценки изменения значений функции
- Если выполняется условие окончания цикла, выводится сообщение и значения x0, y0 и r
- Входные данные:
- Начальные значения x0 = -1.2, y0 = 1
- Значение t = 0.2
- Значение n_max = 6
- Выходные данные:
- После выполнения цикла do-while выводится сообщение и значения x0, y0 и r
- Значение r представляет собой минимальное значение функции f(x)
- Значения x0, y0 являются оптимальными значениями, минимизирующими функцию f(x)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д