总的来说只需要知道它是一种启发式搜索算法,并且能以很大概率获得全局最优解。
我们来简单说一下这个算法:在铁匠打铁时,需要将铁加热至高温,将铁水加至容器后,降温至室温,铁原子便会排列有序,形成一个铁具。降温的过程叫做退火过程,这个物理过程 中能量是从功能量变为低能量的。
而科学家们发现,若在当前温度T下,能量为E(0),在降温单位时间后,能量 E ( 1 ) E(1) E(1)并不一定比 E ( 0 ) E(0) E(0)小, E ( 1 ) = x E(1)=x E(1)=x这种情况能被接受的概率取决于:
满足以下公式:
\begin{cases}
x
\end{cases}
看不懂没关系,只需要知道以下结论:
看了上面关于模型的介绍,你可能还不懂这个算法到达有什么用。我们来简单阐述一下它的应用。当求非线性规划问题的全局最小值时,我们可以使用模拟退火算法进行求解。求解的过程为以下四步:
则最终到达的点有一定概率在最优解附近,再通过贪心的方法即可找到全局最优解。所以这是一个随机算法。
题目来源:BZOJ 3680
gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty。gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了。蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天台的一个洞。这n根绳子有一个公共的绳结x。吊好gty后蒟蒻们发现由于每个gty重力不同,绳结x在移动。蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标,由于他太弱了决定向你求助。
不计摩擦,不计能量损失,由于gty足够矮所以不会掉到地上。
输入第一行为一个正整数n(1<=n<=10000),表示gty的数目。
接下来n行,每行三个整数xi,yi,wi,表示第i个gty的横坐标,纵坐标和重力。
对于20%的数据,gty排列成一条直线。
对于50%的数据,1<=n<=1000。
对于100%的数据,1<=n<=10000,-100000<=xi,yi<=100000
输出1行两个浮点数(保留到小数点后3位),表示最终x的横、纵坐标。
3
0 0 1
0 2 1
1 1 1
0.577 1.000
本题用到了数学知识:广义费马点。
简单的说一下道理:因为重物悬挂的位置有尽可能下降的趋势,所以最终稳定的点应为重力势能和的最小点,同时由于绳子长度一定,则重力势能最小对应下拉绳子长度最长,对应剩余绳长最短,即求到所有点的加权距离和最短的点,其中权值为重力。即求广义费马点。
#include
using namespace std;
const int maxn = 1e4+5;
int n;
double x[maxn],y[maxn],w[maxn];
double xs=0,ys=0,dis;
double pow2(double x){return x*x;}
double d(double x1,double y1,double x2,double y2){
return sqrt(pow2(x1-x2)+pow2(y1-y2));
}
double calc(double nx,double ny){
double res=0;
for(int i=0;i0.001){
nextx=nowx+T*(Rand()*2-1);
nexty=nowy+T*(Rand()*2-1);
dE=calc(nowx,nowy)-calc(nextx,nexty);
if(dE>0 || exp(dE/T)>Rand())
nowx=nextx,nowy=nexty;
T*=0.97;
}
//在结束退火后找到极小值点
for(int i=0;i<1000;i++){
nextx=xs+T*(Rand()*2-1);
nexty=ys+T*(Rand()*2-1);
calc(nextx,nexty);
}
}
int main(){
srand(1594894);
scanf("%d",&n);
for(int i=0;i
费马点:http://www.matrix67.com/blog/archives/422?replytocom=922225#respond
模拟退火算法:https://zhuanlan.zhihu.com/p/21277465