柠檬图如何找到两个节点之间的所有路径
Lemon graph how to find all paths between two nodes
我正在使用 Lemon C++ 库处理图形,我需要做的是找到两个节点之间的所有路径。我能够找到一条路径(最短),但我需要所有路径。
有没有办法用 Lemon 实现这个目标?
// Create the graph
ListDigraph g;
ListDigraph::Node a = g.addNode();
ListDigraph::Node b = g.addNode();
ListDigraph::Node c = g.addNode();
ListDigraph::Node d = g.addNode();
ListDigraph::Node e = g.addNode();
ListDigraph::Arc a_b = g.addArc(a, b);
ListDigraph::Arc b_c = g.addArc(b, c);
ListDigraph::Arc c_d = g.addArc(c, d);
ListDigraph::Arc a_e = g.addArc(a, e);
ListDigraph::Arc e_d = g.addArc(e, d);
// Assign labels to edges and arcs
ListDigraph::NodeMap<std::string> nodeValues(g);
nodeValues[a] = "a";
nodeValues[b] = "b";
nodeValues[c] = "c";
nodeValues[d] = "d";
nodeValues[e] = "e";
ListDigraph::ArcMap<std::string> arcValues(g);
arcValues[a_b] = "a->b";
arcValues[b_c] = "b->c";
arcValues[c_d] = "c->d";
arcValues[a_e] = "a->e";
arcValues[e_d] = "e->d";
// Find the shortest path
Bfs<ListDigraph> bfs(g);
bfs.init();
bfs.addSource(a);
bfs.start();
if (bfs.reached(c))
{
std::cout << nodeValues[c];
ListDigraph::Node prev = bfs.predNode(c);
while (prev != INVALID)
{
std::cout << "<-" << nodeValues[prev];
prev = bfs.predNode(prev);
}
std::cout << std::endl;
}
=> c<-b<-a
感谢 srt1104 的评论,这就是我“解决”问题的方式,假设我正在寻找 a
和 d
之间的所有路径。
Dfs<ListDigraph> dfs(g);
dfs.init();
dfs.addSource(a);
std::vector<ListPath<ListDigraph>> paths;
ListPath<ListDigraph> currPath;
ListDigraph::Node prevNode = a;
while (!dfs.emptyQueue())
{
ListDigraph::Arc arc = dfs.processNextArc();
if (g.source(arc) == prevNode)
{
currPath.addBack(arc);
prevNode = g.target(arc);
}
else
{
prevNode = g.target(arc);
currPath = {};
currPath.addBack(arc);
}
if (g.target(arc) == d)
{
paths.push_back(currPath);
}
}
cout << "Paths.." << endl;
for (auto path : paths)
{
for (int i = 0; i < path.length(); i++)
{
cout << arcValues[path.nth(i)] << " ";
}
cout << endl;
}
---------
Paths..
a->e e->d
a->b b->c c->d
我正在使用 Lemon C++ 库处理图形,我需要做的是找到两个节点之间的所有路径。我能够找到一条路径(最短),但我需要所有路径。
有没有办法用 Lemon 实现这个目标?
// Create the graph
ListDigraph g;
ListDigraph::Node a = g.addNode();
ListDigraph::Node b = g.addNode();
ListDigraph::Node c = g.addNode();
ListDigraph::Node d = g.addNode();
ListDigraph::Node e = g.addNode();
ListDigraph::Arc a_b = g.addArc(a, b);
ListDigraph::Arc b_c = g.addArc(b, c);
ListDigraph::Arc c_d = g.addArc(c, d);
ListDigraph::Arc a_e = g.addArc(a, e);
ListDigraph::Arc e_d = g.addArc(e, d);
// Assign labels to edges and arcs
ListDigraph::NodeMap<std::string> nodeValues(g);
nodeValues[a] = "a";
nodeValues[b] = "b";
nodeValues[c] = "c";
nodeValues[d] = "d";
nodeValues[e] = "e";
ListDigraph::ArcMap<std::string> arcValues(g);
arcValues[a_b] = "a->b";
arcValues[b_c] = "b->c";
arcValues[c_d] = "c->d";
arcValues[a_e] = "a->e";
arcValues[e_d] = "e->d";
// Find the shortest path
Bfs<ListDigraph> bfs(g);
bfs.init();
bfs.addSource(a);
bfs.start();
if (bfs.reached(c))
{
std::cout << nodeValues[c];
ListDigraph::Node prev = bfs.predNode(c);
while (prev != INVALID)
{
std::cout << "<-" << nodeValues[prev];
prev = bfs.predNode(prev);
}
std::cout << std::endl;
}
=> c<-b<-a
感谢 srt1104 的评论,这就是我“解决”问题的方式,假设我正在寻找 a
和 d
之间的所有路径。
Dfs<ListDigraph> dfs(g);
dfs.init();
dfs.addSource(a);
std::vector<ListPath<ListDigraph>> paths;
ListPath<ListDigraph> currPath;
ListDigraph::Node prevNode = a;
while (!dfs.emptyQueue())
{
ListDigraph::Arc arc = dfs.processNextArc();
if (g.source(arc) == prevNode)
{
currPath.addBack(arc);
prevNode = g.target(arc);
}
else
{
prevNode = g.target(arc);
currPath = {};
currPath.addBack(arc);
}
if (g.target(arc) == d)
{
paths.push_back(currPath);
}
}
cout << "Paths.." << endl;
for (auto path : paths)
{
for (int i = 0; i < path.length(); i++)
{
cout << arcValues[path.nth(i)] << " ";
}
cout << endl;
}
---------
Paths..
a->e e->d
a->b b->c c->d