POJ2420.A Star not a Tree?(模拟退火)
Posted sigongzi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2420.A Star not a Tree?(模拟退火)相关的知识,希望对你有一定的参考价值。
题解
开始学习随机化算法= =
模拟退火的板子往上套就行,莫名其妙的就过了
可能数据太水,实现的具体细节可看代码
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
//#define ivorysi
#define MAXN 105
#define eps 1e-8
#define pb push_back
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int N;
struct Point {
db x,y;
}P[MAXN];
inline db o (db x) {return x * x;}
db GetSum(Point s) {
db res = 0;
for(int i = 1 ; i <= N ; ++i) {
res += sqrt(o(s.x - P[i].x) + o(s.y - P[i].y));
}
return res;
}
void Init() {
for(int i = 1 ; i <= N ; ++i) scanf("%lf%lf",&P[i].x,&P[i].y);
}
u32 Rand() {
static u32 x = 1736382156;
return x += x << 2 | 1;
}
db Range_rand() {
return (db)(Rand() % 10000) / 10000;//生成一个[0,1)之内的概率
}
void Solve() {
db delta = 0.98,T = 1000;
db ans = GetSum(P[1]);
Point s = P[1];//选一个点当做初始点
while(T > eps) {
db tmp = 1e18;
Point t;
for(int i = 0 ; i < 4 ; ++i) {
Point z;
z.x = s.x + dx[i] * T;z.y = s.y + dy[i] * T;
db x = GetSum(z);
if(x < tmp) tmp = x,t = z;
}
//找四个方向里最小的那个尝试更新答案
if(tmp < ans) {
ans = tmp;
s = t;
}
else {//以一定的概率接受这个解
if(exp((ans - tmp) / T) > Range_rand()) {
ans = tmp;
s = t;
}
}
T = delta * T;//降温
}
printf("%.0f",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
while(scanf("%d",&N) != EOF && N) {
Init();
Solve();
}
}
以上是关于POJ2420.A Star not a Tree?(模拟退火)的主要内容,如果未能解决你的问题,请参考以下文章
poj-2420 A Star not a Tree?(模拟退火算法)
POJ 2420 A Star not a Tree? (计算几何-费马点)
poj 2420 A Star not a Tree?——模拟退火