JSOI2004 平衡点 / 吊打XXX [模拟退火]
题目描述
如图:有n个重物,每个重物系在一条足够长的绳子上。每条绳子自上而下穿过桌面上的洞,然后系在一起。图中X处就是公共的绳结。假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地上),且忽略所有的摩擦。
问绳结X最终平衡于何处。
注意:桌面上的洞都比绳结X小得多,所以即使某个重物特别重,绳结X也不可能穿过桌面上的洞掉下来,最多是卡在某个洞口处。

输入输出格式
输入格式:
文件的第一行为一个正整数n(1≤n≤1000),表示重物和洞的数目。接下来的n行,每行是3个整数:Xi.Yi.Wi,分别表示第i个洞的坐标以及第 i个重物的重量。(-10000≤x,y≤10000, 0<w≤1000 )
输出格式:
你的程序必须输出两个浮点数(保留小数点后三位),分别表示处于最终平衡状态时绳结X的横坐标和纵坐标。两个数以一个空格隔开。
输入输出样例
输入样例#1:
3
0 0 1
0 2 1
1 1 1
输出样例#1:
0.577 1.000
说明
[JSOI]
题解
- 早就想打一道模拟退火的题,但由于种种原因迟迟没有打
 - 今天由于机缘巧合巨佬讲题,有幸A掉这道模拟退火的模板题
 先来了解一下物理上的退火
模拟退火的出发点是基于物理中固体物质的退火过程与一般组合优化问题之间的相似性。模拟退火算法是一种通用的优化算法,其物理退火过程由加温过程、等温过程、冷却过程这三部分组成。
原理
模拟退火的原理也和金属退火的原理近似:将热力学的理论套用到统计学上,将搜寻空间内每一点想像成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。演算法先以搜寻空间内一个任意点作起始:每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。
- 其实这些都是废话,在OI中要注意的其实只有三点
模拟退火算法的应用很广泛,可以求解NP完全问题 
 (1) 温度T的初始值设置问题
温度T的初始值设置是影响模拟退火算法全局搜索性能的重要因素之一、初始温度高,则搜索到全局最优解的可能性大,但因此要花费大量的计算时间;	反之,则可节约计算时间,但全局搜索性能可能受到影响。实际应用过程中,初始温度一般需要依据实验结果进行若干次调整。
(2) 退火速度问题。
模拟退火算法的全局搜索性能也与退火速度密切相关。一般来说,同一温度下的“充分”搜索(退火)是相当必要的,但这需要计算时间。实际应用中,要针对具体问题的性质和特征设置合理的退火平衡条件。
(3) 温度管理问题。
温度管理问题也是模拟退火算法难以处理的问题之一。实际应用中,由于必须考虑计算复杂度的切实可行性等问题,常采用如下所示的降温方式:
式中k为正的略小于1.00的常数,t为降温的次数。
- 总的来说就是模拟退火算法就是需要我们以一定几率接受次优解,从而跳出局部最优达到整体最优的算法,但因为是随机,所以我们可以多跑几遍,在时间允许的范围内尽量找到正解
 
Code
#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
const double delta=0.9969;//降温系数
int read() {
    int ans=0,f=1; char i=getchar();
    while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
    while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
    return ans*f;
}
int n;
double ansx,ansy,E=1e18+10,t;//E是能量,t为初始温度
struct node {
    int x,y,w;
}a[1010];
double get(double x,double y) {
    double sum=0;
    for(int i=1;i<=n;i++) {
        double dx=x-a[i].x,dy=y-a[i].y;
        sum+=sqrt(dx*dx+dy*dy)*a[i].w;
        //计算势能,势能又与重物质量成正比
        //根据物理知识,重物平衡时总能量最小,而此时物体动能为0,则重力势能最小时系统平衡
    }
    return sum;
}
void work() {
    t=1024.0;//曾经沧海难为水,除却巫山不是云
    double mx=ansx,my=ansy;
    while(t>1e-15) {
        double xx=mx+(rand()*2-RAND_MAX)*t;//得到的答案就是(-RAND_MAX,RAND_MAX),从负到正,可以多方向扩展
        double yy=my+(rand()*2-RAND_MAX)*t;
        double newans=get(xx,yy);//统计当前势能
        double DE=newans-E;
        if(DE<0) {//如果当前解更优就更新答案
            ansx=xx; ansy=yy;
            mx=xx; my=yy;
            E=newans;
        }
        else if(exp(-DE/t)*RAND_MAX>rand()) {//否则我们就以一定几率来接受这个次优解,其中exp为以自然对数为底的对数函数
            mx=xx; my=yy;
        }
        t*=delta;//降温
    }
}
int main()
{
    srand(time(0));
    in(n);
    for(int i=1;i<=n;i++) {
        in(a[i].x); in(a[i].y); in(a[i].w);
        ansx+=a[i].x; ansy+=a[i].y;
    }
    ansx/=n*1.0; ansy/=n*1.0;
    for(int i=1;i<=4;i++) work();
    printf("%.3lf %.3lf\n",ansx,ansy);
    return 0;
}
博主蒟蒻,随意转载.但必须附上原文链接
http://www.cnblogs.com/real-l/
JSOI2004 平衡点 / 吊打XXX [模拟退火]的更多相关文章
- luogu1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
		
