/****************************************************************
* 名称 : 确定搜索区间的外推法 *
* 说明 : 假设函数f( x )具有单谷性,即在所考虑的区间内部, *
* 函数f( x )有唯一的极小点x0。为了确定极小点x所在 *
* 的区间,应使函数f( x )在[ a, b ]区间内形成 *
* “高-低-高”趋势。 *
* 作者 : *** *
* 日期 : 2011-05-22 *
****************************************************************/
#include/****************************************************
* 函数声明 *
****************************************************/
double f( double );
/****************************************************
* 主函数 *
****************************************************/
int main( void )
{
double x_1, x_2, x_3; //定义横坐标
double y_1, y_2, y_3; //定义相应的纵坐标,以减少调用函数的次数,以前没有想到这一点,程序中的重复计算越少越好
int step; //搜索步长
double tmp; //中间变量
//初始化搜索
step = 1; //step的初值对搜索次数影响不大,因为调整时是按照幂次
x_1 = 0; //x_1对搜索次数的影响很大
y_1 = f( x_1 );
x_2 = x_1 + step;
y_2 = f( x_2 );
//开始搜索
if( y_2 > y_1 ) //调整搜索方向
{
step = -step; //C语言中有负号运算符
tmp = x_1; //对x_1和x_2进行交换
x_1 = x_2;
x_2 = tmp;
tmp = y_1; //对y_1和y_2进行交换
y_1 = y_2;
y_2 = tmp;
}
else //空语句可以增加程序的易读性
{
;
}
x_3 = x_2 + step; //为了减少代码的长度,应该修改成do...while的形式
y_3 = f( x_3 ); //但修改之后,逻辑性不强
while( y_3 < y_2 )
{
x_1 = x_2;
x_2 = x_3;
x_3 = x_2 + step;
y_1 = y_2;
y_2 = y_3;
y_3 = f( x_3 );
step = 2 * step;
}
if( x_1 > x_3 ) //将区间按照从小到大的顺序调整,只需调整两端点
{ //这样调整是为了符合“左小右大”的习惯
tmp = x_1;
x_1 = x_3;
x_3 = tmp;
tmp = y_1;
y_1 = y_3;
y_3 = tmp;
}
printf( "x_1 = %f, x_2 = %f, x_3 = %f\n", x_1, x_2, x_3 );
printf( "y_1 = %f, y_2 = %f, y_3 = %f\n", y_1, y_2, y_3 );
return( 0 ); //返回0,表示程序结束
}
/********************************************************
* 函数名称 : 目标函数 *
* 输入变量 : 横坐标x *
* 输出变量 : 纵坐标y *
* 说 明 : 目标函数要求具有单谷性 *
********************************************************/
double f( double x )
{
double y;
y = x * x - 2 *x + 1;
return( y );
}