模拟退火算法的原理
模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为e-ΔE/(kT),其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件S。
模拟退火算法的模型
1模拟退火算法可以分解为解空间、目标函数和初始解三部分。
2模拟退火的基本思想:
(1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点),每个T值的迭代次数L
(2) 对k=1,……,L做第(3)至第(6)步:
(3) 产生新解S′
(4) 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
(5) 若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/T)接受S′作为新的当前解.
(6) 如果满足终止条件则输出当前解作为最优解,结束程序。终止条件通常取为连续若干个新解都没有被接受时终止算法。
(7) T逐渐减少,且T->0,然后转第2步。
Run Away
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 334 Accepted Submission(s): 114
Problem Description
One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look completely harmless at the first sight. But when activated, they start to throw out very hot java, uh ... pardon, lava. Unfortunately, all known paths to the Center Room (where the Sarcophagus is) contain a trigger that activates the trap. The ACM were not able to avoid that. But they have carefully monitored the positions of all the holes. So it is important to find the place in the Large Room that has the maximal distance from all the holes. This place is the safest in the entire room and the archaeologist has to hide there.
Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing three integers X, Y, M separated by space. The numbers satisfy conditions: 1 <= X,Y <=10000, 1 <= M <= 1000. The numbers X and Yindicate the dimensions of the Large Room which has a rectangular shape. The number M stands for the number of holes. Then exactly M lines follow, each containing two integer numbers Ui and Vi (0 <= Ui <= X, 0 <= Vi <= Y) indicating the coordinates of one hole. There may be several holes at the same position.
Output
Print exactly one line for each test case. The line should contain the sentence "The safest point is (P, Q)." where P and Qare the coordinates of the point in the room that has the maximum distance from the nearest hole, rounded to the nearest number with exactly one digit after the decimal point (0.05 rounds up to 0.1).
Sample Input
3
1000 50 1
10 10
100 100 4
10 10
10 90
90 10
90 90
3000 3000 4
1200 85
63 2500
2700 2650
2990 100
Sample Output
The safest point is (1000.0, 50.0).
The safest point is (50.0, 50.0).
The safest point is (1433.0, 1669.8).
Source
Central Europe 1999
Recommend
Eddy
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<math.h>
#include<iostream>
using namespace std;
struct solve
{
double x,y,val;
};
solve tr[51];
double recx[1025],recy[1025];
double X,Y;
int M;
double Evaluate(solve tt)
{
double Min=1e8;
int i;
for (i=1;i<=M;i++)
if ((tt.x-recx[i])*(tt.x-recx[i])+(tt.y-recy[i])*(tt.y-recy[i])<Min)
Min=(tt.x-recx[i])*(tt.x-recx[i])+(tt.y-recy[i])*(tt.y-recy[i]);
return Min;
}
void Simulated_Annealing()
{
double Temper=X+Y,eps=1e-3,dx,dy;
int i,j;
solve tmp;
for (i=1;i<=50;i++)
{
tr[i].x=((rand()%1000+1)*1.0/1000.00)*X;
tr[i].y=((rand()%1000+1)*1.0/1000.00)*Y;
tr[i].val=Evaluate(tr[i]);
}
while (Temper>eps)
{
for (i=1;i<=50;i++)
{
for (j=1;j<=50;j++)
{
dx=(double)(rand()%1000+1)*1.0/1000.00*Temper;
dy=sqrt(Temper*Temper-dx*dx);
if (rand()&1) dx*=-1;
if (rand()&1) dy*=-1;
tmp.x=tr[i].x+dx;
tmp.y=tr[i].y+dy;
if (tmp.x>=0 && tmp.x<=X && tmp.y>=0 && tmp.y<=Y)
{
double value=Evaluate(tmp);
if (value>tr[i].val)
{
tr[i]=tmp;
tr[i].val=value;
}
}
}
}
Temper*=0.6;
}
int url=1;
for (i=2;i<=50;i++)
if (tr[i].val>tr[url].val)
url=i;
printf("The safest point is (%.1lf, %.1lf).
",tr[url].x,tr[url].y);
}
int main()
{
srand(unsigned(time(0)));
int T,i;
scanf("%d",&T);
while (T--)
{
scanf("%lf%lf%d",&X,&Y,&M);
for (i=1;i<=M;i++)
scanf("%lf%lf",&recx[i],&recy[i]);
Simulated_Annealing();
}
return 0;
}