一.模拟退火算法的原理
模拟退火算法是一种元启发式(Meta-Heuristics)算法,来源于固体退火原理,将固体加热至充分高的温度,再让其徐徐冷却。加热时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为e-ΔE/kt,其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。
二.模拟退火算法的模型
① 初始化:初始温度T(充分大),初始解状态S(算法迭代的起点), 每次迭代次数L
② for k=1 to L 做③至⑥
③ 产生新解S’
④ 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
⑤ 若Δt′<0则接受S’作为新的当前解,否则以概率e-Δt/k接受S’作为新的当前解
⑥ 如果满足终止条件则输出当前解作为最优解,结束程序
模拟退火算法是一种元启发式(Meta-Heuristics)算法,来源于固体退火原理,将固体加热至充分高的温度,再让其徐徐冷却。加热时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为e-ΔE/kt,其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。
二.模拟退火算法的模型
① 初始化:初始温度T(充分大),初始解状态S(算法迭代的起点), 每次迭代次数L
② for k=1 to L 做③至⑥
③ 产生新解S’
④ 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
⑤ 若Δt′<0则接受S’作为新的当前解,否则以概率e-Δt/k接受S’作为新的当前解
⑥ 如果满足终止条件则输出当前解作为最优解,结束程序
⑦ T逐渐减少,然后转②
//hdu 3932,求点的最小距离的最大值
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
#define PI 3.14159265358
#define LL long long
#define MAXN 1005
const double eps = 1e-3;
const double INF = 1e20;
int max(int a, int b)
{
if (a > b) return a;
return b;
}
class Point
{
public:
Point()
{
maxDis = -1;
}
Point(double tx, double ty)
{
x = tx;
y = ty;
maxDis = -1;
}
double x, y, maxDis;
};
double dis(Point a, Point b)
{
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
Point hole[MAXN], fp[MAXN];
int X, Y, N, L, P;
double delta;
int main()
{
// Point a(0, 0), b(3, 4);
// cout << dis(a, b);
// cout<<"- -"<<endl;
while (cin >> X >> Y >> N)
{
L = 25, P = 15, delta = double(max(X, Y)) / (sqrt(1.0*N));
srand((unsigned int)time(NULL));
for (int i = 0; i <= N - 1; i++)
{
cin >> hole[i].x >> hole[i].y;
}
for (int i = 0; i <= P - 1; i++)
{
// cout << "- -" << endl;
fp[i].x = double(rand() % 1000 + 1) / 1000 * X;
fp[i].y = double(rand() % 1000 + 1) / 1000 * Y;
fp[i].maxDis = -1;
for (int j = 0; j <= N - 1; j++)
{
double tp = dis(fp[i], hole[j]);
if (fp[i].maxDis < tp) fp[i].maxDis = tp;//找最大距离,用-1
}
}
while (delta>eps)
{
for (int i = 0; i <= P - 1; i++)
{
// Point tmp = fp[i];
for (int k = 1; k <= L; k++)
{
double alpha = double(rand() % 1000 + 1) / 1000.0 * 2 * PI;
Point tp;
tp.x = fp[i].x + cos(alpha)*delta;
tp.y = fp[i].y + sin(alpha)*delta;
if (tp.x<0 || tp.x>X || tp.y<0 || tp.y>Y) continue;
tp.maxDis = -1;
for (int j = 0; j <= N - 1; j++)
{
double distp = dis(tp, hole[j]);
if (tp.maxDis < distp) tp.maxDis = distp;
}
// if (tp.x>=300||tp.y>=300)
// printf("##---(%.1lf,%.1lf)---%.1lf\n", tp.x, tp.y, tp.maxDis);
if (tp.maxDis < fp[i].maxDis)
{
fp[i].maxDis = tp.maxDis;
fp[i].x = tp.x;
fp[i].y = tp.y;
}
}
}
delta *= 0.8;
}
int index = 0;
for (int i = 0; i <= P - 1; i++)
{
// printf("---(%.1lf,%.1lf)---%.1lf\n", fp[i].x, fp[i].y, fp[i].maxDis);
if (fp[index].maxDis > fp[i].maxDis) index = i;
}
printf("(%.1lf,%.1lf).\n%.1lf\n", fp[index].x, fp[index].y, fp[index].maxDis);
//printf("The safest point is (%.1lf, %.1lf).\n", fp[index].x, fp[index].y);
}
return 0;
}
/*
//POJ 1379 求点的最大距离的最小值
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
#define PI 3.14159265358
#define LL long long
#define MAXN 1005
const double eps = 1e-3;
const double INF = 1e20;
int max(int a, int b)
{
if (a > b) return a;
return b;
}
class Point
{
public:
Point()
{
maxDis = INF;
}
Point(double tx, double ty)
{
x = tx;
y = ty;
maxDis = INF;
}
double x, y, maxDis;
};
double dis(Point a, Point b)
{
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
Point hole[MAXN], fp[MAXN];
int X, Y, N, L, P;
double delta;
int main()
{
// Point a(0, 0), b(3, 4);
// cout << dis(a, b);
// cout<<"- -"<<endl;
int T;
cin >> T;
while (T--)
{
cin >> X >> Y >> N;
L = 25, P = 15, delta = double(max(X, Y)) / (sqrt(1.0*N));
srand((unsigned int)time(NULL));
for (int i = 0; i <= N - 1; i++)
{
cin >> hole[i].x >> hole[i].y;
}
for (int i = 0; i <= P - 1; i++)
{
// cout << "- -" << endl;
fp[i].x = double(rand() % 1000 + 1) / 1000 * X;
fp[i].y = double(rand() % 1000 + 1) / 1000 * Y;
fp[i].maxDis = INF;
for (int j = 0; j <= N - 1; j++)
{
double tp = dis(fp[i], hole[j]);
if (fp[i].maxDis > tp) fp[i].maxDis = tp;//找最大距离,用-1
}
}
while (delta>eps)
{
for (int i = 0; i <= P - 1;i++)
{
// Point tmp = fp[i];
for (int k = 1; k <= L; k++)
{
double alpha = double(rand() % 1000+1) / 1000.0 * 2 * PI;
Point tp;
tp.x = fp[i].x + cos(alpha)*delta;
tp.y = fp[i].y + sin(alpha)*delta;
if (tp.x<0 || tp.x>X || tp.y<0 || tp.y>Y) continue;
tp.maxDis = INF;
for (int j = 0; j <= N - 1; j++)
{
double distp = dis(tp, hole[j]);
if (tp.maxDis > distp) tp.maxDis = distp;
}
// if (tp.x>=300||tp.y>=300)
// printf("##---(%.1lf,%.1lf)---%.1lf\n", tp.x, tp.y, tp.maxDis);
if (tp.maxDis > fp[i].maxDis)
{
fp[i].maxDis = tp.maxDis;
fp[i].x = tp.x;
fp[i].y = tp.y;
}
}
}
delta *= 0.8;
}
int index = 0;
for (int i = 0; i <= P - 1; i++)
{
// printf("---(%.1lf,%.1lf)---%.1lf\n", fp[i].x, fp[i].y, fp[i].maxDis);
if (fp[index].maxDis < fp[i].maxDis) index = i;
}
// printf("(%.1lf,%.1lf).\n%.1lf\n", fp[index].x, fp[index].y, fp[index].maxDis);
printf("The safest point is (%.1lf, %.1lf).\n", fp[index].x, fp[index].y);
}
return 0;
}
*/