仅访问选定城市的最低成本并重新开始?

时间:2013-08-07 06:17:25

标签: c++ brute-force traveling-salesman

我理解旅行商的问题。假设我只想访问选定的城市并重新开始,那该怎么做?

让我们说我的成本矩阵是,

  A B C D
A 0 1 2 1
B 1 0 1 2
C 2 1 0 1
D 1 2 1 0

如果我想访问所有城市并返回A.我的最短路径为A->B->C->D,最小距离为4

假设我说如果我只想访问B和D.我怎样才能找到最小距离?

这是修改过的旅行商问题吗?在这种情况下,有人可以帮我做蛮力算法吗?

2 个答案:

答案 0 :(得分:1)

您可以先运行Floyd-Warshall来计算所有节点对之间的最短路径。见wikipedia article。 一旦你有了精简成本矩阵,就可以消除你不感兴趣的所有城市。从那里,它就是标准的旅行推销员。

由于旅行推销员是NP完成的,因此在您之前运行Floyd-Warshall的复杂性无关紧要。

如果你想要完整的方向(包括通过不感兴趣的城市的弯路使路径缩短,你将不得不回到Floyd-Warshall并重建路径。

答案 1 :(得分:0)

我没有方便的代码,但是这里有一些建议和伪代码可以帮助您: 我会通过在内存中存储矢量以及上面的距离矩阵来解决这个问题。类似的东西:

struct Location{
bool visited;
bool mustVisit;
}

Vector<Location> locationVec;

使用问题中的位置填充向量,标记是否必须访问它们,并始终将visited设置为false。然后是有趣的部分!您需要创建locationVec的排列。我会以递归方式执行此操作,例如:

void addLocation(int & curLength, int & maxLength, int & curDistance, Vector<Location> &locationVec, Location* lastVisited)
if(curLenth == maxLength){
//check if currentDistance is less than the previously generated best difference, if so
//replace it
lastVisited->visited=0;
return;
}

//Add the next location
for (int& i : locationVec){
//Check if the location has been visited, and if it must be visited.
//If so: mark as visited, point lastVisited to it, and break
//Also add from lastVisited to the new location to your curDistance
curLength++;
}

addLocation(curLength, maxLength, curDistance, locationVec, lastVisited);
return;
}

这应该让你开始。当你将访问次数从visited = 1更改为visited = 0时,请记住从currentDist中减去,因为你实际上是“取消访问”城市。您可能需要跟踪lastlastvisited,具体取决于您的具体实施。

如果你需要加快速度(而且你可能会,旅行推销员很慢),请查看分支和界限:http://en.wikipedia.org/wiki/Branch_and_bound