⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zyh.c

📁 最优化课程中要用到的所有最优化算法
💻 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 + -