推荐博客:模拟退火总结(模拟退火)by FlashHu.模拟退火的原理,差不多就是不断地由现有的值不断地试探,不断地转到更优的值,并在一定概率下转到较差的值. 题目传送门:luogu1337 [JSO ...
 - 洛谷P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
		
题目描述 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到 ...
 - LG1337 [JSOI2004]平衡点 / 吊打XXX  模拟退火
		
问题描述 LG1337 题解 模拟退火模板 记住概率公式: \(exp(\frac{dealt}{T}) \times rand \ge R_A^ND^M_AX\) zzk太欧了,我交了一版没过他来了 ...
 - LUOGU P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
		
传送门 解题思路 学习了一下玄学算法--模拟退火,首先要求平衡处,也就是求势能最小的地方,就是求这个点到所有点的距离*重量最小.剩下的几乎是模拟退火的板子了. #include<iostream ...
 - P1337 [JSOI2004]平衡点 / 吊打XXX 模拟退火
		
链接 https://www.luogu.org/problemnew/show/P1337 思路 交了好多发,都是wrong 初始值取平均数就1A了 真的是玄学的算法 代码 // luogu-jud ...
 - 洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 解题报告
		
P1337 [JSOI2004]平衡点 / 吊打XXX 题目描述 有 \(n\) 个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.\(X\)处就是公共的绳结.假设 ...
 - 洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX
		
洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 点击进入FakeHu的模拟退火博客 神仙模拟退火...去看fakehu的博客吧...懒得写了... 因为精度问题要在求得的最优解附近(大约 ...
 - [luogu1337][bzoj3680][JSOI2004]平衡点 / 吊打XXX【模拟退火】
		
题目描述 gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天台的一个洞.这n根绳子有 ...
 - 洛谷P1337 【[JSOI2004]平衡点 / 吊打XXX】(模拟退火)
		
洛谷题目传送门 很可惜,充满Mo力的Mo拟退火并不是正解.不过这是一道最适合开始入手Mo拟退火的好题. 对模拟退火还不是很清楚的可以看一下 这道题还真和能量有点关系.达到平衡稳态的时候,物体的总能量应 ...
 
随机推荐
- BGP(边界网关协议)简述
			
BGP的起源 不同自治系统(路由域)间路由交换与管理的需求推动了EGP的发展,但是EGP的算法简单,无法选路,从而被BGP取代. 自治系统:(AS) IGP:自治系统内部协议,ospf,rip,is- ...
 - gp更新来的太快
			
意外总是会发生 添加一个判断function的分支,过滤掉function,其实也考虑再进一步去分析它的作用,稍后再议. 更新一下 var gnp = { get: function(url) { r ...
 - 关于==和equals()方法&Java中string与char如何转换&String,StringBuffer
			
1.对于基本数据类型,可以直接使用==和!=进行内容比较 如:int x=30; int y=30; x==y; //true 基本数据类型 简单类型(基本类型) bo ...
 - Android: Requesting root access in your app
			
package com.certusnet.videomonitor; import java.util.List; import java.io.IOException; import java.i ...
 - NoSQL简单学习(一)
			
只是简单的知道有这个东西,却从来没有去接触,今天看了几篇文章,记录一下,开始慢慢接触这一领域 简介: 8种Nosql数据库系统对比 http://blog.jobbole.com/1344/ 一网打尽 ...
 - 『Golang』MongoDB在Golang中的使用(mgo包)
			
有关在Golang中使用mho进行MongoDB操作的最简单的例子.
 - 「暑期训练」「Brute Force」 Bitonix' Patrol (CFR134D1D)
			
题意 有n" role="presentation">nn个站点,排成圆形,每站间距m" role="presentation"> ...
 - 在Kotlin上怎样用Mockito2 mock final 类(KAD 23)
			
作者:Antonio Leiva 时间:Mar 2, 2017 原文链接:https://antonioleiva.com/mockito-2-kotlin/ 如我们在前面文章中谈到的,Kotlin最 ...
 - linux学习总结---web前端③
			
css3: border-radius opacity: transform: 旋转 rotate 平移translate 缩放scale 扭曲skew transition:转变 强调:开始和结束 ...
 - Java进阶知识点1:白捡的扩展性 - 枚举值也是对象
			
一.背景 枚举经常被大家用来储存一组有限个数的候选常量.比如下面定义了一组常见数据库类型: public enum DatabaseType { MYSQL, ORACLE, SQLSERVER } ...