Red de conocimiento informático - Conocimiento de la instalación - Buscamos programación experta en lenguaje C

Buscamos programación experta en lenguaje C

Recetas Numéricas en C

El libro y programa adjunto tienen procedimientos completos. Sin embargo, encapsulé su versión C++, que puede encontrar el valor extremo de uno o varios parámetros. El archivo de encabezado completo es:

#ifndef __OPTIMIZATION_H__

#define __OPTIMIZATION_H__

.

//////////////////////////////////////////////// /// ////////////////////////////

// clase TOptimización

/ /

// $ Encuentra el valor mínimo de uno o más parámetros de la función

//

// Esta clase optimiza un parámetro de forma predeterminada. , solo necesita ingresar el número de parámetros de optimización

// Se puede utilizar para optimizar la función objetivo.

//

// ...El código principal proviene de:

// Recetas Numéricas en C++

// El El arte de la informática científica

// Segunda edición

// William H. Press Saul A. Teukolsky

// William T. Vetterling Brian P. Flannery

//

// Traducción al chino:

// Algoritmo numérico C++ (segunda edición) Traducido por Hu Jianwei, Zhao Zhiyong, Xue Yunhua y otros

// Electronics Industrial Press Beijing (2005)

//

// Autor: Jian Feng

// Correo electrónico: fengj@tom .com

// 9 de diciembre de 2006

//

////////////////// //////// /////////////////////////////////////////// //////////

//

// Función de entrada:

//

// @ MaxIterationStep: Número máximo de iteraciones, predeterminado 1000

// @ParameterNumbers: Número de parámetros de optimización, predeterminado 1

// @InitMatrix: Parámetros de matriz de inicialización (N*N), predeterminado

// @Tolerance: Tolerancia permitida, por defecto 1E-7

//

// Función de ejecución:

//

// @ExecutePowell: use el método powell para la optimización de múltiples parámetros

// @ExecuteBrent: use el método brent para la optimización de un solo parámetro

//

// Función de salida:

//

// @OptimizatedParameters: datos del resultado de la optimización

// @ObjectiveFunctionValue: el valor de función objetivo en el valor optimizado

//

// Ejemplo de uso:

//

// 1. Parámetro único

// doble objfun(doble a){

// doble suma = 0;

// for(int i = 0; i < DataPoints; + +i)

// suma += SQR( Exps[i] - Theo(a));

// }

// valor doble

// TOptimización opt;

// if(opt.ExecuteBrent(objfun, -10, -1)) opt.OptimizatedParameters(&value);

/ /

// 2. Múltiples parámetros

// double objfun(double *a){

// double sum = 0;

// for(int i = 0; i

+i)

// suma += SQR(Exps[i] - Theo(a));

// }

// valor doble[ 3]

// TOoptimización opt(3);

// double ival[3] = {-1, 0, 1};

// if(opt.ExecutePowell(objfun, ival)) opt.OptimizatedParameters(value);

//

espacio de nombres{

static int ncom; Variables

static double *pcom_p; //Variables públicas

static double *xicom_p; //Variables públicas

static double (*nrfunc)(double*) ; //Puntero de función pública

}

clase TOptimización

