这里使用二进制位表示城市集合,思路看书去吧
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <bitset>
using namespace std;
#define N 4//矩阵维度
#define MAX 0x7f7f7f7f
int distances[N][N] = {0};//距离
int path[N][1 << (N - 1)] = {0};//路径
int dp[N][1 << (N - 1)] = {0};//dp数组
void creatDistances();
void printDistances();
int removeCity(int j, int k)
{ // 从j二进制表示的城市集合中去除k号城市(k位设为0)
return j - (1 << (k - 1));
}
void printPath(int path[][1 << (N - 1)], int i, int j)
{ // 打印路线 i为出发城市编号 j为剩下城市组成的集合
if (j != 0)
{
cout << i << " -> ";
int next_city = path[i][j];
printPath(path, next_city, removeCity(j, next_city));
}
else
{
cout << i << " -> " << 0;
}
}
int TSP(int v, int s)
{
if (dp[v][s] != 0)
return dp[v][s];
int min = MAX;
for (int k = 1; k < N; k++)
{
if ((s >> (k - 1)) & 1)//如果城市k在集合里
{
// cout << "v:" << v << " s:" << bitset<N - 1>(s) << " k:" << k << endl;
int t = TSP(k, removeCity(s, k));//通过k到达集合的最短路径
if (t + distances[v][k] < min)
{
min = t + distances[v][k];
path[v][s] = k;
}
}
}
dp[v][s] = min;
return min;
}
int main()
{
// 课本例题
//int x[N][N] = {{MAX, 3, 6, 7},
// {5, MAX, 2, 3},
// {6, 4, MAX, 2},
// {3, 7, 5, MAX}};
// for (int i = 0; i < N; i++)
// for (int j = 0; j < N; j++)
// distances[i][j] = x[i][j];
// 随机初始化distances[N][N]
creatDistances();
// 初始化i->0的距离
for (int i = 0; i < N; i++)
dp[i][0] = distances[i][0];
// 输出结果
printDistances();
cout << "最短距离为:" << TSP(0, (1 << (N - 1)) - 1) << endl;
printPath(path, 0, (1 << (N - 1)) - 1);
system("pause");
return 0;
}
void creatDistances()
{
// 随机初始化distances[N][N]
srand((unsigned int)time(NULL));
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (i == j)
distances[i][j] = MAX;
else
{
int temp = rand() % 10;
while (temp == 0)
{
temp = rand();
}
distances[i][j] = temp % 10;
}
}
}
}
void printDistances()
{
cout << "代价矩阵为:" << endl;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (distances[i][j] == MAX)
cout << setw(5) << "INF"
<< " ";
else
cout << setw(5) << distances[i][j] << " ";
}
cout << endl;
}
}