русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Программная реализация класса подпрограмм для поиска экстремума унимодальных в заданном интервале функций одной переменной


Дата добавления: 2015-01-16; просмотров: 598; Нарушение авторских прав


#include<conio.h>

#include "matrix.h"

 

typedef matrix<double> dmatrix;

typedef vector<double> dvector;

 

/*Определим вначале некоторые вспомогательные подпрограммы*/

//Для вычисления числа Фибоначчи с заданным номером

long Fib(long n)

{

long F[3]={0,1};

if(n<0)

throw xmsg("Некорректный номер числа");

if(n<2)

return F[n];

for(long i=2;i<=n;i++)

{

F[2]=F[0]+F[1];

F[0]=F[1];

F[1]=F[2];

}

return F[2];

}

 

 

/*Простая парабола для тестирования одномерного поиска*/

double gv(double x)

{

return (4*x*x+5*x+1);

}

 

 

/*Функциональный класс объектов для поиска экстремума; мы включили в него и некоторые функции определения значения вещественного корня*/

class MonoExtremum

{

double c, d;//Границы для одномерного поиска

double eps;//Для допустимой погрешности поиска

/*Указатель на подпрограмму, возвращающую значение исследуемой функции*/

double (*getv)(double x);

public:

//Конструктор для одномерного поиска

MonoExtremum(double C, double D, double EPS, double (*GETV)(double X)): c(C), d(D), eps(EPS), getv(GETV) { }

//Прототипы функций поиска вещественного корня

double RealRoot(long cod); /*сокращением интервала неопределенности*/

double DNewton(); //Метод секущих

double Stoh(); //Стохастическая аппроксимация

/*Прототипы функций решения задачи условной оптимизации*/

double Dihot(); //метод дихотомии

double Fibon(long cnt); //метод Фибоначчи

double Gold(); //метод золотого сечения

dvector Coord(); //метод покоординатного спуска

dvector Grad(); //метод градиента

dvector PSM(); //последовательный симплекс-метод

};

 

 

/*Обобщенная функция уточнения корня последовательным сокращением интервала неопределенности*/



double MonoExtremum::RealRoot(long cod=0)

{

double ct=c,dt=d,x,vc,vd,vx,k;

for(;;)

{

switch(cod)

{

case 0: //Больцано

k=0.5;

vc=getv(ct);

break;

case 1: //Хорды

vc=getv(ct);

vd=getv(dt);

k=vc/(vd+vc);

if(k<0)

k=-k;

break;

case 2: //Случайный поиск

randomize();

k=double(1+random(1111))/1111.0;

vc=getv(ct);

break;

}

x=ct+k*(dt-ct);

vx=getv(x);

if(fabs(vx)<eps)

return x;

if(vx*vc>0)

ct=x;

else

dt=x;

}

}

 

 

//Метод секущих - дискретный аналог метода Ньютона

double MonoExtremum::Dnewton()

{

double sx[3];

sx[0]=(c+d)/2;

sx[1]=sx[0]+1e-4;

sx[2]=sx[1]-(getv(sx[1]))*(sx[1]-sx[0])/

(getv(sx[1])-getv(sx[0]));

while(1)

{

if(getv(sx[2])<eps)

return sx[2];

sx[0]=sx[2];

sx[1]=sx[0]+1e-4;

sx[2]=sx[1]-(getv(sx[1]))*(sx[1]-sx[0])/

(getv(sx[1])-getv(sx[0]));

}

}

 

 

//Стохастическая аппроксимация

double MonoExtremum::Stoh()

{

double scnt=1;

//Для определения знака приращения

double sx[3],fa[3];

sx[0]=(c+d)/2.0;

fa[0]=fabs(getv(sx[0]));

if(fa[0]<eps)

return sx[0];

sx[1]=sx[0]+1e-2;

fa[1]=fabs(getv(sx[1]));

if(fa[1]<eps)

return sx[1];

for(scnt=1;;scnt++)

{

sx[2]=sx[1]-(20.0/scnt)*fa[1]*(sx[1]-sx[0])/ (fa[1]-fa[0]);

fa[2]=fabs(getv(sx[2]));

if(fa[2]<eps)

return sx[2];

sx[0]=sx[1];

sx[1]=sx[2];

fa[0]=fa[1];

fa[1]=fa[2];

}

}

 

 

