我必须创建一个方法来创建一个包含图形中所有路径的列表。我的图形只有一个起始节点和一个结束节点。每个节点都有一个列表,其子列表和其父节点列表。我必须制作另一个包含所有路径的列表(每个路径都在另一个列表中)
有什么建议吗?
答案 0 :(得分:6)
这取决于它是否是非循环的。显然,一个循环将导致无限路径(一次循环,两次循环,三次循环等等)。如果图形是非循环的,那么您应该能够执行深度优先搜索(DFS)(http://en.wikipedia.org/wiki/Depth-first_search)并简单地计算遇到目标节点的次数。
答案 1 :(得分:2)
首先熟悉基本图算法(尝试教科书或谷歌)。找出哪一个最适合您正在解决的问题,并实施它。您可能需要对算法进行一些调整,但一般来说,所有基本图形问题都有广为人知的算法。
答案 2 :(得分:1)
如果你有一个如下所示的GraphNode类:
public class GraphNode
{
public IEnumerable<GraphNode> Children { get; set; }
// ...
}
然后这可以做的工作:
public static class GraphPathFinder
{
public static IEnumerable<IEnumerable<GraphNode>> FindAllPathsTo(this GraphNode startNode, GraphNode endNode)
{
List<IEnumerable<GraphNode>> results = new List<IEnumerable<GraphNode>>();
Stack<GraphNode> currentPath = new Stack<GraphNode>();
currentPath.Push(startNode);
FindAllPathsRecursive(endNode, currentPath, results);
return results;
}
private static void FindAllPathsRecursive(GraphNode endNode, Stack<GraphNode> currentPath, List<IEnumerable<GraphNode>> results)
{
if (currentPath.Peek() == endNode) results.Add(currentPath.ToList());
else
{
foreach (GraphNode node in currentPath.Peek().Children.Where(p => !currentPath.Contains(p)))
{
currentPath.Push(node);
FindAllPathsRecursive(endNode, currentPath, new List<IEnumerable<GraphNode>>());
currentPath.Pop();
}
}
}
}
这是DFS算法的简单实现。没有错误检查,优化,线程安全等......
此外,如果您确定图形不循环,则可以在最后一个方法中删除foreach语句中的where子句。
希望这会有所帮助。
答案 3 :(得分:0)
您可以生成每个可能的顶点组合(使用组合学)并过滤掉不存在的路径(顶点未通过边连接或边缘上的方向错误)。
您可以通过生成组合的代码检查当前顶点可用的剩余顶点来改进此基本思想。
这是假设您有非循环图并希望只访问每个顶点一次。