#--------randomize by time------------------------
def rand(k)
millis().to_i % k
end
#------------------------------------
class Genes
def initialize(gene_count=10, quiz_count=10)
@generation = 1 # first genes
@quiz = Quiz.new(quiz_count) # 10 quiz
p @quiz
while max == quiz_count
@genes = []
#------ first answer (@genes)---------
gene_count.times { |i| @genes << Gene.new(quiz_count) }
mark()
sort()
end
end
def start
while max < @quiz.count
yield(@generation, @genes, max, min, average)
next_genration()
mark()
sort()
end
yield(@generation, @genes, max, min, average)
end
def mark
@genes.length.times { |i| @genes[i].score = @quiz.mark(@genes[i].ans) }
end
def sort # -------------sort by score
@genes.sort! { |a, b| a.score <=> b.score }.reverse!
end
def next_genration
@generation += 1 # next answer genes
pair = [] # pair
pair << @genes[0]
pair << @genes[1]
pair = breed(pair) # next baby
@genes[@genes.length - 2] = pair[0]
@genes[@genes.length - 1] = pair[1]
end
#------- parents to baby ----------------
def breed(parents)
c = parents[0].count #
children = [Gene.new(c), Gene.new(c)]
cross = rand(c - 1) #
c.times do |i|
n = (i < cross) ? 0 : 1
children[0].ans[i] = parents[(0+n)%2].ans[i] # most score
children[1].ans[i] = parents[(1+n)%2].ans[i] # second score
end
#--- mutation baby -------
mutation = rand(c)
children[0].ans[mutation] = rand(3) if mutation < c
mutation = rand(c)
children[1].ans[mutation] = rand(3) if mutation < c
children
end
def max
#---if @genes==true then @genes[0].score else @quiz.count
@genes ? @genes[0].score : @quiz.count
end
def min
#---if @genes==true then @genes[(@genes.length-1)].score else 0
@genes ? @genes[(@genes.length - 1)].score : 0
end
def average
sum = 0
@genes.each { |x| sum += x.score } #@genes score sum
sum / @genes.length # avg
end
end
#------ Gene answer-------------------------------------------------
class Gene
def initialize(count)
@count = count
@ans = []
@count.times { |i| @ans << rand(3) }
end
attr_accessor :score
attr_reader :ans
attr_reader :count
end
#-------- score -------------------------------
class Quiz < Gene
def mark(ans)
score = 0
@count.times { |i| score += 1 if @ans[i] == ans[i] }
score
end
end
#--------------------------------
g = Genes.new
g.start do |generation, genes, max, min, average|
p generation
p max
10.times do |i|
print genes[i].score
p genes[i].ans
end
# break if gets =~ /x/
end