• 模拟退火算法解决函数优化问题


    一、实验目的

    1. 掌握模拟退火算法的基本原理和步骤。

    2. 复习VBVC的基本概念、基本语法和编程方法,并熟练使用VBVC编写模拟退火算法程序。

    二、实验设备

    微机

    三、实验原理

    模拟退火算法是基于Monte Carlo迭代求解策略的一种随机寻优算法,其出发点是基于物理退火过程与组合优化之间的相似性,模拟退火算法由某一较高初温开始,利用具有概率突跳特性的Metropolis抽样策略在解空间中进行随机搜索,伴随温度的不断下降重复抽样过程,最终得到问题的全局最优解。

    标准模拟退火算法的一般步骤可描述如下:

    (1)m=0,给定初温tm,随机产生初始状态sm;

    (2)Repeat

    sold=sm;

    (2.1)Repeat

    (2.1.1)产生新状态:snew=Generate(sold)

    (2.1.2)若min{1, exp[(C(sold)-C(snew))/tm]}³random[0, 1],则sold=snew;

    (2.1.3)Until抽样稳定准则满足;

    (2.2)退温:tm+1=update(tm)sm+1=sold,m=m+1

    (3)Until算法终止准则满足;

    (4)输出算法搜索结果:sm。

    四、预习要求

    1. 认真阅读教材中模拟退火算法的基本原理与步骤。

    2. 复习VBVC的基本概念、基本语法和编程方法。

    2.标准模拟退火算法流程图


    代码实现::::::::::::::::::::

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <math.h>
    #define MAXN 10  //个数
    const double MIN = 100.00;  //数据范围
    const double INIT_T = 300;  //初始温度
    const double RATE = 0.95;    //温度衰减率
    const double FINAL_T = 0.1;  //凝固温度
    const int IN_LOOP = 130;  //内层循环次数
    const int OUT_LOOP = 100;   //外层循环次数 
    const int P_LIMIT = 10000;  //概率选择次数
    double cost = 0; //用于记录次数
    
    struct path   //数据类型存储
    {
    	double NUM[MAXN];
    	double sum;
    };
    
    path bestpath;  //最优解
    
    path getnext(path p) //得到下一组数据的函数
    {
    	int x, i;
    	double y;
    	path ret;
    	ret = p;
    	cost ++;
    	printf("第%.0lf次改变数字:\n", cost);
    	x = (int)(10.0*rand()/(RAND_MAX+1.0)); //随机产生一个0-9的数更换
    	printf("更换的是%d:%lf", x, ret.NUM[x]);
    	ret.sum -= ret.NUM[x]*ret.NUM[x];
    	y = 2*MIN*rand()/(RAND_MAX+1.0)-MIN;//更换后的数据
    	printf("变成:%lf\n", y);
    	ret.NUM[x] = y; //覆盖
    	ret.sum += y*y; //更新总和
    	for(i=0; i<MAXN; i++)
    	{
    		printf("%lf__", bestpath.NUM[i]);
    	}
    	printf("总和:%lf\n\n\n", ret.sum);
    	return ret;
    }
    void init()
    {//初始化
    	int i;
    	char ss[66];
    	bestpath.sum = 0;
    	srand((int)(time(0)));
    	printf("初始状态:");
    	for(i=0; i<MAXN; i++)
    	{//随机产生10个-100到100的数
    		bestpath.NUM[i] = 2*MIN*rand()/(RAND_MAX+1.0)-MIN;
    		bestpath.sum += bestpath.NUM[i]*bestpath.NUM[i];
    		printf("!!!%lf", bestpath.NUM[i]);
    	}
    	printf("$$$%lf\n", bestpath.sum);
    	gets(ss); //用于记录初始状态
    	
    }
    void sa()
    {
    	double T;
    	double rnd = rand()%10000 /10000.0;
    	path curpath, newpath;
    	int i, P_t=0, A_t=0;
    	double delta; //差
    	T = INIT_T;
    	curpath = bestpath;
    	while(true)
    	{
    		for (i=1; i<=IN_LOOP; i++)
    		{
    			newpath = getnext(curpath);//产生新数据
    			delta = newpath.sum - curpath.sum;
    			if(delta < 0.0)
    			{//符合局部优化条件,更新
    				curpath = newpath;
    				P_t = 0;
    				A_t = 0;
    			}
    			else
    			{//跳变
    				rnd = rand()%10000 /10000.0;
    				double p = exp(-delta/T);
    				if (p > rnd) //符合概率,更新
    					curpath = newpath;
    				P_t++;
    				
    			}
    			if (P_t >=P_LIMIT) 
    			{//概率上限限制 
    				A_t++; 
    				break; 
    			} 
    		}
    		if (curpath.sum<bestpath.sum)
    		{//当前数据较优,更新最佳答案
    			bestpath = curpath;
    		}
    		if ( A_t >= OUT_LOOP || T < FINAL_T) break;
    		T = T * RATE;//温度衰减
    	}
    }
    
    void main()
    {
    	int i;
    	init();
    	sa();
    
    	printf("Best number is: ");
    	for(i=0; i<MAXN; i++)
    	{
    		printf("%lf__", bestpath.NUM[i]);
    	}
    	printf("/nThe result is: %lf\n", bestpath.sum);
    
    }
    



  • 相关阅读:
    写在之前
    Fedora Core 3安装杂记(三)
    Fedora Core 3安装杂记(一)
    Firefox 1.0真的挺好用的
    发现Google加了英文页面翻译功能(Beta)
    Fedora Core 3安装杂记(四)
    在FC3的日子里……
    ASP面向对象编程探讨及比较
    显卡千万不能买带风扇的……
    字符串(strcat)
  • 原文地址:https://www.cnblogs.com/zhujinghui/p/3369246.html
Copyright © 2020-2023  润新知