[英]Dynamic approach to the TSP
我无法识别为什么此算法未返回TSP的最短路径。
vector<int> tsp(int n, vector< vector<float> >& cost)
{
long nsub = 1 << n;
vector< vector<float> > opt(nsub, vector<float>(n));
for (long s = 1; s < nsub; s += 2)
for (int i = 1; i < n; ++i) {
vector<int> subset;
for (int u = 0; u < n; ++u)
if (s & (1 << u))
subset.push_back(u);
if (subset.size() == 2)
opt[s][i] = cost[0][i];
else if (subset.size() > 2) {
float min_subpath = FLT_MAX;
long t = s & ~(1 << i);
for (vector<int>::iterator j = subset.begin(); j != subset.end(); ++j)
if (*j != i && opt[t][*j] + cost[*j][i] < min_subpath)
min_subpath = opt[t][*j] + cost[*j][i];
opt[s][i] = min_subpath;
}
}
vector<int> tour;
tour.push_back(0);
bool selected[n];
fill(selected, selected + n, false);
selected[0] = true;
long s = nsub - 1;
for (int i = 0; i < n - 1; ++i) {
int j = tour.back();
float min_subpath = FLT_MAX;
int best_k;
for (int k = 0; k < n; ++k)
if (!selected[k] && opt[s][k] + cost[k][j] < min_subpath) {
min_subpath = opt[s][k] + cost[k][j];
best_k = k;
}
tour.push_back(best_k);
selected[best_k] = true;
s -= 1 << best_k;
}
tour.push_back(0);
return tour;
}
例如,在仅5个点的距离cost
矩阵(图中的5个不同节点)上,该算法返回的路径不是最优路径。 在识别明显或小错误方面的任何帮助将不胜感激。 或有关问题的任何有用提示。
一件看起来很奇怪的事情是,即使我不属于s子集,main for循环也会执行操作。
换句话说,将opt [17] [8]设置为cost [0] [8]。 opt [17] [8]表示处于节点8并已访问节点0和4的状态(因为5 = 2 ^ 0 + 2 ^ 4)。
这应该被标记为不可能,因为如果我们在节点8上,那么我们肯定已经访问了节点8!
我建议通过更改来防止发生这些情况:
for (int i = 1; i < n; ++i) {
vector<int> subset;
至
for (int i = 1; i < n; ++i) {
vector<int> subset;
if ((s&(1<<i))==0) {
opt[s][i]=FLT_MAX;
continue;
}
嵌套循环for(j=
遍历subset
所有节点,包括起始节点 。这导致使用未初始化的值opt[t][0]
,因此导致错误的最佳路径长度计算。
最简单的解决方法是从subset
排除起始节点 :
for (int u = 1; u < n; ++u)
...
if (subset.size() == 1)
...
else if (subset.size() > 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.