Random annealing algorithm

Posted by amax on Tue, 30 Jul 2019 23:54:18 +0200

Mountain climbing algorithm

A search algorithm is considered to be the optimal solution when there is no higher state around it. In fact, it is an estimate of height, and there is a probability that the optimal result can not be found.

Random annealing algorithm

It is an improved optimization of mountain climbing algorithm. Specific optimization is that even if there is no higher point around it, there is also a certain probability that it will move to a lower point, and such a probability will decrease over time.
According to the principle of thermodynamics, when the temperature is T, the probability of cooling with energy difference of dE is P(dE), which is expressed as:
		P(dE) = exp( dE/(kT) ) 
As the program runs, the probability of acceptance actually gets lower and lower.
E=Val(ans); // Val is the valuation function
while( T>T_min ){
	nE= Val( now );
	dE=nE-E; //dE is delta E 
	if(dE>0||eps(dE/T)>random(1,0)){  
		ans=next;
		E=nE; //"Energy" to Change Current Status 
	}
	T=T*r;  // The bigger 0 < R < 1 r, the more likely it is to find the optimal solution. 

A topic

POJ-1379

//#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
#include <time.h>
#include <iomanip>

#define FOR(i,a,b) for(register int i=a;i<=b;i++)
#define LL long long
#define db double
#define Maxn 10000

using namespace std;

inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

const db PI=acos(-1.0);
const int inf=0x7FFFFFFF;
int n;

struct Node{
	db x,y;
	Node(){ x=0; y=0; }
	Node(db a,db b){ x=a; y=b; }
}dot[Maxn+10];
db dis(Node a,Node b){ return sqrt( (db)(a.x-b.x)*(a.x-b.x)+(db)(a.y-b.y)*(a.y-b.y) ); }
db minDis(Node now){
	double ans=1e80;
	FOR(i,1,n) ans=min(ans,dis(now,dot[i]));
	return ans;
}
double random(){
	return rand()%10000/10000.0;
}
int X,Y;
Node Deal(){
	db T_min=1e-8; db T=sqrt( X*X+Y*Y )/2.0;
	Node Ans=Node(X/2.0,Y/2.0);
	db E=minDis(Ans); int count=30;
	while( T>T_min ){
		Node next;
		db nE=0.0;
		FOR(i,1,count){
			Node now;
			db angle=random()*2*PI;
			now=Node( Ans.x+T*cos(angle), Ans.y+T*sin(angle) );
			if(now.x>X) now.x=X; if(now.x<0.0) now.x=0.0;
			if(now.y>Y) now.y=Y; if(now.y<0.0) now.y=0.0;
			db tE=minDis(now);
			if(tE>nE) nE=tE, next=now;
		}
		db dE=nE-E;
		if(dE>=0.0|| exp(dE/T)>random() )
			E=nE, Ans=next;
		T=T*0.8;
	}
	return Ans;
}

int main(){
	
	srand((unsigned)time(0));
	//db l; while(1) if((l=random())>0.4) cout<<l<<endl;
	
	int T=read();
	FOR(i,1,T){
		
		X=read(), Y=read(), n=read();
		FOR(i,1,n) cin>>dot[i].x>>dot[i].y;
		Node Ans=Deal();
		//cout<<" A "<<Ans.x<<" "<<Ans.y<<endl;
		printf("The safest point is (%.1lf, %.1lf).\n",Ans.x,Ans.y);
	}

	return 0;
}