滚动骰子的最短路径

时间:2013-05-20 23:59:31

标签: algorithm dijkstra shortest-path

我有一个难以解决的问题(至少我是怎么看的)。我有一个 die (面对1到6)有不同的值(除了[1-6]以外)和(n-by-m)。我有一个起始位置和一个完成位置。我可以通过滚动模具从一个正方形移动到另一个正方形。通过这样做,我必须将顶面添加到总和/成本。

现在我必须计算如何从开始位置到最终位置的最小值 总和/成本。我已经尝试了几乎所有的东西,但我无法找到正确的算法。

我尝试了Dijkstra,但它没用,因为在正确的路径中有一些中间节点 我可以从另一条路径获得更好的总和(最终证明是不正确的)。我该如何更改算法?

算法概述:
dijkstra:PriorityQueue
if(我可以到达一个总和较小的节点)
,将其从队列中删除,
我改变了它的成本和模具位置 ,将其添加到队列中。

这是代码:

public void updateSums() {

    PriorityQueue<Pair> q = new PriorityQueue<>(1, new PairComparator());

    Help h = new Help();

    q.add(new Pair(startLine, startColumn, sums[startLine][startColumn]));

    while (!q.isEmpty()) {

        Pair current = q.poll();

        ArrayList<Pair> neigh = h.getNeighbours(current, table, lines, columns);

        table[current.line][current.column].visit(); //table ->matrix with Nodes

        for (Pair a : neigh) {

            int alt = sums[current.line][current.column] + table[current.line][current.column].die.roll(a.direction);

            if (sums[a.line][a.column] > alt) {

                q.remove(new Pair(a.line, a.column, sums[a.line][a.column]));

                sums[a.line][a.column] = alt; //sums -> matrix with costs

                table[a.line][a.column].die.setDie(table[current.line][current.column].die, a.direction);

                q.add(new Pair(a.line, a.column, sums[a.line][a.column]));
            } 

        }
    }

}

1 个答案:

答案 0 :(得分:3)

你还需要考虑Dijkstra状态下骰子的位置。

即。你不能只有sums[lines][column],你必须做sums[lines][column][die_config]这样的事情,其中​​die_config是你创建的一种方式,可以将骰子位置转换为整数。

例如,如果你的骰子最初看起来像这样:

  

^ 1&lt; 4 v2&gt; 9 f5 b7(^ =顶面,&lt; =左...下,右,前和   回)

int initial_die[6] = {1,4,2,9,5,7}

您可以通过简单地考虑指向向上的面部索引(从0到5)以及到向左的指数来将其转换为整数。这意味着你的骰子有少于36个(见底部注释)可能的旋转位置,你可以通过(从0开始) (up*6 + left)之类的东西进行编码。我的意思是每个面都会有一个从0到5的值,无论它们与成本相关的值如何,所以按照上面的例子,我们将最初的顶面编码为索引0,左边面对索引1,等等。

所以具有配置值30的骰子意味着left = 30%6 (=0)最初指向的面(initial_die [0]),当前指向左侧,up = (30 - left)/6 (=5)面部目前指向的是最初指向骰子的后退的那个(initial_die [5])。 所以这意味着骰子目前左侧的成本为1,顶部的成本为7 ,您可以从这些信息中获得骰子的其余部分,因为您知道最初的处置。 (基本上,这告诉我们模具向左侧滚动一次,然后向前滚动一次,与初始状态相比)

通过这些附加信息,您的Dijkstra将能够通过考虑到达最终节点的最便宜成本找到您寻找的正确答案,因为您可以拥有多个不同的最终模具位置。

注意:它实际上没有36个可能的位置,因为有些位置是不可能的,例如两个最初相对的侧面将无法在Up / Left上相邻。实际上只有24个有效位置,但我上面使用的简单编码实际上使用的索引最多可达~34,具体取决于你对芯片的编码方式。