📄 zyh.c
字号:
//////////////////////////////
////// 最优化 /////////
//////信号与信息处理 /////////
////// 刘君 /////////
//////06020810021009//////////
//////////////////////////////
//此程序使用Fibonnacci法,用于计算目标函数在给定区间和精度的条件下的最小值//
//////////////////////////////////////////////////////
#include <stdio.h>
#include <math.h>
////////other defination//////////////////////////////
#define BOOL int
////////the area of calculation///////////////////////
#define MIN 0 //区间下界
#define MAX 1 //区间上界
#define L 0.2 //计算精度
#define FUN "exp( -x ) + x*x"
#define CON 0.01 //判别常数
////////////the declaration of functions//////////////
void get_fib_seq( int fib[20] );
int get_n( float l, int fib[20], float min, float max );
float fun( float x);
BOOL single_peak( void );
void fun_MIN( float *a_min, float *b_min, int n, int fib[20] );
//////////////////////////////////////////////////////
////////the main funciton/////////////////////////////
int main( void )
{
BOOL s_p;
float a_min, b_min;
float result;
int k;
int n;
float min = MIN, max = MAX;
float l = L;
float con = CON;
int fib[20];
///////determine whether it is single peak//////////
s_p = single_peak();
if( !s_p )
{
printf( "输入的不是单峰函数,请重新输入!\n" );
return 0;
}
///////stat/////////
printf( "本题使用Fibonnacci法求目标函数最小值\n" );
printf( "输入的目标函数为: " );
printf( FUN );
printf( "\n" );
printf( "区间为:[ %f, %f]\n", min, max );
printf( "精度为:L <= %f\n", l );
printf( "判别常数为:%f\n", con );
get_fib_seq( fib );
n = get_n( L, fib, MIN, MAX );
fun_MIN( &a_min, &b_min, n, fib );
printf( "\n经过%d次迭代,目标函数值位于 %f 与 %f 之间 \n", n, a_min, b_min );
while(1);
return 1;
}
/////////get Fibonacci sequence///////////////////////
void get_fib_seq( int fib[20] )
{
int i;
fib[0] = fib[1] = 1;
for( i = 2; i < 20; i++ )
{
fib[i] = fib[i-1] + fib[i-2];
}
}
/////////get the count of calculation////////////////
int get_n( float l, int fib[20], float min, float max )
{
float f;
int i;
int n;
f = ( max - min ) / l;
for( i = 0; i < 20; i++ )
{
if( fib[i] >= f )
{
n = i;
return n;
}
}
}
////////the function of destionation//////////////////
float fun( float x)
{
float result;
result = exp( -x ) + x*x;
return result;
}
////////determine whether the fun is single peak///////
BOOL single_peak( void )
{
return 1; //还不知道怎样用程序判断一个函数为单峰函数
}
////////the main process function//////////////////////
void fun_MIN( float *a_min, float *b_min, int n, int fib[20] )
{
int k = 1;
float fy, fu;
float ak, bk;
float y, u;
ak = MIN;
bk = MAX;
y = ak + (float)fib[n-2] / fib[n] * ( bk - ak );
u = ak + (float)fib[n-1] / fib[n] * ( bk - ak );
fy = fun( y );
fu = fun( u );
printf( "计算过程如下: \n\n" );
printf( " k ak bk yk uk f(yk) f(uk)\n\n" );
LOOP:
printf( " %-3d%-10f%-10f%-10f%-10f%-10f%-10f\n",k,ak,bk,y,u,fy,fu );
if( fy > fu )
{
ak = y;
y = u;
fy = fu;
u = ak + (float)fib[n-k-1] / fib[n-k] * ( bk - ak );
fu = fun( u );
if( k == (n - 2) )
{
k ++;
printf( " %-3d%-10f%-10f%-10f%-10f%-10f%-10f\n",k,ak,bk,y,u,fy,fu );
goto LOOPEND;
}
k ++;
goto LOOP;
}
else
{
bk = u;
u = y;
fu = fy;
y = ak + (float)fib[n-k-2] / fib[n-k] * ( bk - ak );
fy = fun( y );
if( k == (n - 2) )
{
k ++;
printf( " %-3d%-10f%-10f%-10f%-10f%-10f%-10f\n",k,ak,bk,y,u,fy,fu );
goto LOOPEND;
}
k ++;
goto LOOP;
}
LOOPEND:
k ++;
u = y + CON;
fu = fun( u );
if( fy > fu )
{
*a_min = ak = y;
*b_min = bk;
printf( " %-3d%-10f%-10f%-10f%-10f%-10f%-10f\n",k,ak,bk,y,u,fy,fu );
}
else
{
*a_min = ak;
*b_min = bk = y;
printf( " %-3d%-10f%-10f%-10f%-10f%-10f%-10f\n",k,ak,bk,y,u,fy,fu );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -