<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">模拟退火解TSP</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="cpp">/* * @file SA.cpp * @brief SA解TSP * @author/Univ. taoxiaoxiao/XMU * @date 11-2-2014 */ #include <iostream> #include <fstream> #include <random> using namespace std; #define max 51 //最大的输入规格 int a[max][max]; //距离矩阵 int curPath[max], newPath[max], bestPath[max]; //当前解、新解、最优解 int length, bestLength = 0; //解的结果、最优解的结果 int n; //输入的节点数 int Lk= 2000; //Mapkob链长 double t = 100.0, alpha = 0.9; //温度、衰减速度 double rand1() { //产生0-1间随机数 static default_random_engine e; //引擎 static uniform_real_distribution<double> u(0, 1); //分布 return u(e); } int rand2(int n) { static default_random_engine e; //引擎 static uniform_int_distribution<int> u(1, n); //分布 return u(e); } inline void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } int getLength(int *p) { int len = 0; for (int i = 1; i <= n - 1; ++i) { len += a[p[i]][p[i + 1]]; } len += a[p[n]][p[1]]; return len; } /*2变换法产生新路径*/ int getNewPath() { //获得新路径,并求出新长度 int k, m; int newLen = 0; /* 2分交换 */ while (1) { k = rand2(n); m = rand2(n); if (k != m) break; } /* 新路径 */ swap(newPath[k], newPath[m]); newLen = getLength(newPath); return newLen; } void sa() { int i, count; int newLength, delta; int s = 0; int bChange = 0; /*初始化操作*/ for (i = 1; i<= n; i++) { bestPath[i]=newPath[i]=curPath[i] = i; } length = getLength(curPath); bestLength = length; /*按Metropolis接受准则进行迭代*/ while (1) { count = 0; //对每个温度tk产生Lk个解 Lk个解构成一个mapkob链 while (1) { newLength = getNewPath(); delta = newLength - length; if (delta <= 0 || (delta>0 && exp(-delta / t)>rand1())) { //是否接受新解 bChange = 1; for (i = 1; i <= n; i++) { curPath[i] = newPath[i]; } length = newLength; if (length < bestLength) { bestLength = length; for (i = 1; i <= n; i++) { bestPath[i] = curPath[i]; } } } if (++count >= Lk) break; }//1-while t = alpha * t; //降温 if (1==bChange) { s = 0; bChange = 0; } else { s++; } if (s == 2 || t <=1e-6) { //停止准则 //温度接近零或者有两次结果没变化时 break; } }//2-while } int main() { ifstream infile("file2.txt"); int i, j; if (infile.is_open()) cout << "open file successful." << endl; else { cout << "open file error." << endl; return 0; } while (!infile.eof()) { infile >> n; for (i = 1; i <= n; ++i) { for (j =1; j <= n; ++j) infile >> a[i][j]; } } infile.close(); sa(); for (i = 1; i <= n; ++i) cout << bestPath[i] << "->"; cout << bestPath[1] << endl; cout << bestLength << endl; system("pause"); return 0; }
file2.txt
运行结果
原文地址:http://blog.csdn.net/plu_mik/article/details/43159017