《灵珠觉醒:从零到算法金仙的C++修炼》卷十·混元大罗(91)混元无极破 NP - 旅行商问题(动态规划 + 状态压缩)
《灵珠觉醒:从零到算法金仙的C++修炼》卷十·混元大罗(91)混元无极破 NP - 旅行商问题(动态规划 + 状态压缩)
哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的混元大罗天,天际间弥漫着 NP 问题的挑战,代表着组合优化的极限。天的入口处有一块巨大的石碑,上面刻着一行文字:“欲破此天,需以混元之力,破 NP,旅行商问题显真身。”
哪吒定睛一看,石碑上还有一行小字:“当城市距离矩阵为:
0 2 9 10
1 0 6 4
15 7 0 8
6 3 12 0
时,旅行商的最短路径为1 -> 3 -> 2 -> 4
,总距离为2 + 4 + 7 + 3 = 16
。”哪吒心中一动,他知道这是一道关于旅行商问题的难题,需要通过动态规划和状态压缩来解决。
暴力解法:混元大罗天的初次尝试
哪吒心想:“要解决旅行商问题,我可以尝试枚举所有可能的路径,计算每条路径的总距离,然后找到最短的那条。”他催动混元之力,通过递归生成所有可能的排列,计算每条路径的总距离。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int tsp(vector<vector<int>>& dist, vector<bool>& visited, int current, int n) {
if (all_of(visited.begin(), visited.end(), [](bool v) {
return v; })) {
return dist[current][0];
}
int minDist = INT_MAX;
for (int i = 1; i < n; ++i) {
if (!visited[i]) {
visited[i] = true;
int temp = tsp(dist, visited, i, n) + dist[current][i];
if (temp < minDist) {
minDist = temp;
}
visited[i] = false;
}
}
return minDist;
}
int main() {
vector<vector<int>> dist = {
{
0, 2, 9, 10},
{
1, 0, 6, 4},
{
15, 7, 0, 8},
{
6, 3, 12, 0}
};
int n = dist.size();
vector<