参数太难调了,很多情况下效果都不好, 完整程序下载 /*simulated annealing algorithm for TSP * @author: onezeros@yahoo.cn */ #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <stdlib.h> #include <time.h> #include <assert.h> #include <math.h> using namespace std; //calculate length of a path double calc_path_len(vector<int> path,vector<vector<double> >& distance) { double dis=0; for (int i=0;i<path.size()-1;i++){ dis+=distance[path[i]][path[i+1]]; } dis+=distance[path[path.size()-1]][path[0]]; return dis; } //generate a integer sequence from 0 to n-1 at random void rand_int_order(vector<int>& randorder,const int n) { assert(n>1); randorder.clear(); randorder.resize(n); vector<int> recoder; for (int i=0;i<n;i++){ recoder.push_back(i); } for(int i=0;i<n;i++){ int sel=rand()%recoder.size(); randorder[i]=recoder[sel]; recoder.erase(recoder.begin()+sel); } assert(randorder.size()==n); } int main() { srand((unsigned)time(NULL)); //read data from file fstream filein("data/berlin52.tsp.processed",ios::in); if (filein==NULL){ cout<<"cannot open data file"<<endl; return 1; } fstream fileout("data/result.txt",ios::out); if (fileout==NULL){ cout<<"cannot open a file to write data"<<endl; return 1; } //append the best result found in this test to a file named "best.txt" fstream bestout("data/best.txt",ios::app); if (bestout==NULL){ cout<<"cannot open a file to write data"<<endl; return 1; } //number of cities unsigned int cityNum; filein>>cityNum; cout<<cityNum<<endl; //standard path int* standardPath; standardPath=new int[cityNum]; for (int i=0;i<cityNum;i++){ filein>>standardPath[i]; } //distance between cities vector<vector<double> > distance; for (int i=0;i<cityNum;i++){ vector<double> v; for (int j=0;j<cityNum;j++){ double d; filein>>d; v.push_back(d); } distance.push_back(v); } ////////////////////////////////////////////////////////////////////////// //parameters //initial temperature double T_start; //final temperature double T_final=1; //time of circulation at a certain temperature int L=10000; //ratio of temperature reduction double alpha=0.95; //initial path vector<int> path; //initialization rand_int_order(path,cityNum); //length of best path found double best_path_len=1<<(8*sizeof(int)-2); //initialize T-start=K*disDelta;K(10,20,100... ),disDelta=max(distance)-min(distance). double max_dist=0; double min_dist=best_path_len; for (int i=0;i<cityNum;i++){ for (int j=0;j<cityNum&&i>j;j++){ if (max_dist<distance[i][j]){ max_dist=distance[i][j]; } if (min_dist>distance[i][j]){ min_dist=distance[i][j]; } } } for (int temperature=1;temperature<2;temperature++){//test initial temperature //assign initial temperature T_start=(max_dist-min_dist)*temperature*50; double T=T_start; //annealing while(T>T_final){ for(int l=0;l<L;l++){ int point_former=rand()%(cityNum-2); int point_latter=point_former; while(point_former==point_latter){ point_latter=rand()%(cityNum-1); } //make sure point_former is smaller than point_latter if (point_former>point_latter){ int t=point_latter; point_latter=point_former; point_former=t; } ////new path vector<int> newPath=path; //2-opt //reverse(newPath.begin()+point_former,newPath.begin()+point_latter); //3-opt int point_c=point_latter; while(point_c<=point_latter){ point_c=rand()%cityNum; } vector<int>tmp(newPath.begin()+point_former,newPath.begin()+point_latter); newPath.insert(newPath.begin()+point_c,tmp.begin(),tmp.end()); newPath.erase(newPath.begin()+point_former,newPath.begin()+point_latter); double newLen=calc_path_len(newPath,distance); double delta_dist=newLen-best_path_len; //acceptance criteria if (delta_dist<0||exp(-delta_dist/T)>rand()/RAND_MAX){ best_path_len=newLen; fileout<<"best distance found for the moment: " <<best_path_len<<endl <<"path found for the moment:"<<endl; for (int i=0;i<cityNum;i++){ fileout<<path[i]<<" "; } fileout<<endl; //to console cout<<"best distance found for the moment: " <<best_path_len<<endl <<"best path found for the moment:"<<endl; for (int i=0;i<cityNum;i++){ cout<<path[i]<<" "; } cout<<endl; //jump out cycle of this temperature break; } } //reduce temperature T*=alpha; } bestout<<"current temperature: "<<10*temperature*(max_dist-min_dist)<<endl; bestout<<best_path_len<<endl; for (int i=0;i<cityNum;i++){ bestout<<path[i]<<" "; } bestout<<endl; //record time time_t currenttime; time(¤ttime); bestout<<ctime(¤ttime); } //show standard path and distance fileout<<"standard path:"<<endl; double standardbestlen=0; for (int i=0;i<cityNum;i++){ fileout<<standardPath[i]<<" "; } for (int i=0;i<cityNum-1;i++){ standardbestlen+=distance[standardPath[i]][standardPath[i+1]]; } standardbestlen+=distance[standardPath[cityNum-1]][standardPath[0]]; fileout<<endl<<"length of standard path: "<<endl<<" "<<standardbestlen<<endl; //free memory///////////////////////////////////////////////////////////// filein.close(); fileout.close(); bestout.close(); delete[] standardPath; return 0; }