# 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

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

all_box = amount_of_box
(1..@count).each { |count|
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 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]]
```

#### 実行結果

```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難すい(´･ω･`)