2012-04-19 4 views
2

私は64の長さのJava配列i []を持っている場合、その配列のすべての位置が配列全体をループするのではなく「フル」であるかどうかを素早く調べることができますか?私はReversi AIを書いており、配列全体がいっぱいであるかどうかを知る必要があります。配列内のすべての位置が「完全」であるかどうかを素早く見つける方法はありますか?

+1

私は、提供されたメソッドのいずれかが、配列を反復するよりも実行時に高速であるとは思っていません。あるいは、もっと重要なことに、64要素配列を反復することは、「パフォーマンスボトルネック」のようなものになります。 –

+0

ボードが完全には満たされていない場合でも、Reversiのオセロ変種は終了できます。これは、ボードがいっぱいであるかどうか(非常に速いものであっても)だけには何の意味もないことを意味することはあまり役に立ちませんが、ゲームを宣言する前に(n) (つまり、それをMinimaxツリー/グラフの葉に置きます)。 (*これは、グリッドが完全に塗りつぶされる前にゲームが終了することを意味する* from:.wikipedia.org/wiki/Reversi#Rules) –

答えて

10

long(64ビット)タイプのflags変数を保持し、適切なビットを設定またはクリアすることによって、どのアレイエントリが「フル」であるかを追跡するために使用します。 (アレイエントリと同期させておく必要があります)

ビットごとに1の値を使用すると、関連するセルがいっぱいであることを意味する場合は、アレイ全体が満たされているかどうかを、フラグ変数を-1Lに設定します。

実装例

int[] grid = new int[64]; 
long full = 0L; 

// place a piece at a certain grid position 
grid[17] = 1; // pretend 1 is the code for black 
full |= 1L << 17; // set bit 17 in our "full" tracker 

// is the grid full? 
if (full == -1L) 
    // yes it is! 
else 
    // no it isn't 

あなたも、より狡猾こと、そしてあなたが完全に配列を使用して避けることができますので、あまりにも各セルの色を追跡するためのフラグ変数を使用することができます。 1つの変数は、与えられたセルが占有されているかどうかを追跡し、もう1つは色を追跡します(白は0、黒は1)。

long colour = 0L; 
long full = 0L; 

// set position 17 to white 
colour &= ~(1L << 17); // clear the bit (white) 
full |= (1L << 17); // set it to occupied 

// set position 42 to black 
colour |= (1L << 42); // set the bit (black) 
full |= (1L << 42); // set it to occupied 

// is position 25 occupied? 
if ((full & (1L<<25)) != 0) { 
    // yes, but what colour? 
    if ((colour & (1L<<25)) != 0) 
     // black 
    else 
     // white 
} 

// is the grid full? 
if (full == -1L) 
    // yes it is! 
else 
    // no it isn't 
+3

+1イタチでいっぱいの樽より狡猾です。 – mcfinnigan

+0

私は位置iにアイテムを追加すると仮定しています。 long + = 2^i; –

+0

はい。私はより多くの提案を追加しました。 –

2

複数の「空の」セルを個別に保持し、移動するたびに更新することができます。

しかし、私はこの最適化の必要性を見ません:長さ64のループは非常に高速でなければなりません。これが本当のボトルネックかどうか、最適化があなたの努力の価値があるかどうかを試してみてください。

+0

アルファベータプルーニング法を使用している場合は、私はノードを開く時間。したがって、64^64回のループが発生する可能性があります。 なぜ今すぐに見えますか? –

+0

@Sam:この場合、空のセルの数を維持するために増分/減分を使用するだけでは、ビット演算(インデックス計算を伴う)より高速でなければなりません。 – Vlad

0

白黒(またはフリーホワイトiswhite)に2つのBitSetsを使用できます。

+0

なんて!(黒||白) –

0

Arrays.asList(i).contains(EMPTY)(おそらくあなたは空を意味するnullを解釈しています)。

+1

メソッドが順番にループしませんか? – sgowd

+0

これは、配列を繰り返し処理する明白なアプローチよりも効率が悪いです。 –

+0

書き込みと読み込みが速くなりました。私たちがパフォーマンスについて話していたら、それぞれのポジションで配列要素を使用することはありません.2つの 'long'が実行するでしょう。そして、比較はおそらくは(十分に最新のプロセッサアーキテクチャ上の)単一の単純な操作を取るでしょう。 –

関連する問題