您的位置:首页 > 其它

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

2012-11-02 20:25 218 查看
一、实验目的

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

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

二、实验设备

微机

三、实验原理

模拟退火算法是基于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. 复习VB、VC的基本概念、基本语法和编程方法。



图2.1 标准模拟退火算法流程图

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

#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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: