【问题标题】:How to get all paths between to items如何获取项目之间的所有路径
【发布时间】:2019-05-05 21:32:15
【问题描述】:

我必须计算列表中两个项目之间的所有可能路径。每个项目都有两个字段:它的名称和它的邻居的名称。

我必须生成一个列表,其中包含允许我在两个特定项目之间建立路径的所有项目。

想象一下我有 Item(A, B) 和 Item(A, C) 并且我被要求从 B 到 C 的解决方案。我必须返回两个 Item 因为我可以通过使用它们从 B 到达 C :B->A->C。

请注意,我对到达目的地所需的物品没有限制。

我尝试了几种解决方案,但都没有成功。我知道我必须使用某种递归函数,但我不知道怎么做。

这是我的 Item 类:

public class Item {
    private String name;
    private String neighbor;

    public Item(String name, String neighbor){

        this.name = name;
        this.neighbor = neighbor;
    }

    //getters and setters
}

由于我必须获取两个特定项目之间的所有可能路径,因此我必须返回一个列表列表:

List<List<Item>> solution;

我的解决方法

我最终将我的项目转换为图表,一旦构建完成,我使用深度优先横向 (DFT) 来查找源和目标之间的所有可能路径。

我设置了将每个项目的名称与图形表示相关联的键值对,并从图形中得到一个整数列表,指示图形中的路径(例如 1-2-3-5)。从该列表中,我找到了我的项目,并返回了一个列表,其格式为我已经解释过的格式。

仅为有类似问题的人发帖!

【问题讨论】:

  • 为什么不使用不同的数据结构(例如有向图或无向图)来更好地模拟节点之间的关系?
  • 因为需要使用这个数据结构
  • 好的,您可以遍历每个节点并在每个节点上执行深度优先搜索,看看您是否可以到达所需的节点(沿途将节点标记为已访问以避免循环)。跨度>
  • 您谈论列表,但您所描述的至少是一棵树,但更可能是无向图。所以:听起来你一直在使用完全错误的数据结构,通过首先确保你使用正确的数据结构,你的问题会变得容易得多。编写或使用简单的图形数据结构,使用父/子关系而不是“邻居”,您的搜索算法变为“尝试从这里到达 X,通过联系所有父母和所有孩子(使用 seen 节点列表已联系)”。
  • 是的,我同意你的看法@Mike'Pomax'Kamermans。我正在使用无向图。我的问题是我必须强制使用这种数据结构,所以我将尝试从我的数据中创建一个无向图并使用该图

标签: java recursion


【解决方案1】:

根据我的评论尝试这样的事情:

您可以遍历每个节点并执行深度优先搜索 每个节点,看看你是否可以到达所需的节点

您标记访问过的节点既可以避免循环(如果它们在您的用例中甚至可能)并跟踪路径。

List<Item> depthFirstSearch(Item startItem, Item desiredItem, List<Item> visitedNodes) {
    if (startItem.equals(desiredItem)) {
        return visitedNodes;
    }

     // Exit if we reach a cycle or no more neighbors to follow
    if (visitedNodes.contains(startItem) || startItem.getNeighbor() == null) {
        return null;
    }

    visitedNodes.add(startItem); 

     // Recurse; continue search from neighbor
    return depthFirstSearch(startItem.getNeighbor(), desiredItem, visitedNodes);
}

并像这样使用它(你需要根据你的代码调整它):

List<Item> items;
List<List<Item>> result = new List<List<Item>>();

for (Item item : items) {   
    List<Item> pathToDesired = depthFirstSearch(item, desiredItem, new LinkedList<Item>());

    if (pathToDesired != null) {
        results.add(pathToDesired);
    }
}

result 将包含所需项目的所有路径。

【讨论】:

  • 你的解决方案有问题,就是Item的neighbor字段是String,而不是不同的Item。每个项目都有两个字段,它的名称和它的邻居名称。它代表了两个项目之间的联系,而不是项目本身。
  • 嗯,好的,所以在这种情况下,我会使用“名称”作为键将您的项目存储在哈希图中。与其在startItem.getNeighbor() 上递归,不如使用startItem.getNeighbor() 作为从哈希图中获取实际项目并对其进行递归的键:即depthFirstSearch(itemMap.get(startItem.getNeighbor()), desiredItem, visitedNodes);
  • 是的,它可以工作。非常感谢您的宝贵时间。我最终所做的是将我的数据转换为图表,并按照您的建议使用 DFT,我在图表中找到源和目标之间的所有路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2019-12-22
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
相关资源
最近更新 更多