POJ--1379[Run Away] 模拟退火

 

算法:模拟退火http://www.cppblog.com/RyanWang/archive/2010/05/05/106112.html

 
 
 
CODE:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
const int RanN=30;
const int RunN=30;
const double P=0.6;
int X,Y,M;
struct px
{
	double x,y,d;
};
struct px stu[1001];
struct px S[RanN+1];
int Max(int x,int y)
{
	return x>y?x:y;
}
double get_dis(px t)
{
	double sum=1e10,temp;
	int i;
	for(i=1;i<=M;i++)
	{
		temp=sqrt((double)((t.x-stu[i].x)*(t.x-stu[i].x)+(t.y-stu[i].y)*(t.y-stu[i].y)));
		if(sum>temp)
			sum=temp;
	}
	return sum;
}
void get_ans()
{
	int i,r;
	double delta,epsilon=1e-2,k1,k2,max;
	px temp;
	delta=(double)Max(X,Y)/(sqrt(1.0*M));
	for(r=1;r<=RanN;r++)
	{
		S[r].x=double(rand()%1000+1)/1000.000*X;
		S[r].y=double(rand()%1000+1)/1000.000*Y;
		S[r].d=get_dis(S[r]);
	}
	while(delta>epsilon)
	{
		for(r=1;r<=RanN;r++)
		{
			for(i=1;i<=RunN;i++)
			{
				k1=double(rand()%1000+1)/1000.000*delta;//定长度
				k2=sqrt(delta*delta-k1*k1);//k1,k2的平方和开根号是delta
				if (rand()%2==1) k1*=-1;//定方向
				if (rand()%2==1) k2*=-1;
				temp.x=S[r].x+k1;
				temp.y=S[r].y+k2;
				if(temp.x<=X&&temp.x>=0&&temp.y<=Y&&temp.y>=0)//在界内才处理
				{
					max=get_dis(temp);
					if(max>S[r].d)//直接更新该点
					{S[r].d=max;S[r].x=temp.x;S[r].y=temp.y;}
				}
			}
		}
		delta*=P;
	}
	max=0;
	px ans;
	for(i=1;i<=RanN;i++)
	{
		if(S[i].d>max)
		{max=S[i].d;ans=S[i];}
	}
	printf("The safest point is (%.1lf, %.1lf)./n",ans.x,ans.y);
}
int main ()
{
    int T,i;
    scanf("%d",&T);
    //srand((unsigned)time(NULL)); 
    while(T--)
    {
        scanf("%d%d%d",&X,&Y,&M);
        for(i=1;i<=M;i++)
        {
            scanf("%lf%lf",&stu[i].x,&stu[i].y);
            //if(stu[i].x<0||stu[i].x>X||stu[i].y<0||stu[i].y>Y)//除去界外点
			//{i--;M--;}
        }
        get_ans();
    }
	return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__简言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值