どういうわけかRubyの持つクラスを割り当てません
-
19-09-2019 - |
質問
は、実行時には、私のコードは、多くの場合、メソッドのmate
のための未定義のメソッドエラーに入って来ます。私の知る限り理解できるよう、Person
は何とかいつかコードのexucutionに沿って亀裂をすり抜けると、それに割り当てられallele
を持たない管理します。
コード(免責事項ではなく、最高の書式設定):
class Allele
attr_accessor :c1, :c2
def initialize(c1, c2)
@c1 = c1
@c2 = c2
end
#formats it to be readable
def to_s
c1.to_s + c2.to_s
end
#given Allele a
def combine(a)
pick = rand(4)
case pick
when 0
Allele.new(c1,a.c1)
when 1
Allele.new(c1,a.c2)
when 2
Allele.new(c2,a.c1)
when 3
Allele.new(c2,a.c2)
end
end
end
class Person
attr_accessor :allele, :male
def initialize(allele,male)
@allele = allele
@male= male
end
#def self.num_people
#@@num_people
#end
def to_s
"Allele:" + allele.to_s + " | Male:" + male.to_s
end
def male
@male
end
def allele
@allele
end
def mate(p)
if rand(2) == 0
Person.new(allele.combine(p.allele),true)
else
Person.new(allele.combine(p.allele),false)
end
end
end
male_array = Array.new
female_array = Array.new
male_child_array = Array.new
female_child_array = Array.new
# EVENLY POPULATE THE ARRAY WITH 5 THAT PHENOTYPICALLY MANIFEST TRAIT, 5 THAT DON'T
# AND 5 GIRLS, 5 GUYS
pheno_dist = rand(5)
#make guys with phenotype
pheno_dist.times { male_array << Person.new(Allele.new(1,rand(2)),true) }
#guys w/o
(5-pheno_dist).times { male_array << Person.new(Allele.new(0,0),true) }
#girls w/ pheno
(5-pheno_dist).times { female_array << Person.new(Allele.new(1,rand(2)),false) }
#girls w/o
pheno_dist.times { female_array << Person.new(Allele.new(0,0),false) }
puts male_array
puts female_array
puts "----------------------"
4.times do
#mates male with females, adding children to children arrays. deletes partners as it iterates
male_array.each do
male_id = rand(male_array.length) #random selection function. adjust as needed
female_id = rand(female_array.length)
rand(8).times do
child = male_array[male_id].mate(female_array[female_id])
if child.male
male_child_array << child
else
female_child_array << child
end
end
male_array.delete_at(male_id)
female_array.delete_at(female_id)
end
#makes males male children, females female children, resets child arrays
male_array = male_child_array
female_array = female_child_array
male_child_array = []
female_child_array = []
puts male_array
puts female_array
puts "----------------------"
end
すぐに間違って見えますか?
解決
、あなたが反復され、その上のアレイから削除するべきではない。
もう一つの問題は、「4倍速が行う」を開始し、あなたのループです。時には女性の配列はそうサイズ0を返し、空です。ランド(0)ランダムフロート> = 0となる<次いで嵌合するように渡される空female_array返すゼロ、上の配列のインデックスとしてそれを使用する1。
しかし、それ間違ったよりも多くのがあります。あなたは、各使用male_arrayを反復するが、その後ランダムに男性を選びました。それは、いくつかの男性が複数回交尾することができます。他のすべてではありません。同様に、一部の女性は、他のすべてではない、チームメイトと各反復で複数回を再現してもらいます。あなたの意思ということですか?
のは、最初と同じ配列で男性と女性のすべてを保つことを検討してみましょう。これは、物事を単純化します。あなたは時々、すべての男性と、時々、すべての女性を見つける必要がないのでしかし、我々はそのためのメソッドを作ります:
def males(population)
population.find_all do |person|
person.male?
end
end
def females(population)
population.find_all do |person|
person.female?
end
end
男性と女性がランダムにペアリングする必要がある場合は、より生物学的に正確であるだろうが、誰もが一度以上かみ合うようになっていません。これは非常に簡単です:
def random_pairs(males, females)
males.shuffle[0...females.size].zip(females.shuffle)
end
そして、人口の再生が簡単に、なります:
def make_children(male, female)
# return an array of children
end
def reproduce(population)
children = []
random_pairs(males(population), females(population)).each do |male, female|
children << make_children(male, female)
end
children
end
このような機能を持つこと、そして生殖の4サイクルを行うことは、このような単純なものでしょう
people = # ... generate your initial list of people of all sexe.
4.times do
people = reproduce(people)
end
何の機能がそれに渡された引数を変更していないので、あなたは副作用との支障もありません。
詳細は「メス」、「random_pairs」、人口ファーストクラスのオブジェクト作りと機能「男性」を動かすたとえば、オブジェクト指向のスタイルで行うことができ、その中に「再現します」。私は読者の練習として残しておきましょう。
他のヒント
あなたは各未定義た行動で反復され、アレイから削除します。通常、アドバイスは、Array#のdelete_ifを使用することですが、私はあなたがこのケースに入れて使用するかどうかはわかりません。