//Реализация функций одномерного поиска экстремума

//Метод дихотомии

double MonoExtremum::Dihot()

{

double xl,xr,yl,yr,dt=d,ct=c;

for(;(dt-ct)>eps;)

{

/*задаем координаты 2-х точек эксперимента вблизи средины интервала*/

xl=(ct+dt)/2-0.01*(dt-ct);

xr=(ct+dt)/2+0.01*(dt-ct);

//Вычисляем значения функции в этих точках

yl=getv(xl);

yr=getv(xr);

if(sign(yl-yr)>0)

/*Бывшая правая - теперь левая, а правая - симметрично*/

{

ct=xl;

xl=xr;

xr=ct+dt-xl;

}

else

{

dt=xr;

xr=xl;

xl=ct+dt-xr;

}

}

return (ct+dt)/2;

}

 

 

//Метод Фибоначчи для поиска экстремума

double MonoExtremum::Fibon(long cnt)

{

double k=(double)Fib(cnt-1)/(double)Fib(cnt);

/*вычисляем координаты 2-х первых точек эксперимента*/

double ct=c, dt=d, xl=d-k*(d-c), xr=c+k*(d-c), yl, yr;

/*Далее в цикле в худшую точку переносим ближайшую границу, а добавочную точку определяем симметрично оставшейся относительно середины интервала */

for(long i=cnt;i>1;i--)

{

yl=getv(xl);

yr=getv(xr);

if(sign(yl-yr)>0)

{

ct=xl;

xl=xr;

xr=ct+dt-xl;

}

else

{

dt=xr;

xr=xl;

xl=ct+dt-xr;

}

}

return (ct+dt)/2;

}

 

 

//Метод золотого сечения

double MonoExtremum::Gold()

{

double k=0.618033989;

/*вычисляем координаты 2-х первых точек эксперимента*/

double ct=c, dt=d, xl=d-k*(d-c), xr=c+k*(d-c), yl, yr;

/*Далее в цикле в худшую точку переносим ближайшую границу, а добавочную точку определяем симметрично оставшейся относительно середины интервала*/

for(;(dt-ct)>eps;)

{

yl=getv(xl);

yr=getv(xr);

if(sign(yl-yr)>0)

{

ct=xl;

xl=xr;

xr=ct+dt-xl;

}

else

{

dt=xr;

xr=xl;

xl=ct+dt-xr;

}

}

return (ct+dt)/2;

}

 

 

//Программа тестирования методов уточнения корней и

//одномерного поиска экстремума

main()

{

/*Тестирование методов уточнения корня последовательным сужением интервала неопределенности*/

MonoExtremum root1(-0.5,0.5,1e-3,gv); //Сконструируем объект

double res0=root1.RealRoot(0); //0-метод Больцано

cout<<endl<<"Bolzano: "<<res0<<" Func : "<< gv(res0);

double res1=root1.RealRoot(1); //1-метод хорд

cout<<endl<<"Chord : "<<res1<<" Func : "<< gv(res1);

double res2=root1.RealRoot(2); /*2-метод Монте _ Карло*/

cout<<endl<<"Rand :"<<res2<<" Func : "<<gv(res2);

 

//Тестирование поиска корня методом секущих

double resDNewton=root1.DNewton();

cout<<endl<<"DNewton : "<<resDNewton<<" Func : "

<<gv(resDNewton);

 

/*Тестирование поиска корня методом стохастической аппроксимации*/

double resStoh=root1.Stoh();

cout<<endl<<"Stoh : "<<resStoh<<" Func : "

<<gv(resStoh);

 

//Тестирование методов поиска экстремума

MonoExtremum extr1(-3.0,+5.0,1e-3,gv);/*Сконструируем объект*/

//Вызываем методы решения

double resDihot=extr1.Dihot(), //Дихотомии

resFib=extr1.Fibon(25), //Фибоначчи

resGold=extr1.Gold(); //Золотого сечения

cprintf("\r\nDihot : %lf Fibon : %lf Gold : %lf ", resDihot,resFib,resGold);

getch();

}



<== предыдущая лекция | следующая лекция ==>
Подготовительные операции | 


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.863 сек.