0

解決するのが難しい問題があります (少なくとも私はそう見ています)。異なる値 ([1-6] 以外)のサイコロ(面 1 ~ 6) とボード(n-by-m) があります。開始位置と終了位置があります。サイコロを振って、あるマスから別のマスに移動できます。これを行うことで、上面を合計/コストに追加する必要があります。

ここで、最小の合計/コストで開始位置から終了位置に到達する方法を計算する必要があります。ほとんどすべてを試しましたが、正しいアルゴリズムが見つかりません。

ダイクストラを試しましたが、正しいパスには、別のパスからのより良い合計で到達できる中間ノードがいくつかあるため、役に立ちません(最終的には正しくないことがわかります)。アルゴリズムを変更するにはどうすればよいですか?

アルゴリズムの概要:
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]));
            } 

        }
    }

}
4

1 に答える 1

3

ダイクストラ状態でのサイコロの位置も考慮する必要があります。

つまり、だけを持つことはできません。 のsums[lines][column]ようなことをする必要があります。 はsums[lines][column][die_config]die_configダイの位置を整数に変換するために作成する方法です。

たとえば、最初は次のようなサイコロがあるとします。

^1 <4 v2 >9 f5 b7 (^ = 上面、< = 左... 下、右、前後)

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

上向きの面のインデックス (0 から 5 まで) と左向きの面のインデックスを考慮するだけで、整数に変換できます。これは、ダイスの回転位置が 36 未満(下の注を参照)であり、 (0-based) などでエンコードできることを意味します(up*6 + left)。つまり、各面は、コストに関連付けられた値に関係なく、決定した 0 から 5 の値を持つことになるため、上記の例に従って、最初の上面を index としてエンコードし0、左側の面をindex としてエンコードします。 1、 等々。

したがって、config 値を持つサイコロは、最初に上を向いていた面 (initial_die[0]) が現在左を指しており、現在上を向いている面が、最初はダイの後ろを向いていた面であること30を意味します。ダイ (initial_die[5])。したがって、これは現在、サイコロの左面にコスト 1 があり、上面にコスト 7 があることを意味します。最初の配置がわかっているため、この情報から残りのサイコロの面を導き出すことができます。(基本的に、これは、最初の状態と比較して、サイコロが左に 1 回転がされた後、前に 1 回転がされたことを示しています)left = 30%6 (=0)up = (30 - left)/6 (=5)

この追加情報を使用すると、ダイクストラは、最終ノードに到達する最も安いコストを考慮して、求める正しい答えを見つけることができます。これは、最終的なダイの位置が異なる複数のダイが存在する可能性があるためです。

注: 実際には 36 の可能な位置はありません。たとえば、最初は反対側の 2 つの側面が上/左で隣接することができないなど、いくつかの不可能な位置があるためです。実際には有効な位置は 24 しかありませんが、上記で使用した単純なエンコードでは、ダイのエンコード方法に応じて、実際には最大 34 までのインデックスが使用されます。

于 2013-05-21T01:19:57.807 に答える