查找从一个图节点到另一个图节点的所有路径的逻辑

时间:2012-11-01 14:20:42

标签: algorithm logic combinations

我有一个棘手的逻辑问题,我正在尝试创建一个算法来解决它,但我正在努力解决它。

考虑这些数据:

A to B
A to C
A to D
A to E
B to C
B to D
B to E
C to D
C to E
D to E

正如您所看到的,这有效地产生了如下模型:A - B - C - D - E

你只能向一个方向前进,(从左到右)我想写的是一个可以计算出2点之间所有可能组合的算法,即

如果我想从A转到E,所有可能的组合都是这样的:

A - E 
A - D - E
A - C - E
A - B - E
A - C - D - E
A - B - D - E
A - B - C - E
A - B - C - D - E

我认为就是这样。

有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

首先,考虑一下如何表示单个“跳”:每个节点都需要一个相邻节点的列表。首先构建这些节点。

您还需要一种从节点池中查找节点的方法(按名称?)。也许把它们放在地图上?

一个暴力算法将从所请求的节点开始并递归跟踪所有跳,观察循环,直到到达请求的端,传递List - 使用它作为下推堆栈,来记录路径。每次到达请求的结束时,将列表的内容保存到Path集合。如果你遇到了死胡同(没有链接转到请求的结尾),请在递归中备份并继续。

根据您对速度的需求,您可以扩展数据结构以保留一些预先计算的路径。

尝试使用伪代码然后使用Java。

答案 1 :(得分:2)

您的问题最好说明如下:“对于给定的有向图,列出可以从某个节点转到另一个节点的所有可能路径。”请参阅Graph Algorithm To Find All Connections Between Two Arbitrary Vertices

你可以用递归来解决它:

Paths(NodeSequence start, Node finish, ListOfNodeSequences result)将一个空白的节点序列列表作为第三个参数,并且可以通过Node n的一跳到达的每个start添加start + {{ 1}}如果nresult,则为n,否则将finish作为第一个参数调用Paths

递归可能不一定是解决此问题的最有效资源的方法,但编码并不是很多工作。上面的结果假设你将初始化一个空的结果变量,它将被递归函数修改而不是被返回,所以它有点奇怪,但我给出的版本应该花费最少的努力。

不完整的解决方案(省略不相关的实施细节):

start + n

public class Node { public String name; public boolean Equals(Node other) { throw new NotImplementedException(); } }; public class NodeSequence { private ArrayList<Node> nodes; public NodeSequence() { nodes = new ArrayList<Node>(); } public NodeSequence Plus(Node n) { // Returns this NodeSequence with n appended to the end throw new NotImplementedException(); } public Node Last() { throw new NotImplementedException(); } } public void paths(NodeSequence start, Node finish, ArrayList<NodeSequence> results) { Node startNode = NodeSequence.Last(); ArrayList<Node> nextStops; // Populate nextStops with every node that is directly after startNode // Recursive block for (Node n : nextStops) { if (n.Equals(finish)) results.Add(start.Plus(n)); else Paths(start.Plus(n), finish, results); } } ArrayList<NodeSequence> findAllPaths(Node start, Node finish) { ArrayList<NodeSequence> allPaths = new ArrayList<NodeSequence>(); // This line will take a while paths(start, finish, allPaths); return allPaths; } 会给你结果。

答案 2 :(得分:1)

我认为逻辑可能如下:

  1. 维护一个列表/数组,例如

      char[] chars = {'A','B', 'C', 'D','E'};
    
  2. 创建3个索引变量,begin = 0,end = chars.length-1,index = 0;
  3. 每个范围打印实施2个嵌套for循环,

      for begin =0 to end
          collect chars[beign]
          for indx end -begin to end
              collect chars[indx]                  
    
  4. 我认为这样做会。

    一个示例逻辑如下:

     char[] chars = {'A','B', 'C', 'D','E'};
     List<Character> charList = new ArrayList<Character>();
     for (int begin=0; begin <chars.length; begin++){
       for (int index=begin; index <chars.length; index++){
         charList.add(chars[begin]);
         for (int indx1=chars.length-index; indx1 <chars.length-begin; indx1++){
            charList.add(chars[indx1+begin]);
         }
         System.out.println(charList);
         charList.clear();
       }
     }
    

    哪个应该打印结果为:

    [A]
    [A, E]
    [A, D, E]
    [A, C, D, E]
    [A, B, C, D, E]
    [B]
    [B, E]
    [B, D, E]
    [B, C, D, E]
    [C]
    [C, E]
    [C, D, E]
    [D]
    [D, E]
    [E]