目次> 第20章> 20.3 | TOPUPPREVNEXT |
プログラミング入門の定番です。
リカーシブ・アルゴリズムの例題として提示されることも多いのですが、
全数探索の例題としてもよく使われます。
「すべてのケースを洗い出して調べてみる」 しかないと考えられる問題で、
[エイト・クィーンの問題]
チェス盤は、縦8、横8の盤ですが、ここに8個のクィーンをお互いに
利き筋にないように置く
というのが問題です。
チェス盤を一般化して、縦横Nマスの盤にN個のクィーンを置く問題を
N−Queen問題といいます。この問題は、Nが増加するにつれて
計算の手間が、eN に比例して増加することで
知られています。Nが8とか10であればあっという間に計算できますが、
Nが大きくなるにつれて計算時間が急激に増加します。
このように、問題のサイズが大きくなるにつれて
計算時間が指数関数的に増加する問題をNP問題といいます。
20.2のハノイの塔は、円盤の個数nに対して、移動回数が 2 n− 1 ですから、これもNP問題です。
概ね、以下の戦略ですべての組み合わせを網羅します。
Java の メソッド風の書き方で、 「 n 行目に置く」 という
checkAndSet( n ) を書いてみましょう。
n 行目の置ける場所を探すには、n 行目以降 一番下まで
ちゃんと置けることを確認しなければいけません。
行は 0、1、2、...、7 までの8行です。
void checkAndSet(int n) {
n行目の k列目にクイーンを置くことを
と表しましょう。たとえば、pos が { 0, 4, 7, 5, 2, 6, 1, 3 } であれば、下図のような盤とクイーンの配置を表すことにします。
クイーンの縦の利き筋は、posに同じ番号がないかどうかで調べられます。 右上がり方向の利き筋は、 行と列の和が等しいことで調べられます。 右下がり方向の利き筋は、 行と列の差が等しいかどうかで調べられます。クイーンを置いたときに、 列の番号をposに保存すると同時に、行番号から列番号を引いたものを na に 行番号と列番号の和を ns に設定しておくことにします。
ソースプログラムは、 EightQueen4.java です。
実行には、次の4つの GIF ファイルが必要です。プログラムと同じフォールダにダウンロードしてください。
更新日:2004-06-25 | TOPUPPREVNEXT |