バックトラック法

11月 11th, 2008 admin Posted in アルゴリズムとデータ構造 |

久しぶりに「アルゴリズムとデータ構造シリーズ」です。今回は第10章「バックトラック法と幅優先探索」のバックトラック法です。

バックトラック法

ある解を求めるときに、考えられるパターンをすべて試しながら解く方法のひとつです。迷路の右手法をイメージするといいんじゃないでしょうか。パワープレイすぎてスマートさはありませんが、結局この方法が早かったり、この方法でないと解けなかったりします。以前ナンプレに挑戦したときも結局このバックトラック法を使いました。

コード

今回はエイトクイーン問題をバックトラック法で解くようにしました。

RUBY:
  1. class Qween
  2.   def initialize(n)
  3.     @size = n
  4.     @board = Array.new
  5.     @size.times do |i|
  6.       @board[i] = Array.new
  7.       @size.times do |j|
  8.         @board[i].push(nil)
  9.       end
  10.     end
  11.   end
  12.  
  13.   def check(y,x)
  14.  
  15.     (0...x).each do |i|
  16.       return nil unless @board[y][i].nil?
  17.     end
  18.  
  19.     (x+1).times do |i|
  20.       if (y-i)>= 0 && (x-i)>= 0
  21.         return nil unless @board[y-i][x-i].nil?
  22.       end
  23.  
  24.       if (y+i) <@size && (x-i)>= 0
  25.         return nil unless @board[y+i][x-i].nil?
  26.       end
  27.     end
  28.     true
  29.   end
  30.  
  31.   def solve(x)
  32.     return true if x == @size
  33.  
  34.     (0...@size).each do |i|
  35.       if check(i,x)
  36.         @board[i][x] = true
  37.  
  38.  
  39.         if solve(x+1)
  40.           return true
  41.         else
  42.           @board[i][x] = nil
  43.         end
  44.       end
  45.     end
  46.     return nil
  47.   end
  48.  
  49.   def show
  50.     @board.each do |row|
  51.       row.each do |c|
  52.         print c ? 'Q' : '-'
  53.         print ' '
  54.       end
  55.       print "\n"
  56.     end
  57.   end
  58. end
  59.  
  60. q = Qween.new(ARGV[0].to_i
  61. )
  62. q.solve(0)
  63. q.show

結果

CODE:
  1. Q - - - - - - -
  2. - - - - - - Q -
  3. - - - - Q - - -
  4. - - - - - - - Q
  5. - Q - - - - - -
  6. - - - Q - - - -
  7. - - - - - Q - -
  8. - - Q - - - - -

たしかにQが縦にも横にも斜めにも重ならないように配置されています。

まとめ

ちなみにNクイーン問題は4x4以上ならすべて解があるそうです。個人的には4x4の解が一番かっこよく見えるかな。クイーン同士が仲良さそうで

CODE:
  1. - - Q -
  2. Q - - -
  3. - - - Q
  4. - Q - -

※このシリーズは私がRubyでアルゴリズムとデータ構造を基礎から学ぶ記録です。全体の目次はこちらへ。

2 Responses to “バックトラック法”

  1. [...] バックトラック法 はてなに追加 MyYahoo!に追加 del.icio.usに追加 livedoorClipに追加 15 Responses to “Rubyでアルゴリズムとデータ構造” [...]

  2. I loved reading this and I dont really like to read :)

Leave a Reply