8-Queensプログラム
 # -*- coding: utf-8 -*-
 #
 # GAで8-Queenを解く!
 #
 class Queens
  POPULATION = 1000
  attr_reader :solution
  def randomgene
   (0...8).collect {
    rand(8)
   }
  end
  def initialize
   @genes = []
   POPULATION.times {
    @genes << randomgene
   }
   File.delete("average.log") if File.exist?("average.log")
   File.delete("best.log") if File.exist?("best.log")
  end
  def evaluateone(gene)
   collisions = 0
   v = {}
   (0...8).each { |i|
    collisions += 1 if v[gene[i]]
    v[gene[i]] = ''
   }
   v = {}
   (0...8).each { |i|
    collisions += 1 if v[i+gene[i]]
    v[i+gene[i]] = ''
   }
   v = {}
   (0...8).each { |i|
    collisions += 1 if v[i-gene[i]]
    v[i-gene[i]] = ''
   }
   if collisions == 0 then
    @solution = gene
   end
   # 1.0 / (1.0 + collisions)
   collisions
  end
  def evaluate
   @val = []
   @totalval = 0.0
   totalcollisions = 0.0
   best = 100.0
   (0...POPULATION).each { |i|
    collisions = evaluateone(@genes[i])
    @val[i] = 1.0 / (1.0 + collisions)
    @totalval += @val[i]
    totalcollisions += collisions
    best = collisions if collisions < best
   }
   File.open("average.log","a"){ |f|
    f.puts totalcollisions.to_f / POPULATION
   }
   File.open("best.log","a"){ |f|
    f.puts best.to_f
   }
  end
  
  def selectone
   r = rand(10000) / 10000.0
   v = 0.0
   (0...POPULATION).each { |i|
    if r >= v && r < v + @val[i] / @totalval then
     return @genes[i].dup
    end
    v += @val[i] / @totalval
   }
  end
  def dump
   (0..10).each { |i|
    puts @genes[i].join(' ')
   }
   puts "totalval = #{@totalval}"
  end
  def calc
   newgenes = []
   while newgenes.length < POPULATION do
    if rand(10000) < 6000 then # 交叉
     a = selectone
     b = selectone
     p1 = rand(8)
     p2 = rand(8)
     if p2 < p1 then
      tmp = p2
      p2 = p1
      p1 = tmp
     end
     (p1..p2).each { |i|
      tmp = a[i]
      a[i] = b[i]
      b[i] = tmp
     }
     newgenes << a
     newgenes << b
    elsif rand(10000) < 600 then # 突然変異
     a = selectone
     a[rand(8)] = rand(8)
     newgenes << a
    else
     newgenes << selectone
    end
   end
   @genes = newgenes
  end
 end
 queens = Queens.new
 while true do 
  queens.evaluate
  queens.dump
  queens.calc
  break if queens.solution
 end
 (0...8).each { |i|
  s = (0...8).collect { '.' }
  s[queens.solution[i]] = 'Q'
  puts s.join(' ')
 }