{

privado:

typedef double ( *Reff)(doble *);

typedef doble (*Ptrf)(doble );

público:

TOptimización(int n = 1);

~TOptimization(){ FreeMemory(); }

//Método principal

void ParameterNumbers(int n){ FreeMemory(); (); }

//Utiliza el método Powell para optimizar uno o más parámetros

bool ExecutePowell(Reff obj, double *a = 0);

// Utilice el método brent para optimizar un parámetro, y se debe proporcionar el intervalo donde se encuentra el parámetro

bool ExecuteBrent(Ptrf obj, double vFrom = 0, double vTo = 1);

void OptimizatedParameters (double *a){ for(int i=0; i

void OptimizatedParameters(double &a ){ a = vmin; }

//void OptimizatedParameters(double *a){

// if(método) for(int i=0; i

// else *a = vmin;

//}

//Otros métodos

void InitMatrix(doble **m)

{

for(int i=0; i

for(int j = 0 ; j

matx[i][j]=m[i][j]

setm = true;

}

> void MaxIterationStep(int s){ ITMAX = s }

void Tolerance(double eps){ ftol = eps }

double ObjectiveFunctionValue()const{ return trast; /p>

privado:

double brent(doble hacha, doble bx, doble cx, Ptrf f, doble tol, doble &xmin, int &flag);

void mnbrak( doble &ax, doble &bx, doble &cx, doble &fa, doble &fb, doble &fc, función Ptrf);

void linmin(doble *p, doble *xi, doble &fret, función Reff);

bool powell(doble *p, doble **xi, doble ftol, int &iter, doble &fret, función Reff);

void shft2(doble &a, doble &b, const doble c){ a=b; b=c; }

void shft3(doble &a, doble &b, doble &c, const doble d){ a=b; b=c;

doble SQR(doble x){ return x * x }

void SWAP(doble &a, doble &b){ double dum=a; b=dum; >

doble SIGNO(const doble &a, const doble &b){return b >= 0?(a>=0?a:-a):(a>=0?-a:a);}

double MAX(const double &a, const double &b){return b > a ? (b): (a);}

void AllocateMemory();

void FreeMemory();

static double f1dim(double x)

{

int j;

double *xt = new double [ ncom];

//Vec_Dp &pcom=*pcom_p,&xicom=*xicom_p;

doble *pcom = pcom_p, *xicom = xicom_p

para ( j=0;j

xt[j]=pcom[j]+x*xicom[j];

//eliminar []xt;

doble val = nrfunc(xt);

eliminar []xt;

return val;

}

bool setm //Si establecer la matriz inicial de la dirección de optimización

int num ; //Parámetros de optimización

int ITMAX; //Número máximo de iteraciones

int iter; //Número real de pasos de iteración

int método; //Método de optimización 0: 1-D brent, 2: M-D Powell

double vmin; //Parámetros de optimización unidimensionales

double ftol; p>

double fret ; //Valor de la función objetiva

double *coef; //Valor del parámetro de optimización multidimensional

double **matx; -dirección del parámetro de optimización dimensional

};

///////////////////////////// ////////////// /////////////////////////////////////

TOptimización en línea::TOptimización(int n )

{

num = n;

ftol = 1e-7;

ITMAX = 1000;

iter = 0;

traste = 0.;

vmin = 0.;

método = 0;

setm = false;

AllocateMemory();

}

optimización nula en línea::AllocateMemory()

{

pcom_p = nuevo doble [num];

xicom_p = nuevo doble [num];

coef = nuevo doble [ num];

matx = nuevo doble *[ num];

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

{

coef[i] = 0.;

matx[i] = nuevo doble [num];

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

matx[i][ j]=(i == j ? 1.0 : 0.0

}

}

);

inline void TOptimization::FreeMemory()

{

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

{

eliminar []matx[i];

p>

}

eliminar []matx;

eliminar []pcom_p;

eliminar []xicom_p;

eliminar []coef;

}

inline bool TOptimización::ExecutePowell(Reff obj, doub

le *a)

{

método = 1;

if(a)

for(int i = 0; i < num; ++i) coef[i] = a[i];

return powell(coef, matx, ftol, iter, traste, obj);

}

inline bool TOptimization::ExecuteBrent(Ptrf obj, double vFrom, double vTo)

{

método = 0;

int flag;

doble cx, fa, fb, fc;

mnbrak(vFrom,vTo,cx,fa,fb,fc,obj);

traste = brent( vFrom,vTo,cx,obj, ftol,vmin, flag);

return flag ? true : false;

}

TOptimización nula en línea::mnbrak (doble &ax, doble &bx, doble &cx, doble &fa,

doble &fb, doble &fc, función Ptrf)

{

const double GOLD=1.618034, GLIMIT=100.0,TINY=1.0e-20;

doble ulim,u,r,q,fu;

fa=func(ax);

fb=func(bx);

if (fb > fa) {

INTERCAMBIAR(ax,bx);

INTERCAMBIAR(fb,fa);

}

cx=bx+GOLD*(bx-ax);

fc=func(cx);

mientras (fb > fc) {

r=(bx-ax)*(fb-fc);

q=(bx-cx)*(fb-fa);

u=bx-((bx-cx)*q-(bx-ax)*r)/

(2.0*SIGN(MAX(fabs(q-r),TINY),q-r)) ;

ulim=bx+GLIMIT*(cx-bx);

if ((bx-u)*(u-cx) > 0.0) {

fu=func(u);

if (fu < fc) {

ax=bx;

bx=u;

fa=fb;

fb=fu;

return;

} else if (fu > fb) {

cx= u;

fc=fu;

return;

}

u=cx+GOLD*(cx-bx);

fu=func(u);

} else if ((cx-u)*(u-ulim) > 0.0) {

fu=func(u);

if (fu < fc) {

shft3(bx,cx,u,cx+GOLD*(cx-bx));

shft3(fb,fc, fu,func(u));

}

} else if ((u-ulim)*(ulim-cx) >= 0.0) {

u=ulim;

fu=func(u);

} else {

u=cx+GOLD*(cx-bx);

fu=func(u);

}

shft3(ax,bx,cx,u);

shft3(fa,fb, fc,fu);

}

}

optimización doble en línea::brent(doble hacha, doble bx, doble cx,

Ptrf f, doble tol, doble &xmin, int &flag)

{

flag = 1;

const double CGOLD=0.3819660;

const doble ZEPS=1.0e-20;

int iter;

doble a,b,d=0.0,etemp,fu,fv,fw,fx;

doble p,q,r,tol1,tol2,u,v,w,x,xm;

doble e=0.0;

a=(ax < cx ? ax : cx);

b=(ax > cx ? ax : cx);

x=w=v=bx;

fw=fv =fx=f(x);

for (iter=0;iter

xm=0.5*(a+b);

tol2=2.0*(tol1=tol*fabs(x)+ZEPS);

if (fabs(x-xm) <= (tol2-0.5*(b-a))) {

xmin=x;

return fx;

}

if (fabs(e) > tol1) {

r=(x-w)*(fx-fv);

q=(x-v)*(fx-fw);

p=(x-v)*q-(x-w)* r;

q=2.0*(q-r);

si (q > 0.0) p = -p;

q=fabs(q);

etemp=e;

e=d;

if (fabs(p) >= fabs(0.5*q*etemp) || p <

;= q*(a-x) || p >= q*(b-x))

d=CGOLD*(e=(x >= xm ? a-x : b-x));

else {

d=p/q;

u=x+d;

if (u-a < tol2 || b-u < tol2)

d=SIGN(tol1,xm-x);

}

} más {

d=CGOLD*(e=(x > = xm ? a-x : b-x));

}

u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));

fu=f(u);

if (fu <= fx) {

if (u >= x) a=x else b=x; ;

shft3(v,w,x,u);

shft3(fv,fw,fx,fu);

} más {

if (u < x) a=u; else b=u;

if (fu <= fw || w == x) {

v=w ;

w=u;

fv=fw;

fw=fu;

} else if (fu <= fv | | v == x || v == w) {

v=u;

fv=fu;

}

}

}

bandera = 0;

xmin=x;

retorno fx;

}

Optimización void en línea::linmin(double *p, double *xi, double &fret, Reff func)

{

int j, flag;

const double TOL=1.0e-8;

double xx,xmin,fx,fb,fa,bx,ax;

int n=num;

ncom=n;

//pcom_p=nuevo Vec_Dp(n);

//xicom_p=nuevo Vec_Dp(n);

nrfunc =func;

//Vec_Dp &pcom=*pcom_p,&xicom=*xicom_p;

doble *pcom = pcom_p, *xicom = xicom_p;

para ( j=0;j

pcom[j]=p[j];

xicom[j]=xi[j];

}

ax=0.0;

xx=1.0;

mnbrak(ax,xx,bx,fa,fx,fb,f1dim);

es

et=brent(ax,xx,bx,f1dim,TOL,xmin, flag);

for (j=0;j

xi[j] *= xmin;

p[j] += xi[j];

}

//eliminar xicom_p;

/ /delete pcom_p;

}

inline bool TOptimización::powell(double *p, double **xi, double ftol, int &iter,

double &fret , función Reff)

{

const int ITMAX=500;

const double TINY=1.0e-20;

int i ,j,ibig;

double del,fp,fptt,t;

int n=num;

//Vec_Dp pt(n),ptt( n),xit(n);

doble *pt, *ptt, *xit;

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

{

pt = nuevo doble [n];

ptt = nuevo doble [n];

xit = nuevo doble [n];

}

traste=func(p);

for (j=0;j

for (iter=0;;++iter) {

fp=traste;

ibig=0;

del= 0.0;

para (i=0;i

para (j=0;j

fptt=traste;

linmin(p,xit,traste,func);

if (fptt-traste > del) {

del=fptt-fret;

ibig=i+1;

}

}

if ( 2.0*(fp-traste) <= ftol*(fabs(fp)+fabs(traste))+TINY) {

eliminar []pt;

eliminar []ptt;

eliminar []xit;

devolver verdadero;

}

if (iter == ITMAX)

{

eliminar []pt;

eliminar []ptt;

eliminar []xit;

devolver falso;

//cerr<<"powell excede el máximo de iteraciones.";

<

p> }

for (j=0;j

ptt[j]=2.0*p[j]-pt[j];

xit[j]=p[j]-pt[j];

pt[j]=p[j];

}

fptt=func(ptt);

if (fptt < fp) {

t=2.0*(fp-2.0*traste+fptt)*SQR(fp-traste-del )-del*SQR(fp-fptt);

if (t < 0.0) {

linmin(p,xit,fret,func);

for (j=0;j

xi[j][ibig-1]=xi[j][n-1];

xi[j ][n-1]=salir[j];

}

}

}

}

}

#endif