読者です 読者をやめる 読者になる 読者になる

牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

Rubyで書いてみた〜人工知能ジェネテックアルゴリズム

Ruby

Ruby on Railsをやる前にRubyの勉強に、なぜか評判の良かった『『マッチ箱の脳』人工知能ジェネテックアルゴリズムをPythonでやってみた - 牌語備忘録 - pygo』を今度はRubyで書いてみた。

Ruby

若干修正

# *-# -*- coding: utf-8 -*-
# Genetic Algorithm
# ga.rb

class GeneticAlgorithm
  def initialize
    @stick_num = 10
    @kind_num = 3
    @amount = 10
    @count = 200
    @point = 10
  end

  def matchbox num = @stick_num, kind = @kind_num
    seq = []
    (1..num).each {|x| seq << (rand kind) + 1}
    seq
  end

  def amount_of_box amount = @amount
    seq = []
    (1..amount).each {|x| seq << matchbox}
    seq
  end
  
  def del_repetition_new_add box_seq
    box_seq.uniq!
    if box_seq.length < @amount then
      box_seq << (amount_of_box @amount - box_seq.length)
    else
      box_seq
    end
  end
  
  def rating ans, box_seq
    point_lst = []
    box_seq.each { |box| 
      point = 0
      (1..ans.length).zip(ans, box).each { |a|
        if a[1] == a[2] then
          point += @point
        end
      }
      point_lst << [point, box]
    }
    point_lst.sort.reverse!
  end
  
  def parent rate_seq
    [rate_seq[0][1], rate_seq[1][1]]
  end
  
  def mutation kids_seq
    psition = rand kids_seq.length
    if psition < 10 then
      change = lambda { |x| x < 3 ? x + 1 : x - 2 }
      kids_seq[psition] = change[kids_seq[psition]]
    end
    kids_seq
  end
  
  def recombination parent_seq
    crossing = rand @stick_num
    kid_a = parent_seq[1][0,crossing] + parent_seq[0][crossing, @stick_num - 1]
    kid_b = parent_seq[0][0,crossing] + parent_seq[1][crossing, @stick_num - 1]
    [(mutation kid_a), (mutation kid_b)]
  end
  
  def answer_display ans
    all_box = amount_of_box
    (1..@count).each { |count|
      dd_box = del_repetition_new_add all_box
      rate_seq = (rating ans, dd_box).dup
      puts "Generation: %d" % count
      p rate_seq
      all_box = rate_seq.map{|x|x[1]}
      parent_seq = parent rate_seq
      top = all_box[0,2]
      tail = all_box[2, @stick_num - 3]
      all_box = (recombination parent_seq) + tail + top
      if rate_seq[0][0] == 100:
          break
      elsif count == @count then
        puts "break: limit over %d Generation!" % count
      end
    }
  end
  
end

ga = GeneticAlgorithm.new
answer = [3, 1, 2, 2, 2, 3, 1, 3, 2, 1]
#test
#ga.matchbox
#p ga.amount_of_box
#p ga.del_repetition_new_add ga.amount_of_box
#rate_lst = ga.rating answer, ga.amount_of_box
#p rate_lst
#p ga.parent rate_lst
#p ga.mutation [3, 1, 2, 2, 2, 3, 1, 3, 2, 1]
#p ga.recombination [[3, 2, 1, 1, 3, 3, 2, 2, 2, 1],[2, 1, 3, 2, 3, 1, 1, 1, 2, 1]]
ga.answer_display answer

実行結果

