模拟退火算法

这个https://www.cnblogs.com/tian-luo/p/9228570.html题目的模拟退火算法解法,mark一下写法。

#include<bits/stdc++.h>
#define N 25
using namespace std;
 
struct ss
{
    int path[N];
};
int dis[N][N],n;
 
int xiagao()
{
    srand(time(0));
    ss now;
     
    for(int i=1;i<=n;i++)now.path[i]=i;  
    random_shuffle(now.path+2,now.path+n);
 
    int ans=0;
    for(int i=1;i<n;i++)ans+=dis[now.path[i]][now.path[i+1]];
     
    double T=1,k=0.999,eps=1e-6;
     
    while(T>eps)
    {
        int l=rand()%(n-2)+2;
        int r=rand()%(n-2)+2;
        if(l>r)swap(l,r);
         
        int diss=dis[now.path[l-1]][now.path[r]]+dis[now.path[l]][now.path[r+1]]-(dis[now.path[l-1]][now.path[l]]+dis[now.path[r]][now.path[r+1]]);
         
        if(diss<0)
        {
            ans+=diss;
            int ls[N];
            for(int i=r;i>=l;i--)ls[i]=now.path[l+r-i];
            for(int i=l;i<=r;i++)now.path[i]=ls[i];
        }
        else
        {
            double ran=double(rand()%10000);
            ran/=9999.0;
             
            if(ran<exp((double)diss*-1.0/T))
            {
                ans+=diss;
                int ls[N];
                for(int i=r;i>=l;i--)ls[i]=now.path[l+r-i];
                for(int i=l;i<=r;i++)now.path[i]=ls[i];
            }
        }
         
        T=k*T;
         
    }
    return ans;
}
 
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)scanf("%d",&dis[i][j]);
     
    int upper=1000,ans=INT_MAX;
    while(upper--)
    {
        ans=min(ans,xiagao());
        //printf("%d
",ans);
    }
    printf("%d
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/tian-luo/p/10693736.html