模拟退火
模拟退火
基本思路(Main Thoughts):
模拟退火是一种比爬山算法更加优(乱)秀(搞)的贪心法
它基于爬山算法点的有点就是可以下降 不过越后几率越低,这样就能找到更高的山峰.
形象的比喻如下:
爬山算法:兔子爬最高的山峰.
模拟退火:兔子喝醉了,乱爬,在爬的过程中逐渐清醒,最后爬到高峰.
实现步骤(Implementation Steps):
- 设定初始温度 温度最小值 起始位置,转移法
- 随机转移 然后判断该步后的决策与之前决策的优劣
a) 优 直接取代
b) 劣 则以一定概率移动 不过这个概率还会慢慢减少
3.至于那个一定概率 大概就是用现在与原来的差值用log(差的绝对值/温度)或者exp(差的绝对值的相反数/温度)函数与一个rand 的值比较.
4.概率慢慢减少就是温度慢慢下降
模板(Code):
//by 苍梧
时间&空间复杂度(Time & Memory Complexity):
空间:O(?)
时间:O(?)
主要用途&优缺点(Main Applications & Advantages & Disadvantages):
主要用途:乱搞
优点:比爬山算法更靠谱?
缺点:有时比爬山算法还不靠谱?
推荐题目&数据(Recommendatory Problems & Data) :
POJ 2420 做一道感受一下气氛吧。。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<ctime> 6 7 using namespace std; 8 9 #define maxn 101 10 11 #define eps 1e-4 12 13 int n; 14 15 struct poi{ 16 int x,y; 17 }p[maxn]; 18 19 double sqr(double x){return x*x;} 20 21 double dis(double X,double Y,poi P){return sqrt(sqr(X-P.x)+sqr(Y-P.y));} 22 23 double sumdis(double xx,double yy) 24 { 25 double sum=0; 26 for(int i=1;i<=n;i++) 27 sum+=dis(xx,yy,p[i]); 28 return sum; 29 } 30 31 int main() 32 { 33 freopen("t.in","r",stdin); 34 while(scanf("%d",&n)!=EOF) 35 { 36 srand(n); 37 double xx=0,yy=0; 38 for(int i=1;i<=n;i++) 39 scanf("%d%d",&p[i].x,&p[i].y),xx+=p[i].x,yy+=p[i].y; 40 xx/=n,yy/=n; 41 double T=100000,ANS=sumdis(xx,yy); 42 while(T>0.02) 43 { 44 double sum=0,x,y,t=(rand()%10000)/10000.0; 45 for(int i=-1;i<=1;i++) 46 for(int j=-1;j<=1;j++) 47 { 48 x=xx+T*i; 49 y=yy+T*j; 50 double D=sumdis(x,y); 51 if(D+eps<ANS)ANS=D,xx=x,yy=y; 52 else if(log((D-ANS)/T)>t+eps)ANS=D,xx=x,yy=y; 53 54 } 55 T*=t; 56 } 57 printf("%.0lf\n",ANS); 58 } 59 return 0; 60 }
貌似还和计算几何有关?以后再看吧。。