【问题标题】:Which Map implementation is most suitable for River Crossing puzzle?哪种 Map 实现最适合 River Crossing 谜题?
【发布时间】:2017-03-07 05:05:52
【问题描述】:

这是我正在学习的数据结构课程的一个项目,因此我希望您提供关于我是否正确考虑这个问题或者我是否遗漏了什么的意见,而不是提供编码答案。很多人都听说过这个谜题,但如果你没有听说过,这里是:

一位农民带着他的财产在河的南岸:一只山羊、一头狼和一棵很大的卷心菜。农夫想带着他所有的财产去河的北岸。这条河又深又宽,不能涉水过。但是,有一艘小船可用。这艘船太小了,以至于农民一次只能带走他的一件财产。重要的是要注意另外两个条件。

  1. 如果将山羊和狼单独留在火星车的同一侧,狼会吃掉山羊。
  2. 如果山羊和卷心菜单独放在同一侧,山羊会吃掉卷心菜。

该项目要求我们创建一个 Graph 数据结构来帮助农民决定如何将他的财产转移到河的另一边。

我目前的想法是我将有一个Vertex 类:

public class Vertex {
    private enum Element{ FARMER, SHEEP, WOLF, CABBAGE }
    private Element type;
    private List<Edge> neighbors;

    public Vertex(Element e){
        type = e;
    }
    public List getNeighbors(){
        return this.neighbors;
    }

    public void AddEdge(Vertex destination, int depth){
        neighbors.add(new Edge(destination, depth));
        destination.neighbors.add(new Edge(this, depth));
    }
    private static class Edge {
        public Vertex destination;
        public int depth;

        public Edge(Vertex destination, int depth){
            this.destination = destination;
            this.depth = depth;
        }
    }
}

我还想创建一个Graph 类,其中包含顶点和边的collection(HashMap、TreeMap 或其他类型的数据结构)作为字段。它还将包含我的Bank 类的两个对象的字段,以表示河流的南侧和北侧。

正如您在Vertex 类中所见,我创建了一个名为Element 的枚举,其中包含FARMER, SHEEP, WOLF, CABBAGE。在阅读了有关 Map 实现的 JavaDoc 之后,我倾向于使用 EnumMap 作为我的 Map 类型。最终,我将需要在 BreadFirst 搜索和 DepthFirst 搜索中遍历这些数据,但我想不出任何理由为什么一个 Map 实现会比另一个更好。

我只是通过阅读 JavaDoc 而不是在课堂上了解 EnumMap,所以我想确保我没有遗漏任何可能使这成为一个坏主意的关键信息...

所以我的问题是:在这种情况下使用 EnumMap 是否有意义,或者不同的 Map 实现更有意义?

如果您需要更多说明或背景信息,请告诉我。

【问题讨论】:

  • 我不清楚您使用地图的目的。您可以将EnumMap 视为由Element 而不是整数索引的数组,例如map[FARMER] == some valuemap[SHEEP] == some other value 等,这不是合法的 Java,但希望能让您了解这会给您带来什么。如果这不是您想要的,那么您不需要EnumMap
  • @ajb 我想使用地图来根据另一侧的剩余内容来基本检查向河流一侧移动是否有效,这打破了拼图规则。例如,我试图将卷心菜移过河,但检查另一边的顶点,然后注意到它们是狼和羊,这违反了规则。
  • 抱歉,这还不够具体。我仍然无法说出你为什么想要一张地图以及你会用它做什么。映射具有成对的(键,值),每个键最多一对。如果你想要一个EnumMap,那么关键就是Element。每个键对应的值是什么?
  • 实际上,我完全不清楚您是否清楚地知道您使用图表的目的。我认为您需要非常清楚和具体:顶点代表什么,边代表什么,最重要的是,您的程序将如何使用图形来解决问题?我的意思是实际上有一个计算机会遵循的逐步算法,而不是一个模糊的想法。如果你没有那个,那么你就太快地跳入代码的细节了。如果您有算法,请分享它,因为它将帮助我们回答您的问题。
  • 对于那些可能遇到这篇文章的人来说,我想到的算法基本上是查看初始状态(然后是第一次迭代后的当前状态)并检查可能的结果:初始状态 = ( (FCGW) ())。可能的状态= ((CGW) (F)), ((GW) (FC)), ((WC) (FG)), ((GC) (FW))。下一次迭代将使用 ((WC) (FG)) 作为当前状态并评估可能的新可能状态。这一直持续到找到所需的状态。

标签: java dictionary graph


【解决方案1】:

在我看来,银行状态应该进入顶点,边缘类型应该是四种可能性之一(三种可用的动物或他自己)。哈希集对于检测图中的循环很有用,但这显然需要为您的 Vertex 类提供适当的 equals 和 hashCode 方法。

Graph 类不需要维护边的集合。它只需要一个对初始 Vertex 的引用,以及任意数量的实用方法。

对于 EnumMap,每个 Vertex 都可以使用它来将边存储到下一个 Vertex。

【讨论】:

    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2021-03-17
    相关资源
    最近更新 更多