irb(main):342:0> Generation: 1
[[60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 1, 1, 2, 1, 3, 1, 2, 3, 1]], [40, [3, 1, 3, 1, 1, 1, 2, 3, 3, 1]], [30, [2, 3, 2, 3, 3, 1, 3, 3, 3, 1]], [30, [2, 3, 2, 3, 1, 3, 2, 2, 2, 2]], [20, [2, 3, 3, 2, 1, 2, 1, 1, 1, 3]], [20, [2, 1, 3, 1, 2, 2, 3, 2, 1, 2]], [10, [2, 3, 3, 3, 3, 2, 3, 2, 2, 2]], [10, [1, 1, 3, 1, 3, 2, 2, 2, 1, 2]]]
Generation: 2
[[60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 1, 1, 2, 1, 3, 1, 2, 3, 1]], [40, [3, 1, 3, 1, 1, 1, 2, 3, 3, 1]], [30, [2, 3, 2, 3, 3, 1, 3, 3, 3, 1]], [30, [2, 3, 2, 3, 1, 3, 2, 2, 2, 2]], [20, [2, 3, 3, 2, 1, 2, 1, 1, 1, 3]], [20, [2, 1, 3, 1, 2, 2, 3, 2, 1, 2]], [10, [2, 3, 3, 3, 3, 2, 3, 2, 2, 2]]]
Generation: 3
[[70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 1, 1, 2, 1, 3, 1, 2, 3, 1]], [40, [3, 1, 3, 1, 1, 1, 2, 3, 3, 1]], [30, [2, 3, 2, 3, 3, 1, 3, 3, 3, 1]], [30, [2, 3, 2, 3, 1, 3, 2, 2, 2, 2]], [20, [2, 3, 3, 2, 1, 2, 1, 1, 1, 3]]]
Generation: 4
[[70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [1, 1, 1, 2, 1, 3, 1, 2, 3, 1]], [40, [3, 1, 3, 1, 1, 1, 2, 3, 3, 1]], [30, [2, 3, 2, 3, 3, 1, 3, 3, 3, 1]]]
Generation: 5
[[70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [50, [3, 3, 1, 2, 3, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [1, 1, 1, 2, 1, 3, 1, 2, 3, 1]]]
Generation: 6
[[70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [60, [1, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 3, 1, 2, 2, 2, 1, 1, 2, 2]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]], [50, [3, 1, 3, 1, 3, 1, 1, 1, 2, 1]], [50, [1, 3, 1, 2, 2, 2, 1, 1, 2, 1]]]
Generation: 7
[[70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 1, 1, 2, 2, 2, 2, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [60, [1, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 3, 1, 2, 2, 2, 1, 1, 3, 1]], [50, [3, 3, 1, 2, 2, 2, 1, 1, 2, 2]], [50, [3, 1, 3, 1, 3, 2, 1, 3, 2, 3]]]
Generation: 8
[[70, [3, 1, 1, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 1, 1, 2, 2, 2, 2, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [60, [1, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]], [50, [3, 3, 1, 2, 2, 2, 1, 1, 3, 1]]]
Generation: 9
[[80, [3, 1, 2, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 2, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 2, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [60, [1, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 2, 1, 1, 2, 1]], [50, [3, 3, 1, 2, 3, 1, 1, 3, 2, 3]]]
Generation: 10
[[80, [3, 1, 2, 2, 2, 2, 1, 2, 2, 1]], [80, [3, 1, 1, 2, 2, 3, 1, 2, 2, 1]], [70, [3, 1, 2, 3, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 2, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 2, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 1, 1, 3, 1]], [60, [1, 1, 1, 2, 2, 2, 1, 1, 2, 1]]]
Generation: 11
[[90, [3, 1, 1, 2, 2, 3, 1, 3, 2, 1]], [80, [3, 1, 2, 2, 2, 2, 1, 2, 2, 1]], [80, [3, 1, 1, 2, 2, 3, 1, 2, 2, 1]], [70, [3, 1, 2, 3, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 2, 2, 2, 2, 2, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]], [60, [3, 2, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 1, 1, 2, 2, 2, 2, 1, 2, 1]]]
Generation: 12
[[100, [3, 1, 2, 2, 2, 3, 1, 3, 2, 1]], [90, [3, 1, 1, 2, 2, 3, 1, 3, 2, 1]], [80, [3, 1, 2, 2, 2, 2, 1, 2, 2, 1]], [80, [3, 1, 1, 2, 2, 3, 1, 2, 2, 1]], [70, [3, 1, 2, 3, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 2, 2, 2, 2, 2, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 3, 1, 2, 3, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 2, 2, 1]], [70, [3, 1, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 2, 1, 1, 2, 1]], [60, [3, 3, 1, 2, 2, 1, 1, 3, 2, 3]]]
true
irb(main):343:0> 

ぎゃぁRuby難すい(´・ω・`)
無理矢理でっち上げた感じになっちゃった(||゚Д゚)