【模拟退火】poj2420 A Star not a Tree?

题意:求平面上一个点,使其到给定的n个点的距离和最小,即费马点。

模拟退火的思想是随机移动,然后100%接受更优解,以一定概率接受更劣解。移动的过程中温度缓慢降低,接受更劣解的概率降低。

在网上看到的代码都不太靠谱,我这个代码的关键之处在于,每一次随机走点时,不是1次,而是在10次随机中取最优者作为当前这一步的随机结果,这样运行时非常优秀。

T降温时乘0.9/0.99这样的数都行,越接近1越准确,但速度越慢。

这份代码即使用0.9也可以ac。

#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
const double EPS=0.00000001;
const double PI=acos(-1.0);
struct Point{
	double x,y;
	Point(const double &x,const double &y){
		this->x=x;
		this->y=y;
	}
	Point(){}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
	double length(){
		return sqrt(x*x+y*y);
	}
}a[105],p;
double ans;
int n;
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
	return Vector(a.x-b.x,a.y-b.y);
}
Vector operator + (const Vector &a,const Vector &b){
	return Vector(a.x+b.x,a.y+b.y);
}
Vector operator * (const double &K,const Vector &v){
	return Vector(K*v.x,K*v.y);
}
double calc(Point p){
	double res=0.0;
	for(int i=1;i<=n;++i){
		res+=(a[i]-p).length();
	}
	return res;
}
int main(){
	srand(233);
//	freopen("poj2420.in","r",stdin);
//	freopen("poj2420.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		a[i].read();
		p.x+=a[i].x;
		p.y+=a[i].y;
	}
	p.x/=(double)n;
	p.y/=(double)n;
	ans=calc(p);
	double T=100000.0;
	while(T>EPS){
		double bestnow=10000000.0;
		Point besttp;
		for(int i=1;i<=10;++i){
			double rad=(double)(rand()%10000+1)/10000.0*2.0*PI;
			Point tp=p+T*Point(cos(rad),sin(rad));
			double now=calc(tp);
			if(now<bestnow){
				bestnow=now;
				besttp=tp;
			}
		}
		if(bestnow<ans || exp((ans-bestnow)/T)*10000.0>(double)(rand()%10000)){
			ans=bestnow;
			p=besttp;
		}
		T*=0.99;
	}
	printf("%.0f\n",ans);
	return 0;
}
时间: 2024-12-14 05:50:48

【模拟退火】poj2420 A Star not a Tree?的相关文章

poj-2420 A Star not a Tree?(模拟退火算法)

题目链接: A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5219   Accepted: 2491 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allo

[POJ2420]A Star not a Tree?(模拟退火)

题目链接:http://poj.org/problem?id=2420 求费马点,即到所有其他点总和距离最小的点. 一开始想枚举一个坐标,另一个坐标二分的,但是check的时候还是O(n)的,复杂度相当于O(n^2lgn),没意义. 学习一种神贪心,模拟退火.感觉和启发式搜索有点像啊,又有点像牛顿迭代. 思路就是,固定一个点和一个步长,从这个点开始向四个方向扩展,扩展的步长就是当前步长.如果扩展到的点可以更新答案,那么记住这个点,也就是说这个贪心方向(梯度?)是正确的.就可以拿着这个点继续沿着这

[POJ2420]A Star not a Tree?

来源: Waterloo Local 2002.01.26 题目大意: 找出$n$个点的费马点. 思路: 模拟退火. 首先任取其中一个点(或随机一个坐标)作为基准点,每次向四周找距离为$t$的点,如果找到的点总距离更小,就把该点作为新的基准点. 每次找完后降低温度$t$,重复上述过程,直到温度$t$低于阈值$threshold$. 另外注意在POJ上double类型输出不能用%lf,只能用%f,一开始因为这个WA了好几次. 1 #include<cmath> 2 #include<cst

[模拟退火][UVA10228] A Star not a Tree?

好的,在h^ovny的安利下做了此题 模拟退火中的大水题,想当年联赛的时候都差点打了退火,正解貌似是三分套三分,我记得上一道三分套三分的题我就是退火水过去的... 貌似B班在讲退火这个大玄学... 这题还是比较简单的啦~ 随机化坐标x,y就可以啦 然而格式错了n遍.....死的心都有了 最后输出是四舍五入!!!四舍五入!!!四舍五入!!! 两组答案中间有空行!!!有空行!!!有空行!!!   然后只要会退火的板子就可以啦 //LevenKoko#include<bits/stdc++.h> u

UVA 10228 - Star not a Tree?(模拟退火)

UVA 10228 - Star not a Tree? 题目链接 题意:给定一些点,费马点(到这些点距离和最短),输出距离和 思路:模拟退火去搞,初始温度1W步,降温系数设为0.83,然后每次找周围4个方向,做10次保证答案准确 代码: #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <cstdlib> #include <al

poj2420A Star not a Tree?(模拟退火)

链接 求某一点到其它点距离和最小,求这个和,这个点 为费马点. 做法:模拟退火 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #inclu

POJ 2420 A Star not a Tree? (计算几何-费马点)

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3435   Accepted: 1724 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you

[POJ 2420] A Star not a Tree?

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4058   Accepted: 2005 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you

【POJ 2420】A Star not a Tree?

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3929   Accepted: 1952 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you