Graph 从线性规划解中提取顶点路径
我一直在尝试解决一个路由问题,比如Graph 从线性规划解中提取顶点路径,graph,routing,linear-programming,traveling-salesman,Graph,Routing,Linear Programming,Traveling Salesman,我一直在尝试解决一个路由问题,比如TSP(旅行推销员问题),但有些曲折。我使用线性规划(CPlex库)和有向图(带原点顶点)(Coin或::Lemon库)对问题进行了建模 线性规划找到了解决方案,但我的问题在于如何检索路径。 我可以迭代图的每个顶点和边,找出线性程序使用的是哪个,所以我想我应该从原点开始,使用选择的边到达下一个节点,直到我再次到达原点 问题是CPlex路径可能会多次穿过任何顶点。所以我决定使用递归算法。但我不太明白。以下是我尝试过的: FindPath ( node N, pat
TSP
(旅行推销员问题),但有些曲折。我使用线性规划(CPlex库
)和有向图(带原点顶点)(Coin或::Lemon库
)对问题进行了建模
线性规划找到了解决方案,但我的问题在于如何检索路径。
我可以迭代图的每个顶点和边,找出线性程序使用的是哪个,所以我想我应该从原点开始,使用选择的边到达下一个节点,直到我再次到达原点
问题是CPlex路径可能会多次穿过任何顶点。所以我决定使用递归算法。但我不太明白。以下是我尝试过的:
FindPath ( node N, path P)
AddedAnyPath <- false
for each edge E out of N that hasn't been used yet
T is the target of E
add T to P
if findPath ( E, P )
AddedAnyPath = true
end for each
if AddedAnyPath
if all edges were used
return true
else
return false
end if
endif
end
TSP(路径)的解决方案是顶点的有序列表,从原点开始和结束,访问每个顶点。有两种可能的情况
如果您允许一个顶点访问两次,那么在您的变体中,您允许“子巡更”。(案例2)
变量X\u nt为1。(连接节点n和节点t的边变量)
如果没有子顺序:情况1,则可以在返回到原点节点后停止
看起来您允许子巡更(多个循环,上面的案例2)。如果是,则必须访问作为TSP解决方案一部分的所有边,其值为1。(修改代码以跟随每个节点到其终端节点的任意一条边,每次一条边。)
希望有帮助。TSP(路径)的解决方案是一个有序的顶点列表,从原点开始和结束,访问每个顶点。有两种可能的情况
如果您允许一个顶点访问两次,那么在您的变体中,您允许“子巡更”。(案例2)
变量X\u nt为1。(连接节点n和节点t的边变量)
如果没有子顺序:情况1,则可以在返回到原点节点后停止
看起来您允许子巡更(多个循环,上面的案例2)。如果是,则必须访问作为TSP解决方案一部分的所有边,其值为1。(修改代码以跟随每个节点到其终端节点的任意一条边,每次一条边。)
希望能有所帮助。谢谢您的回答。我现在就试试你说的,我会给你回复的,它成功了!非常感谢。我正在根据你的建议用正确的代码编辑我的问题谢谢你的回答。我现在就试试你说的,我会给你回复的,它成功了!非常感谢。我正在根据你的建议用正确的代码编辑我的问题
bool findPath2 ( Store_Instance &T, DiNode ¤t, list <DiNode> &path, ListDigraph::ArcMap<bool> &usedArcs, IloCplex &cplex, ListDigraph::ArcMap<IloNumVar> &x) {
DiNode currentNode = current;
bool success = false;
int positionToInsert = 1;
while (true) {
//Find an unvisited edge E whose value is 1.
Arc unvisitedArc = INVALID;
for(Digraph::OutArcIt a(T.g, currentNode); a != INVALID; ++a) {
if(cplex.getValue(x[a]) >= 1-EPS && !usedArcs[a]) {
unvisitedArc = a;
break;
}
}
if (unvisitedArc != INVALID) {
//Mark edge as visited
usedArcs[unvisitedArc] = true;
//Get the target T of the edge
DiNode target = T.g.target(unvisitedArc);
//Add Edge E to the path
list<DiNode>::iterator iterator = path.begin();
advance(iterator, positionToInsert);
path.insert(iterator, target);
//Increase the iterator
positionToInsert++;
//If all the edges whose value is 1 are visited, stop
bool usedAllEdges = true;
for (ArcIt a(T.g); a != INVALID; ++a){
if (cplex.getValue(x[a]) > 1-EPS && usedArcs[a] == false) {
usedAllEdges = false;
break;
}
}
if (usedAllEdges) {
success = true;
break;
}
//Else, Set N to be T and repeat
else currentNode = target;
} else {
//No arcs were found. Find a node from the path that has unvisited Arc
positionToInsert = 0;
DiNode target = INVALID;
for (list<DiNode>::const_iterator iterator = path.begin(), end = path.end(); iterator != end; ++iterator) {
DiNode v = *iterator;
for(Digraph::OutArcIt a(T.g, v); a != INVALID; ++a) {
if(cplex.getValue(x[a]) >= 1-EPS && !usedArcs[a]) {
target = v;
break;
}
}
positionToInsert ++;
if (target != INVALID) break;
}
if (target != INVALID) {
//cout << "found lost node" << endl;
currentNode = target;
} else {
success = false;
break;
}
}
}
return success;
}
Let starting n = origin node
For node n:
Find an unvisited edge E whose value is 1.
Mark edge as visited
Get the target T of the edge
Add Edge E to the path
If all the edges whose value is 1 are visited, stop
Else, Set N to be T and repeat