МЕТОД ПОКООРДИНАТНОГО СПУСКА --------------------------------------- 23 1. ПОСТАНОВКА ЗАДАЧИ -----------------------------------------------------------------2. СТРАТЕГИЯ ПОИСКА -------------------------------------------------------------------3. ОБРАБОТКА ИНДИВИДУАЛЬНОГО ЗАДАНИЯ. ----------------------------------------4. АЛГОРИТМ ------------------------------------------------------------------------------5. ПРОГРАММА НА ЯЗЫКЕ СИ++ --------------------------------------------------------- 23 23 24 25 27 МЕТОД ГРАДИЕНТНОГО НАИСКОРЕЙШЕГО СПУСКА ----------------- 30 1. ПОСТАНОВКА ЗАДАЧИ -----------------------------------------------------------------2. СТРАТЕГИЯ ПОИСКА -------------------------------------------------------------------3. ОБРАБОТКА ИНДИВИДУАЛЬНОГО ЗАДАНИЯ -----------------------------------------4. АЛГОРИТМ ------------------------------------------------------------------------------5. ПРОГРАММА НА ЯЗЫКЕ СИ++ --------------------------------------------------------- 30 30 31 32 33 ВЫВОД: -------------------------------------------------------------------------------------- 35 РЕЗУЛЬТАТЫ ПРОГРАММ EXE ФАЙЛЫ --------------------------------------- 36 МЕТОД ДИХОТОМИИ ----------------------------------------------------------------------МЕТОД ЗОЛОТОГО СЕЧЕНИЯ -------------------------------------------------------------МЕТОД ЧИСЕЛ ФИББОНАЧИ--------------------------------------------------------------МЕТОД ПОКООРДИНАТНОГО СПУСКА --------------------------------------------------МЕТОД ГРАДИЕНТНОГО НАИСКОРЕЙШЕГО СПУСКА ----------------------------------- 36 37 38 39 40 МЕТОД ПОКООРДИНАТНОГО СПУСКА 1. Постановка задачи 1.1 Разработать алгоритм и составить программу определения точки экстремума функции двух переменных f(x,y). 2 x y 2 z 2 16 уравнение сферы. 1.2 Предельная чувствительность е=0,0005 2. Стратегия поиска Стратегия решения задачи состоит в: 1) нахождении опорной точки (Х0), которую можно выбрать как центр тяжести. 2) Выбираем направление и ищем экстремум как функцию одной переменной (Х1) X 1 var X 2 .....X n const f ( X 1 , X 20 ....X n0 ) далее применяем один из предыдущих методов (метод дихотомии) 3) Выбираем 2-ое направление и ищем опять экстремум X 2 var X 1 const f ( X 1ext , X 2 ) X 2ext 4) Далее проверка z e где, z f xi X ext 1 2 f * e2 2 2 xi Идея метода заключается в применении одномерной стратегии поиска по выделенной координате при фиксированных остальных координатах после перебора всех координат процесс поиска может быть повторен из-за возможного не попадания в фактическую точку экстремума. Недостаток: Метод хорошо работает только в условиях, когда координаты мало влияют друг на друга Если метод не работает нужно подвинуть систему координат, т.е. для улучшения метода покоординатного поиска обычно пытаются изменить направление поиска, например, вращая систему координат. Достоинство: 1) простота 2) возможность применения стратегии одномерного поиска 23 Область поиска X2 X3 X2 X1 X0 X1 3. Обработка индивидуального задания. x 2 y 2 z 2 16 уравнение сферы. z 4 -4 -4 4 0 4 -4 y 24 x 4. Алгоритм void main (void) k=1 z=max_value(x,y) y=max No z<e k=0 z=max_value(x,y) x=max Yes x,y,z END No z<e Yes No k=1 x,y,z k==1 END Yes 25 max_value(x,y) с=(a+b)/2 v=y No k==1 Yes v=x var1=c-e/2 var2=c+e/2 f1=sqrt(16-pow(var1,2)-pow(v,2)); f2=sqrt(16-pow(var2,2)-pow(v,2)); No No No f1>f2 f1==f2 Yes a=var1 b=var2 max=(a+b)/2 Yes max=var2 a=var1 max=var1 b=var2 (b-a)>=2e Yes No k==1 Yes v1=max v2=v v1=v v2=max s=16; w=s-(pow(v1,2)-pow(v2,2)) ; d= pow (w,3) ; prx=(-1*v2)/(sqrt(s-pow(v1,2)-pow(v2,2))); pry=(-1*v1)/(sqrt(s-pow(v1,2)-pow(v2,2))); prxy=(-1*v1*v2)/sqrt(d ); prx2=(pow(v1,2)-s)/sqrt (d); pry2=(pow(v2,2)-s)/sqrt (d) ; z=e*(prx+pry)+pow(e,2)*(prx2+prxy+pry2); 26 5. Программа на языке Си++ # include <math.h> // библиотеки # include <stdio.h> # include <conio.h> # include <stdlib.h> # include <iostream.h> float s,d,w, x=0, y=0, e=0.0005, z, max, k,fz,a=-4,b=4 ; // s,d,w- промежуточные переменные для удобства вычислений // х,у- переменные // е- предельная чувствительность // z-проверка условия // max- максимум // к-сигнал // fz //a, b- координаты отрезка на котором определяется максимум float max_value (float,float); // прототипы функций void vivod (void); void main () { clrscr(); // очистка экрана // оформление экрана textmode(3); //текстовый режим С80 (40символов * 25 строк, цветной) textcolor(BLUE|BLINK); // цвет выдаваемого текста textbackground(YELLOW); // установка цвета фона под вновь вводимый текст cprintf("\n*********************** МЕТОД ПОКОРДИНАТНОГО СПУСКА ************************ "); textmode(3); textcolor(RED); cprintf("\n"); cprintf("Поиск максимального значения"); cprintf("x^2+y^2+z^2=16 уравнение сферы "); textmode(3); textcolor(MAGENTA); cprintf("\n"); cprintf ("Выполнила студентка групп И-5-5 Щербакова Анна "); textmode(LASTMODE); // возврат в предыдущий режим cout <<" ********************************************************"; k=1; // фиксируем переменную хб ищем максимум по у do { z=max_value(x,y); 27 y=max; if (z<e) { vivod(); break; // досрочный выход из цикла } else { k=0; z=max_value(x,y); x=max; } if (z<e) {vivod(); break; // досрочный выход из цикла } else k=1; } while(k==1); cprintf("\n \n \n \n \n \n"); printf( " \n Для завершения работы нажмите <Enter>"); getch(); } float max_value(float x,float y) { float var1, var2, v1, v2, c, v, f1, f2; // var1,var2,v1,v2-вспомогательные ячейки // f1,f2- значения функций // с- координата середины отрезка. float prx,pry,prxy,prx2,pry2; // prx- частная производная по х // pry- частная производная по у // prxy- частная производная по х,у // prx2- вторая частная производная по х // pry2- вторая частная производная по у do { c=(a+b)/2; if (k==1) v=x; else v=y; var1=c-e/2; var2=c+e/2; f1=sqrt(16-pow(var1,2)-pow(v,2)); f2=sqrt(16-pow(var2,2)-pow(v,2)); if (f1==f2) { a=var1; 28 b=var2; max=(a+b)/2; } if (f1>f2) { max=var1; b=var2; } else if (f1<f2) { max=var2; a=var1; } } while ((b-a)>=2*e); if (k==1) { v1=max; v2=v; } else{v1=v; v2=max;} s=16; w=s-(pow(v1,2)-pow(v2,2)) ; d= pow (w,3) ; prx=(-1*v2)/(sqrt(s-pow(v1,2)-pow(v2,2))); pry=(-1*v1)/(sqrt(s-pow(v1,2)-pow(v2,2))); prxy=(-1*v1*v2)/sqrt(d ); prx2=(pow(v1,2)-s)/sqrt (d); pry2=(pow(v2,2)-s)/sqrt (d) ; z=e*(prx+pry)+pow(e,2)*(prx2+prxy+pry2); return z; } void vivod (void) { cout <<"\nЗначение координаты x= " <<x; cprintf("\n"); cout <<"\n Значение координаты y= " << y; cprintf("\n"); fz=sqrt(16-pow(x,2)-pow(y,2)); cout <<"\n Значение функции z= " <<fz; cprintf("\n"); } 29 МЕТОД ГРАДИЕНТНОГО НАИСКОРЕЙШЕГО СПУСКА 1. Постановка задачи 1.1 Разработать алгоритм и составить программу определения точки экстремума функции двух переменных f(x,y). x 2 y 2 z 2 16 уравнение сферы. 1.2 Предельная чувствительность е=0,0005 2. Стратегия поиска Стратегия решения задачи состоит в: 1) нахождении опорной точки (Х0), которую можно выбрать как центр тяжести. f f f ; ;.....; 2) grad x x x 1 2 n 3) Поиск осуществляется: xik 1 xik a * grad X k i где а- коэффициент смещения 2 f i i a 2 f f f i j x i x j x i x i x f 1 2 f 2 * e2 4) Далее проверка z e где, z xi X 2 xi В градиентном методе важную роль играет выбор величины а- шага градиентного метода Рассмотрим технологию рассчета оптимального градиентного метода с использованием гр. квадратурной модели целевой функции: n z 1 n n 2z z ( xi 1 ) z xi x k x k xl k 1 x 2 k 1 l 1 x x k k l ext x k xk (t i 1 ) xk (t1 ) j z z j z xi k 1 x k x k где n z x k 1 n n 2 z 2 z z 1 j a 0 ja1 j 2 a 2 x k xl 2 2 k 1 l 1 x k xl 30 a 0 z ( xi ) z a1 k 1 x n n 2 z z z a 2 k 1 l 1 x x x x l k l l n 2 z a1 k 1 x n n a 2 z z z a2 k 1 l 1 x x x x l k l l Комментарии: Несмотря на явное выражение для оптимального шага а, соотношение используется крайне редко, т.к. затраты на его рассчет оказываются настолько большими, что перекрывают временные затраты связанные с использованием приближенного шага в градиентном методе, т. е. проще “вручную” подобрать этот шаг. 2 n а 3. Обработка индивидуального задания смотри метод покоординатного спуска 31 4. Алгоритм НАЧАЛО A=16-pow(x,2)-pow(y,2); dfx=x/sqrt(A); dfy=y/sqrt(A); prx=(-1*x)/sqrt(A); pry=(-1*y)/sqrt(A); pr2x=(pow(y,2)-16)/sqrt(pow(A,3)); pr2y=(pow(x,2)-16)/sqrt(pow(A,3)); prxy=(-1*x*y)/sqrt(pow(A,3)); z=e*(prx+pry)+0.5*pow(e,2)*(pr2x+pr2y+2*prxy); No z<e Yes B=(x*x+y*y)/fabs(A); C=(y*y-16)*(x*x); D=(x*x-16)*(y*y); E=2*(-1*x*x*y*y); F=sqrt(pow(A,5)); st=B/((C+D+E)/F); x,y,z a=st x-=a*dfx; y-=a*dfy; while (1) END 32 5. Программа на языке Си++ # include <stdio.h> //библиотеки # include <iostream.h> # include <conio.h> # include <math.h> float x=0,y=0,dfx,dfy,A,z,e=0.0005,a; // х,у – переменные // dfx- fx ( f (fxfy ) ) значение градиента в точке х0 // dfy- fу ( f (fxfy ) ) значение градиента в точке х0 // е- предел чувствительности // я- проверка условия void gradient (float x,float y); // прототипы функций float prirf (float x,float y); float step (float x,float y); void vivod (void); void main (void) { clrscr(); // очистка экрана // оформление экрана textmode(3); // текстовый режим С80 (40 символов* 25 строк, цветной) textcolor(BLUE|BLINK); // цвет выдаваемого текста textbackground(YELLOW); // установка цвета фона под вновь вводимый текст cprintf("\n**************** МЕТОД ГРАДИЕНТОНОГО НАИСКОРЕЙШЕГО СПУСКА ********************* "); textmode(3); textcolor(RED); cprintf("\n"); cprintf(" Поиск максимального значения "); cprintf("x^2+y^2+z^2=16 уравнение сферы \n "); textmode(3); textcolor(MAGENTA); cprintf("\n"); cprintf Выполнила студентка группы И-5-5 Щербакова Анна"); textmode(LASTMODE); cout << " ***********************************************************"; do { A=16-pow(x,2)-pow(y,2); gradient(x,y); z=prirf(x,y); if (z<e) { vivod(); 33 break;} // досрочный выход из цикла else { a=step(x,y); x-=a*dfx; y-=a*dfy; } } while (1); cprintf("\n \n \n \n \n \n"); printf( " \n Для окончания работы нажмите <Enter>"); getch(); } void gradient (float x, float y) { dfx=x/sqrt(A); dfy=y/sqrt(A); return; } float prirf (float x,float y) { float prx,pry,pr2x,pr2y,prxy; prx=(-1*x)/sqrt(A); pry=(-1*y)/sqrt(A); pr2x=(pow(y,2)-16)/sqrt(pow(A,3)); pr2y=(pow(x,2)-16)/sqrt(pow(A,3)); prxy=(-1*x*y)/sqrt(pow(A,3)); z=e*(prx+pry)+0.5*pow(e,2)*(pr2x+pr2y+2*prxy); return z; } float step (float x,float y) { float B,C,D,E,F,st; B=(x*x+y*y)/fabs(A); C=(y*y-16)*(x*x); D=(x*x-16)*(y*y); E=2*(-1*x*x*y*y); F=sqrt(pow(A,5)); st=B/((C+D+E)/F); return st; } 34 void vivod (void) { cout <<"\n Значение координаты x="<<x; cprintf("\n"); cout <<"\n Значение координаты y="<<y; cprintf("\n"); z=sqrt (16-x*x-y*y); cout <<"\n Значение функции z="<<z; } Вывод: Реальный выбор итерационного процесса должен производится с учетом имеющейся информации об объеме и составе памяти ЭВМ. 35 Результаты программ exe файлы Метод дихотомии 36 Метод золотого сечения 37 Метод чисел Фиббоначи 38 Метод покоординатного спуска 39 Метод градиентного наискорейшего спуска 40 41