2. Алгоритм с парными пробами
где gi – пробный шаг по i-й переменной, выбираемый достаточно малым для разностной оценки производной.
Отметим, что при таких расчетах gi ,нельзя брать слишком малым, а значения функции нужно вычислять с достаточно высокой степенью точности, иначе при вычислении разности
Df(x1, ...,xi+ gi, ..., xn) - f(x1, ..., xi, ..., xn)
Df(x1, ...,xi+ gi, ..., xn) - f(x1, ..., xi- gi,..., xn)
будет допущена большая ошибка.
Первый алгоритм требует меньших затрат по сравнению со вторым (обычно затраты выражаются количеством вычислений критерия оптимальности), но позволяет получить решение менее точно, чем второй, эта погрешность зависит от величины пробного шага
На рис. изображены линии уровня функции двух переменных u= f (х, у), , и приведена траектория поиска ее минимума с помощью метода градиентного спуска.
Метод наискорейшего спуска
Суть метода наискорейшего спуска состоит в следующем. Как и прежде, в начальной точке определяется антиградиент минимизируемой функции. Однако теперь в направлении антиградиента делается ни один шаг, а движутся в данном направлении до тех пор, пока целевая функция убывает, достигает в некоторой точке минимума. В этой точке опять определяют антиградиент и ищут новую точку минимума целевой функции и так далее. В данном методе спуск имеет более целеустремлённый характер, производится более крупными шагами и градиент функции вычисляется в меньшем числе точек.
Описание программы
Программа предназначена для нахождения точек минимума функций нескольких переменных – другими словами для минимизации этих функций.
В программе реализован один из методов спуска – Градиентный метод спуска с выбором шага. Начальный шаг задается.
Изменение шага осуществляется по схеме
если ; если Вычисление градиента происходит по методу с парными пробами, это улучшает поиск за счёт более точного вычисления градиента.
Метод наискорейшего спуска по сравнению с обычным градиентным методом дает некоторое ускорение , метод хорошо "работает" при минимизации гладких функций и если начальное приближение выбрано достаточно далеко от оптимума. Если же очередная точка окажется в окрестности оптимума, то уменьшение целевой функции будет очень медленным. Это происходит из-за того, что для получения оптимума с высокой точностью необходимо выполнить большое число мелких шагов.
Метод наискорейшего спуска хотя не дает особенного ускорения сходимости он свободен от параметров и на практике может дать некоторый выигрыш, особенно на начальных итерациях.
В связи с этим в программе был реализован более точный метод градиентного спуска.
В качестве условия окончания поиска задаётся требуемая малость модуля градиента функции, т.е. должно выполнятся условие
(В области оптимума градиент равен 0, но достичь этого значения практически не возможно, поэтому задаётся требуемая малость близкая к 0).Так же в программе можно задавать номер итерации выхода из цикла,
Другими словами при достижении какого количества точек прерывать цикл, если он не прервется сам раньше.
Реализация программы:
Общая блок схема
Руководство для пользования
Программа написана на языке программирования С++, в
среде Borland C++5.
Программа имеет понятный интуитивный графический интерфейс.
После запуска необходимо следовать инструкциям и вводить все необходимые данные.
На начальном этапе выбирается одна из предложенных функций,
Затем вводится начальное приближение и диапазоны по каждой переменной. На следующем этапе вводятся параметры вычислений: начальный коэффициент шага, пробный шаг, погрешность.
Затем программа рассчитывает точки приближения и находит для данных ограничений точку минимума.
Затем графически отображает траекторию поиска точки минимума.
Приложение А
Листинг программы
#include <vcl.h>
#pragma hdrstop
#include "Math.hpp"
#include "math.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
int ii=0,n=0,s=0;
AnsiString Formula[3]={"U=A*x1^3+B*x2^2-C*x1-D*x2","U=x1^2+x1*x2+x2^2","U=X1^2+X2^2"};
int KolPer[3]={2,2,2};// массив в котором хранится кол-во перемен. для каждой ф-ии
bool DD=true,Diapozon=true; // если true то точка входит в диапозон иначе нет
double PeremenN[5]={0};//double *PeremenN =new double[n]; //нул.приб
double InterN[5]={0};//double *InterN =new double[n]; //нач
double InterK[5]={0};//double *InterK =new double[n]; //кон
double Param[4]={0}; //параметры
double T1[5]={0};//double *T1 =new double[n]; //tochka i -я
double T2[5]={0};//double *T2 =new double[n]; //tochka i+1 -я
double TempT[5]={0};//double *TempT =new double[n]; // временная tochka i+1 -я
double BB[5]={0};//double *BB= new double [n]; // BB - массив с измененой i-ой точкой X[i]+g
double B[5]={0};//double *B= new double [n]; //B - массив с измененой i-ой точкой X[i]-g
int g=0;
double ModG =0; //модуль градиента
int ss=0,ind=0;
double **Tochki; // указатель на массив с точками приближения
//---------------------------------------------------------------------------
double TForm1::F1( double T[]) //Formula1 U=A*x1^3+B*x2^2-C*x1-D*x2
{ double U = 0;
U=IntPower(T[0],3)+2*IntPower(T[1],2)-3*T[0]-4*T[1];