题目链接

一个比较好的解释?

模拟退火(Simulated Annealing,SA):

(1)初始化一个温度(充分大)、初始解状态S、每个T值的迭代次数。

(2)对i=1,...,L,做(3)至(7)步。

(3)产生新解S'。

(4)计算Δt=C(S')-C(S),其中C(S)为评价函数。

(5)若Δt<0,则接受新解S'作为当前解;否则以exp(-Δt/(kT))的概率接受S'作为当前解(k为玻尔兹曼常数,一般不管它?)

(6)如果满足终止条件,则输出当前解作为最优解,结束程序。

终止条件通常为连续若干个新解都没有被接受时终止算法。

(7)T逐渐减少,且T->0,转(2)。

//1028kb	6256ms
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define D (0.96)//as big as possible?
#define Rand() ((rand()<<1)-RAND_MAX)
const int N=10005; int n;
struct Node{
int w;
double x,y;
}p[N]; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline double Sqr(double x){
return x*x;
}
inline double Dis(double x,double y,int i){
return sqrt(Sqr(x-p[i].x)+Sqr(y-p[i].y));
}
double Calc(double x,double y)
{
double res=0;
for(int i=1; i<=n; ++i)
res+=Dis(x,y,i)*p[i].w;//i->dis*w[i] i对答案产生dis*w[i]的影响
return res;
}
void SA()
{
double ansx=0,ansy=0,ans;
for(int i=1; i<=n; ++i)
ansx+=p[i].x*p[i].w, ansy+=p[i].y*p[i].w;
ansx/=n, ansy/=n, ans=Calc(ansx,ansy);
for(int Time=1; Time<=5; ++Time)//多次!需要记录ans及now。
{//一次大概要1000次。
double T=1000,nowx=ansx,nowy=ansy,now=Calc(ansx,ansy),res,xx,yy;
while(T>1e-12)
{
// xx=ansx+T*(2*(rand()%Max)-Max),yy=ansy+T*(2*(rand()%Max)-Max);//x(y)+[-Max,Max-2] 不能只是用坐标的最大值。。delta应该够大些。
xx=nowx+T*Rand(),yy=nowy+T*Rand();//x(y)+[-RAND_MAX,RAND_MAX-1]
res=Calc(xx,yy);
if(res<ans) ans=res, ansx=xx, ansy=yy;
if(res<now)
nowx=xx, nowy=yy, now=res;
else if(exp((now-res)/T)*RAND_MAX>rand())//exp(-delta/T)>rand()/RAND_MAX
nowx=xx, nowy=yy;
T*=D;
}
}
printf("%.3lf %.3lf",ansx,ansy);
} int main()
{
srand(20180501);
n=read();
for(int i=1; i<=n; ++i) p[i].x=read(),p[i].y=read(),p[i].w=read();
SA();
return 0;
}

爬山算法:

感觉流程和代码有点。。不写了。

每次将当前情况(所有点)对答案的影响计算出来,答案接受影响*T后的值;T逐渐减小,直至T足够小输出答案。

//1016kb	2584ms
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define D (0.97)//尽量大些?
const int N=10005; int n;
struct Node{
int w;
double x,y;
}p[N]; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline double Sqr(double x){
return x*x;
}
inline double Dis(double x,double y,int i){
return sqrt(Sqr(x-p[i].x)+Sqr(y-p[i].y));
}
void Hill_Climb()
{
double ansx=0,ansy=0;
for(int i=1; i<=n; ++i)
ansx+=p[i].x*p[i].w, ansy+=p[i].y*p[i].w;
ansx/=n, ansy/=n;
double T=1000,dis,xx,yy;
while(T>1e-8)
{
xx=yy=0;
for(int i=1; i<=n; ++i){
dis=Dis(ansx,ansy,i);
if(dis<1e-10) continue;//除0。。
xx+=(p[i].x-ansx)*p[i].w/dis,//每个点对答案产生x(y)/r*w[i]的影响。
yy+=(p[i].y-ansy)*p[i].w/dis;
}
ansx+=xx*T, ansy+=yy*T;
T*=D;
}
printf("%.3lf %.3lf",ansx,ansy);
} int main()
{
n=read();
for(int i=1; i<=n; ++i) p[i].x=read(),p[i].y=read(),p[i].w=read();
Hill_Climb();
return 0;
}

BZOJ.3680.吊打XXX(模拟退火/爬山算法)的更多相关文章

  1. bzoj 2428: [HAOI2006]均分数据 && bzoj 3680 : 吊打XXX 模拟退火

    每次把元素随便扔随机一个初始解,退火时每次随机拿一个元素扔到随机一个集合里,当温度高时因为状态不稳定扔到那个元素和最小的里边. 如果新解优,更新ans. 把原式拆一下,就可以用int存了. bzoj ...

  2. 洛谷 P1337 平衡点 & bzoj 3680 吊打 XXX —— 模拟退火

    题目:https://www.luogu.org/problemnew/show/P1337 https://www.lydsy.com/JudgeOnline/problem.php?id=3680 ...

  3. bzoj 3680 吊打xxx 模拟退火

    第一道模拟退火 重心嘛,就是要找到一个点,使其到所有点距离*该点权值和最小 思路:初始化一个T,mint,当T大于mint时,每次随机一个解,如果解比当前解优,直接转移,否则,以某概率(与T正相关)转 ...

  4. BZOJ 3680: 吊打XXX (模拟退火)

    //yy:今天简单入门学了下ORZ 爬山算法:兔子朝着比现在高的地方跳去.它找到了不远处的最高山峰.但是这座山不一定是珠穆朗玛峰.这就是爬山算法,它不能保证局部最优值就是全局最优值. 模拟退火:兔子喝 ...

  5. BZOJ 3680: 吊打XXX【模拟退火算法裸题学习,爬山算法学习】

    3680: 吊打XXX Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 3192  Solved: 1198[Sub ...

  6. [BZOJ 3680] 吊打XXX 【模拟退火】

    题目链接:BZOJ - 3680 题目分析 这道题是SLYZ的神犇把JSOI的平衡点那道题改了一下题面变成了吊打GTY神犇..Orz 第一次写模拟退火,只能照着别人的代码写,我看的是PoPoQQQ神犇 ...

  7. BZOJ 3680 吊打XXX

    Description gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天台的一个洞 ...

  8. 3680: 吊打XXX

    3680: 吊打XXX 链接 思路: 模拟退火. 代码: 跑的特别慢... #include<cstdio> #include<algorithm> #include<c ...

  9. 【BZOJ3680】吊打xxx [模拟退火]

    吊打XXX Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description gty又虐了一场比赛,被虐的蒟蒻 ...

随机推荐

  1. Windows服务时间控件怎么调试

    写了timer,调试的话在构造函数里面把Elapsed方法写成null,null就可以调试了 public PSJCService() { InitializeComponent(); Getuser ...

  2. CSS 设置网页中选中文字的背景色

    在样式文件中增加如下代码: ::selection { background: hsla(5, 92%, 76%, 0.8); color: #fff;}

  3. bzoj千题计划281:bzoj4558: [JLoi2016]方

    http://www.lydsy.com/JudgeOnline/problem.php?id=4558 容斥原理 全部的正方形-至少有一个点被删掉的+至少有两个点被删掉的-至少有3个点被删掉的+至少 ...

  4. bzoj千题计划241:bzoj3864: Hero meet devil

    http://www.lydsy.com/JudgeOnline/problem.php?id=3864 题意: 给你一个DNA序列,求有多少个长度为m的DNA序列和给定序列的LCS为0,1,2... ...

  5. bzoj千题计划184:bzoj1261: [SCOI2006]zh_tree

    http://www.lydsy.com/JudgeOnline/problem.php?id=1261 dp[l][r][dep]  区间[l,r]内的节点,根在dep层的最小代价 枚举根i,dp[ ...

  6. 流媒体技术学习笔记之(八)海康、大华IpCamera RTSP地址和格式

    海康: rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream 说明: username: 用户名 ...

  7. Spring RedisTemplate操作-List操作(4)

    @Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...

  8. 给定一个整数,求解该整数最少能用多少个Fib数字相加得到

    一,问题描述 给定一个整数N,求解该整数最少能用多少个Fib数字相加得到 Fib数列,就是如: 1,1,2,3,5,8,13.... Fib数列,满足条件:Fib(n)=Fib(n-1)+Fib(n- ...

  9. [机器学习&数据挖掘]机器学习实战决策树plotTree函数完全解析

    在看机器学习实战时候,到第三章的对决策树画图的时候,有一段递归函数怎么都看不懂,因为以后想选这个方向为自己的职业导向,抱着精看的态度,对这本树进行地毯式扫描,所以就没跳过,一直卡了一天多,才差不多搞懂 ...

  10. 20155321 2016-2017-2 《Java程序设计》第五周学习总结

    20155321 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第八章 异常处理 Java提供特有的语句进行处理 try { 需要被检测的代码; } cat ...