我是Ruby的初学者,编写了一个非常简单的程序来模仿遗传学,但输出适应性总是保持在15-24左右。这个程序最终是否应该达到32的适应度然后输出呢?
已编辑的代码:
#!/usr/bin/env ruby
class Animal
attr_reader :genes
def initialize (genes=[])
@genes = genes
end
def random_chromosome
@genes = Array.new(32).collect {|x| rand 2}
self
end
def calc_fitness
@genes.inject(0){|i, v| next i + v if v == 1; i}
end
def mutate
2.times { @genes[rand 32] = rand 2}
end
def mate(other)
@genes = (@genes[0...16] + other.genes[0...16])
mutate
self
end
def is_spartan?
@genes == (Array.new.fill 1)
end
end
class Generation
attr_reader :animals
def initialize (animals=[], gen_size = 10)
@animals = animals
@gen_size = gen_size
end
def seed
@animals = Array.new(@gen_size).collect {Animal.new.random_chromosome}
end
def mate
@animals = [].tap {|a|
@gen_size.times{
a << @animals[rand @gen_size].mate(@animals[rand @gen_size])
}
}
end
def alphas
@animals.sort! {|a, b| b.calc_fitness <=> a.calc_fitness}.first(@gen_size)
end
def include_spartans?
@animals.include? Array.new(32).fill 1 #perfect genes
end
def output
@animals.each {|an| print "#{an.genes.join}: #{an.calc_fitness}\n"}
end
end
NUM_OFFSPRING = 10
gen = Generation.new
gen.seed
i = 0
loop do
i += 1
if gen.include_spartans? #end if there are any perfect genes
puts "Members have reached spartan status!"
break
end
puts "*** ALPHAS FROM GENERATION: #{i}***"
gen.mate
gen.alphas
gen.output
sleep(0.2)
end
示例输出
* ALPHAS FROM GENERATION:1 *
11101101011111101001010110101101:21 10111111111100000110000101011001:18 11101111110110111100001100000001:18 11000101101111010110000111011001:18 11101111110110111100001100000001:18 10111111111100000110000101011001:18 11000101101111010110000111011001:18 11000011010000011001101111101101:17 01100001110110011000101111110000:16 10001010111110001100001101000001:14
* ALPHAS FROM GENERATION:2 *
11101111110110101110111111010011:24 01100001110110011110111111011110:21 11000101101111011100001101000001:16 10001010111110000110000111011001:16 11000101101111011100001101000001:16 10111111010100001000001101100001:15 10111111010100001000001101100001:15 10111111010100001000001101100001:15 10111111010100001000001101100001:15 10111111010100001000001101100001:15
* ALPHAS FROM GENERATION:3 *
11101111111110101011111111000000:22 11101111111110101011111111000000:22 10111111110000001110011111011010:20 10111111110000001110011111011010:20 10111111110000001110011111011010:20 11000101101111011000101011111000:18 11000101101111011000101011111000:18 11000101101111011000101011111000:18 11000101101111011000101011111000:18 01100001110100011011111101010000:16
答案 0 :(得分:2)
Patru让你走上正轨。这里解决了一些问题:https://gist.github.com/matt-glover/9700810
原始代码不使用NUM_OFFSPRING
。即使它确实这样做也会将10只动物拉回为alphas(或尝试无论如何),所以NUM_OFFSPRING
确实应该更大,以便看到alpha选择显示出任何影响。
原始代码对动物进行排序以找到alphas但实际上并不保留前10名。相反,它返回方法调用中的前10名,但存储完整排序的@animals
数组。
交配需要产生新的Animal
,否则可以在交配阶段一次又一次地选择相同的动物。原始代码仅保留结果对中存储在第一只动物中的最后交配尝试的结果。这最终消灭了动物库中的单个动物在动物列表中出现多次,并且只反映了最后交配尝试迭代的基因。
最后,include_spartans?
检查需要按照示例中的方式绘制基因图,或者调用每只动物并在那里进行检查。旧代码正在检查动物实例与一组数据。