使用DFS计算Java中5x5字段上可能的骑士移动

时间:2016-01-12 13:30:42

标签: java recursion depth-first-search

我试图在5x5场上计算所有可能的骑士移动。

为此,我尝试使用DFS(深度优先搜索)和Graph类。

该字段看起来像这样(使用每个字段的id):

0  1  2  3  4
5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

可能的步骤是这样定义的(使用Graph,G的边缘):

G.addEdge(0, 1); G.addEdge(0, 5);

G.addEdge(1, 2); G.addEdge(1, 6);

G.addEdge(2, 3); G.addEdge(2, 7);

G.addEdge(3, 4); G.addEdge(3, 8);

G.addEdge(4, 9);

G.addEdge(5, 6); G.addEdge(5, 10);

G.addEdge(6, 7); G.addEdge(6, 11);

G.addEdge(7, 8); G.addEdge(7, 12);

G.addEdge(8, 9); G.addEdge(8, 13);

G.addEdge(9, 14);

G.addEdge(10, 11); G.addEdge(10, 15);

G.addEdge(11, 12); G.addEdge(11, 16);

G.addEdge(12, 13); G.addEdge(12, 17);

G.addEdge(13, 14); G.addEdge(13, 18);

G.addEdge(14, 19);

G.addEdge(15, 16); G.addEdge(15, 20);

G.addEdge(16, 17); G.addEdge(16, 21);

G.addEdge(17, 18); G.addEdge(17, 22);

G.addEdge(18, 19); G.addEdge(18, 23);

G.addEdge(19, 24);

G.addEdge(20, 21);

G.addEdge(21, 22);

G.addEdge(22, 23);

G.addEdge(23, 24);

这是我试图找到可能的目的地的地方:

private static void calculatePath(int currentSquare) {
        short tours = 0;

        for (int point : G.adj(currentSquare)) {
            System.out.print(currentSquare + " ");
            if (dfs.marked(currentSquare)){
                tours++;
                dfs.unmark(currentSquare);
                calculatePath(point);
            }
        }
        System.out.println(currentSquare + " - tours: " + tours);
        System.out.println("\n");
    }

例如,如果我尝试通过calculatePath(20)调用此递归函数,它应该返回11和17,因为这些是骑士可以从该字段跳转到的唯一可能目的地(ID为20)。未标记的正方形是已经到达的正方形。

变量tours将是可能的游览量(在calculatePath(20)的情况下为2)。

2 个答案:

答案 0 :(得分:1)

您需要一些方法来表达图表中的方向。您的Graph类如何?你可以做的是实现left,right,up和down方法,它们返回那个方向的顶点(如果没有相邻的顶点,则返回null)。这样,您就可以找到可能的动作。在您的示例中,返回顶点的唯一组合是2x right(),1x up()和1x right(),2x up()。

答案 1 :(得分:1)

你的主要问题是你在递归之前unmark广场。

此代码:

        if (dfs.marked(currentSquare)){
            tours++;
            dfs.unmark(currentSquare);
            calculatePath(point);
        }

说:

  1. 如果此方块未标记:
    1. 标记广场
    2. 增量tours
    3. 取消标记广场。 << 这显然是错误的。
    4. 计算此新广场的新路径。
  2. 只有在您从现在标记的方块尝试新路径后才需要unmark

    这并不能解决你的问题并产生骑士的动作,但它肯定会有所帮助。

    您遇到的下一个问题是您添加到图表的边是每个方块的直接邻居。如果你想检查骑士的移动,你将需要增加图形标记方块,这些方格是骑士分开相邻的。这是前五个 - 我会让你完成清单。

        g.addEdge(0, 7);
        g.addEdge(0, 11);
    
        g.addEdge(1, 10);
        g.addEdge(1, 12);
        g.addEdge(1, 8);
    
        g.addEdge(2, 5);
        g.addEdge(2, 11);
        g.addEdge(2, 13);
        g.addEdge(2, 9);
    
        g.addEdge(3, 6);
        g.addEdge(3, 12);
        g.addEdge(3, 14);
    
        g.addEdge(4, 7);
        g.addEdge(4, 13);
    
        g.addEdge(5, 2);
        g.addEdge(5, 12);
        g.addEdge(5, 14);
    

    再次 - 这可能不是您问题的解决方案,但这显然是您的问题之一。