我们可能需要更多地了解您的图表。我有一个“类似”的问题。
这可能不是您正在寻找的,但它是相似的。这是我在有向图上使用的一个 DFS 访问者,它有一个根来计算从起始节点到所有其他(可达)节点的路径数。
这很有效,因为我的图是一个有根的 DAG。我必须先反转图表,以便我的起始节点实际上是一个接收节点。然后源节点成为 DAG 的根。如果我想要实际路径,我可能会添加一个告诉路径历史的堆栈。
//depth first search to calculate path number, calculates the number of paths to a target
// conceptually equivalent to a topological sort.
class PathNumDFSVisitor:public boost::default_dfs_visitor{
public:
PathNumDFSVisitor(boost::unordered_map<std::string,std::size_t>& inMap):pathNumMap(inMap){}
template < typename Vertex, typename Graph >
void finish_vertex(Vertex u, const Graph & g)
{
std::string term = g[u].termId;
if(boost::out_degree(u,g) == 0){
pathNumMap[term] = 1;
}else{
pathNumMap[term] = 0;
//Iterate over the children of the term to add the child annotations
typename boost::graph_traits< Graph >::out_edge_iterator ei, e_end;
for(tie(ei, e_end) = boost::out_edges(u, g); ei != e_end; ++ei){
Vertex v = boost::target(*ei, g);
std::string childTermId = g[v].termId;
pathNumMap[term] += pathNumMap[childTermId];
}
}
}
boost::unordered_map<std::string,std::size_t>& pathNumMap;
};
不过,在一般情况下,我建议计算一条最短路径,然后依次获取每条边并找到从源到目标的替代路线。现在该边缘可能是两个或多个边缘,这反过来又需要放松并考虑替代路径。就像 Sehe 说的,它会是一个生成器,并且它可以在一般的无向图中快速爆炸。也许如果我们对您的图形约束有更多了解,我们可以提供更多帮助。
也许添加最大路径长度条件可以帮助限制您生成的简单路径的数量。
考虑这个一般的全连接图。
我们需要计算A和B之间的所有路径。
所以我们需要所有 1 条边路径 + 所有 2 条边路径加上 ...
所以我们需要A - B,一个优势。
然后是所有 2 个边缘路径。
A - ? - B,有3个
然后所有 3 条边路径
A - ? - ? - B,有 3 * 2。
以此类推,有 4 个或更多边。
您可以看到随着 N 的增长,我们会达到 N-2 * N-3 * N-4 ... 等等。这是一个阶乘爆炸,O(N!)。
这些示例说明了不同的拓扑如何导致非常不同的算法和复杂性。要从 SO 中获得直接/有用的答案,请提供任何有帮助的细节。