关于退火问题的一段C代码,求修改!
其中有些东西是我调试的时候用的!求大神帮忙修改修改!
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>#define Max_distance 9999999#define N 30double x[N]={0.37,0.75,0.45,0.76,0.71,0.07,0.42,0.59,0.32,0.60,0.30,0.67,0.62,0.67,0.20,0.35,0.27,0.94,0.82,0.37,0.61,0.42,0.60,0.39,0.53,0.40,0.63,0.50,0.98,0.68};double y[N]={0.91,0.87,0.85,0.75,0.72,0.74,0.71,0.69,0.64,0.64,0.59,0.59,0.55,0.55,0.50,0.45,0.43,0.42,0.38,0.27,0.26,0.25,0.23,0.19,0.19,0.13,0.08,0.04,0.02,0.85};double dis[N][N]={0};int path[N];void test(){ int i,j; printf("\n\n"); for(i=0;i<N;i++) printf("%d ",path[i]);/* for(i=0;i<N;i++) { for(j=0;j<N;j++) { printf("%d ",dis[i][j]); if(j+1%6==0) printf("\n"); } printf("\n");printf("\n");printf("\n");printf("\n"); }*/ printf("\n\n");}//计算距离void count_distance(){ int i,j; for(i=0;i<N;i++) { for(j=0;j<N;j++) { dis[i][j]=sqrt(pow((x[i]-x[j]),2)+pow((y[i]-y[j]),2)); printf("%f ",dis[i][j]); if(j+1%6==0) printf("\n"); } printf("\n");printf("\n");printf("\n"); }}//初始化一条路void init_path(){ int i; for(i=0;i<N;i++) { path[i]=i; printf("%d ",path[i]); }}//计算路程double count_lucheng(int a,int b){ double s=0; int i; if(a<0) a=0; if(b>=N-1) b=N-1; for(i=a;i<b;i++) { s+=dis[path[i]][path[i+1]]; } return s;}//退火算法double tuihuo(){ init_path(); //退火条件 test(); double T=1; double at=0.999,df; double e=pow(0.1,30); int L=20000; //开始退火 srand(time(0)); //计算初始路程 double sum=count_lucheng(0,N-1); int i=0;int a,b; while(i<L) { a=rand()%30; b=rand()%30; df=dis[a-1][b]+dis[a][b+1]-dis[a-1][a]-dis[b][b+1]; double d=exp(-df/T); int c=rand(); if(df<0||(df>=0&&(d>c)))//接受新路径 { int newpath[N]; int j; int mm=(a>b? a:b); int nn=(a<b? a:b); int k=nn; for(j=nn;j<=mm;j++) { newpath[j]=path[j]; } for(j=mm;j>=nn;j--) { path[k]=newpath[j]; k=k+1; } sum+=df; } T=T*at; if(T<e) break; i++; test(); printf("%f ",sum); float newdis=count_lucheng(0,N-1); printf("%f ",newdis); } return sum;}void main(){ count_distance(); double www=tuihuo(); //test(); int i; for(i=0;i<N;i++) { printf("%d ",path[i]); } printf("%f\n",www);} while(i<L) { a=rand()%30; b=rand()%30; df=dis[a-1][b]+dis[a][b+1]-dis[a-1][a]-dis[b][b+1]; double d=exp(-df/T); int c=rand(); if(df<0||(df>=0&&(d>c)))//接受新路径//这里df《0 sum后面就会变小咯 { int newpath[N]; int j; int mm=(a>b? a:b); int nn=(a<b? a:b); int k=nn; for(j=nn;j<=mm;j++) { newpath[j]=path[j]; } for(j=mm;j>=nn;j--) { path[k]=newpath[j]; k=k+1; } sum+=df; }
[解决办法]
a=rand()%30;
b=rand()%30;
df=dis[a-1][b]+dis[a][b+1]-dis[a-1][a]-dis[b][b+1];
当a为0时,dis[a-1][b]和dis[a-1][a]越界。当b为29时,dis[a][b+1]和dis[b][b+1]越界。