程序挺大的
/*
下面的文件名为:Hooke_Jeeves.h
*/
#include
/*
(1) 调用格式:
rtn = dirs( n,x,d,min,r,f,&fmin,maxi,&lc,xn,dl )
rn为整形变量,为0表示正常返回。
(2) 参数说明:
输入参数:
n----整形变量,自变量的个数,
d----实型变量,搜索步长,输入时候存放初始步长,当d
r----实型变量,步长缩短因子
maxi-整型变量,容许函数计算的最大次数
(*f)()--实型函数指针,目标函数f(n,x),n:整型变量,自变量个数;
x[]:n个元素的一唯实型数组
输出参数:
*fmin-实型指针,返回时,存放函数f(x1,...,xn)的极小值
*lc---整形指针,返回时,若LC=0表示已经达到精度要求,
若LC=1表示迭代计算次数已经达到最大,但不满足精度要求而返回
输入兼输出参数:
x[]---n个元素的一唯实型数组,输入时,存放初始点,返回时,存放函数f的极小值点
工作区域:xn[]----n个元素的一唯实型数组,dl[]----n个元素的一唯实型数组.
注意:本方法实用于变量个数不多的情况,其在最优点附近更是如此,但是它的适应性较强,不需要求导数
*/
/********************************************************************************************/
/* This routine can be called in following format: */
/* rtn=dirs(n,x,d,min,r,f,fmin,maxi,lc,xn,dl) */
/* n -- Integer data, */
/* x[] -- double array, */
/* d -- double value, */
/* min -- double value, */
/* r -- double value, */
/* *fmin -- Point of double value, */
/* (*f)() -- Point of double function */
/* maxi -- Integer data, */
/* *lc -- Point of integer data, */
/* xn[] -- double array, */
/* dl[] -- double array */
/********************************************************************************************/
void e(int n,double xn[],double dl[],double *fm,double *fn,
double (*f)(int n,double x[]),int maxi,int *ll,int *lc)
{
int j;
for( j = 0 ; j < n ; j++ )
{
xn[j] = xn[j] + dl[j];
if(maxi <= *ll)
{
*lc = 1;
return ;
}
*ll = *ll + 1;
*fn = (*f)(n,xn);
if( *fn < *fm )
{
*fm = *fn;
}
else
{
dl[j] = -dl[j];
xn[j] = xn[j] + 2.0 * dl[j];
if(maxi <= *ll )
{
*lc = 1;
return;
}
*ll = *ll + 1;
*fn = (*f)(n,xn);
if( *fn >= *fm )
{
xn[j] = xn[j] - dl[j];
}
else
{
*fm = *fn;
}
}
}// end of for(j=
return ;
}// end of proc
int dirs(int n,double x[],double d,double min,double r,double (*f)(int n,double x[]),
double *fmin,int maxi,int *lc,double xn[],double dl[])
{
int i,ll,jj;
double fm,fn,w;
for(i=0;i
dl[i] = d; //d是搜索步长
}
*fmin = (*f)( n,x );
ll = 1;
*lc = 0; //求借是否成功的标志
while(1)
{
fm = *fmin;
for( i=0 ; i < n ; i++ )
{
xn[i] = x[i];
}
e( n,xn,dl,&fm,&fn,f,maxi,&ll,lc );
if( *lc == 1 ) return 1;
if( fm >= *fmin )
{
if(min > d) return 1;
d = d * r;
for(i=0;i
dl[i] = dl[i] * r;
}
}
else
{
do
{
jj = 0;
for(i=0;i
if( x[i] < xn[i] && dl[i] < 0 || x[i] >= xn[i] && dl[i] > 0 )
{
dl[i] = -dl[i];
}
w = x[i];
x[i] = xn[i];
xn[i] = 2.0 * xn[i] - w;
} // end of for(i=0;i
*fmin = fm;
if(maxi <= ll)
{
*lc = 1;
return (1);
}
ll++;
fn = (*f)(n,xn);
fm = fn;
e( n,xn,dl,&fm,&fn,f,maxi,&ll,lc ) ;
if( *lc == 1 ) return 1;
if( fm < *fmin )
{
for( i = 0 ; i < n ; i++ )
{
if( 0.5 * fabs(dl[i]) < fabs(xn[i]-x[i]) )
{
jj = 1;
}
}
if( jj == 0 )
{
if( min > d ) return 0;
d = d * r;
for( i = 0 ; i < n ; i++ )
{
dl[i] = dl[i] * r;
}
}
}// end of if( fm < *fmin )
}
while( jj == 1 ); //end of do
} // end of else
}// end of while(1)
return 1;
}
下面是调用的一个例子
/*
文件名为:Hooke_Jeeve.cpp
*/
#include
#include "Hooke_Jeeve.h"
int main(void)
{
double g(int n,double x[]);
double fmin,xn[2],dl[2];
int lc,rtn;
int n = 2;
double x[2] = {1.0,1.0}; //初始点
double min = 0.001;
double d = 0.5;
double r = 0.5;
int maxi = 200;
rtn = dirs(n,x,d,min,r,g,&fmin,maxi,&lc,xn,dl);
printf("|-------------------------------------------------|\n");
printf(" X1 X2 FMIN LC \n");
printf("|-------------------------------------------------|\n");
printf("| %lf %lf %lf %d\n",x[0],x[1],fmin,lc);
printf("|-------------------------------------------------|\n");
return 0;
}
double g(int n,double x[])
{
double z;
z = sqrt(pow(x[0]-0,2)+pow(x[1]-1,2))+sqrt(pow(x[0]-1,2)+pow(x[1]-1,2))+sqrt(pow(x[0]-0,2)+pow(x[1]-0,2))+sqrt(pow(x[0]-1,2)+pow(x[1]-0,2))+sqrt(pow(x[0]-2,2)+pow(x[1]-1,2))+sqrt(pow(x[0]-2,2)+pow(x[1]-0,2)); /把这个地方修改为自己要优化的公式就行了
return z;
}
朋友,这个题目也太难了点吧。就单看那函数就够呛的了。更加不用说编程了。
不是计算计专业没关系,
你先把计算步骤写下来,
我再用C 编程,
i读书时数学没学好,工式不懂,郁闷.
我觉得,你出1000分都不一定有人做。难不难先不说,乍一看都让人害怕,更别提做了。
编程方面说看起来不是很难,毕竟题目中给了算法;但数学角度上貌似挺麻烦!
有时间可以一试!