RSS    

   Реферат: Минимизация функций нескольких переменных. Метод спуска

В связи с этим в программе был реализован более точный метод градиентного спуска.

В качестве условия окончания поиска задаётся требуемая малость модуля градиента функции, т.е. должно выполнятся условие

(В области оптимума градиент равен 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];

    return U;  }         

                      

//---------------------------------------------------------------------------

 double TForm1::F2( double T[]) //Formula2 U=x1^2+x1*x2+x2^2

 {  double U = 0;

    U = IntPower(T[0],2)+T[0]*T[1]+IntPower(T[1],2);

    return U;  }

//---------------------------------------------------------------------------

 double TForm1::F3( double T[]) //Formula3  U=X1^2+X2^2

 { double U = 0;

   U =T[0]*T[0]+T[1]*T[1]+1;

    return U; }

//---------------------------------------------------------------------------

void TForm1::Tochka(double shag)      // функция считает координаты следующей точки

{                        // n - количество переменных

  for (int i = 0; i < n; i++)

  {

   TempT[i]=T2[i]-shag*Gr(i);

  //точка X[j+1]=точка X[j]- h козф шага *градиет grad R(X[j])

   }

}

//---------------------------------------------------------------------------

double  TForm1::Gr( int i) //gradient  i-номер переменной

 {

  double dR=0;  //   dR - градиент по i

   for (int j=0;j<n;j++)   //BB,B==T1;

    {

     BB[j]=T2[j];

     B[j]=T2[j];

    }

  BB[i]=T2[i]+ Param[1] ; // добавляем и отнимаем пробный шаг

  B[i]=T2[i]- Param[1] ;  //  к i-ой переменной

  switch (UD->Position) {

   case 0: dR = (F1(BB)- F1(B))/(2*Param[1]) ; break;

   case 1: dR = (F2(BB)-F2(B))/(2*Param[1]); break;

   case 2: dR = (F3(BB)-F3(B))/(2*Param[1]); break;

       }

   return dR;

 }

//--------------------------------------------------------------------------

void TForm1::Min()

 {                                // массив в котором

   //double Tochki[1][5]; //хранится первое приближение

   //double **Tochki;              //создаем массив Temp[ss][n]

    Tochki = new  double*[100];

     for (int j = 0; j < 100; j++)

     Tochki[j] = new  double[3];

   bool Minimum=false,Pogresh=false,shag=false;

   double sh=Param[0];

   for (int j=0;j<n;j++)  //T1,T2,TempT=PeremenN;

    {

     T1[j]=PeremenN[j];

     T2[j]=PeremenN[j];

     TempT[j]=PeremenN[j];

     Tochki[0][j]=PeremenN[j];

     }

   while ( Minimum == false   )  // после выхода из цикла

   {                            //  минимум в точке T2

     shag=false;

     // начало блока 2

     while (shag == false)

     {

       double R=0;

       Tochka(sh);

       switch (UD->Position) {

        case 0: R=F1(TempT)-F1(T1) ; break;

        case 1: R=F2(TempT)-F2(T1); break;

        case 2: R=F3(TempT)-F3(T1); break; }

        if (R > 0)   // шаг большой то

        {            // уменьшаем его в 2 раза

          sh= sh/2;

         }

        else

         { shag =true; }

       }

     // конец блока 2

     // Проверяем входит ли точка в указанный диапозон

     // если нет то считаем предыдущую точку минимальной

    if (DD==true )

    {

      for ( int i=0; i<n; i++)

       {

        if ( InterN[i] > TempT[i])

          {

           Diapozon=false;

           Minimum = true;

          }

          if (InterK[i] < TempT[i])

           {

           Diapozon=false;

           Minimum = true;

          }

        }

      }

          for (int j=0;j<n;j++)

            {

              T1[j]=T2[j];       //T1=T2

              T2[j]=TempT[j];    //T2=TempT

             }

           // начало блока 3

        ModG=0;      //- модуль градиента

       for (int i = 0; i < n; i++)

        {

          ModG+= Gr(i)*Gr(i);

         }

       ModG=sqrt(ModG);

       if ( ModG < Param[2])    // /gradient/ < e  где e-погрешность

         {  Minimum=true;  }   //  /gradient/ - модуль градиента

     // конец блока 3

             ss++;

       if (Param[3] != -1 )

          if (ss == Param[3])

           Minimum=true;

       // начало блока 4

     if ( ss > 99 )

       {  MessageDlg("Предел превышен ...точек более 100 ..измените шаг",mtWarning,

            TMsgDlgButtons() << mbOK , 0);break;}

     if(Diapozon==true)

      {

        for (int j = 0; j < n; j++)

           Tochki[ss][j] = T2[j];

        }

      }

      for (int j = 0; j <= ss; j++)

         {

           for (int i = 0; i < n; i++)

              TempT[i]= Tochki[j][i];

           switch (UD->Position) {

            case 0: Tochki[j][2] = F1(TempT) ; break;

            case 1: Tochki[j][2] = F2(TempT); break;

            case 2: Tochki[j][2] = F3(TempT); break; }

         }

         //

        /* double **Temp;              //создаем массив Temp[ss][n]

          Temp = new  double*[ss];

           for (int j = 0; j < ss; j++)

             Temp[j] = new  double[n];

        //

         for (int i = 0; i < ss; i++)

          for (int j = 0; j < n; j++)

           Temp[i][j]=Tochki[i][j];

        //

          //for (int i = 0; i < ss;  i++) //удаляем массив Tochki[ss][n]

          //delete[] Tochki[i];

          //delete  Tochki;

        //

       int mm=ss+1;

       double **Tochki;         //создаем массив Tochki[ss+1][n]

        Tochki = new  double*[mm];

        for (int j = 0; j < mm; j++)

          Tochki[j] = new  double[n];

       //

         for (int i = 0; i < mm-1; i++)

           for (int j = 0; j < n; j++)

            Tochki[i][j] = Temp[i][j];

        //

         for (int j = 0; j < n; j++)

Страницы: 1, 2, 3, 4


Новости


Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

                   

Новости

© 2010.