Here’s why: I was trying to fix a problem with a plugin on this site and there seems to be a cache I can’t figure out, which stops me from doing what I want to do. So, just to get out of that frustrated mindset I decided to do some other light coding instead. For some reason, I had also been thinking about this rule we had in our D&D games back in early 90s, so why not combine these two?
The rule was this: If two characters procreate, the child has all the stats of the two parents averaged and rounded up. So, if we have a parent with strength of 13 and another with a strenght of 10, the child would have a strength of 13 + 10 / 2 = 11.5 rounded up to 12. At the time I didn’t really notice this, but that does seem a little problematic.
But hey, let’s test this out. With code!
Here’s the problem: Just simulating this in my head, I came up with two conclusions. First, the variance is going to fall quickly, which is kind of obvious. Second, everything is going to end up as 13 in the end. WHy is this a problem? I do fear that I might have somehow let my assumptions guide my coding, as my code does show that by generation 12, every stat would actually be exactly 13. (I’m not going to go into a discussion on how to name generations, but I have started with generation 0, so you could say by generation 13 everything will be 13, but that’s up to you. I remember this being a rabbithole back in the day, but I don’t think it’s actually worth it. I just used a coding convention of starting from 0.)
Otherwise, my couplings are purely random, which isn’t how this works in real life. Also, there is a chance of incestious couplings, but I’m not going to bother checking for that. In a population of 100,000, I don’t think it’s going to be meaningful. There’s a small chance of siblings procreating and probably a pretty high chance of cousins doing so, but I don’t think those are going to skew the results. Also, I do assume each coupling produces exactly one boy and one girl (which show another problem with this rule: all children are identical).
Here’s the code (for some reason I can’t get the indentations to work on the page, so I just added some whitespace, but it doesn’t look very good):
function _3d6()
{
return mt_rand(1, 6)+mt_rand(1, 6)+mt_rand(1, 6);
}
mt_srand(microtime(true));
$males = array();
$females = array();
$boys = array();
$girls = array();
$no_of_people = 100000;
$generations = 20;
for($i=0; $i<$no_of_people; $i++)
{
$males[$i] = _3d6();
$females[$i] = _3d6();
}
for($j=0; $j<$generations; $j++)
{
$male_sum = 0;
$female_sum = 0;
$children_sum = 0;
$male_sum_squared = 0;
$female_sum_squared = 0;
$children_sum_squared = 0;
for($i=0; $i<$no_of_people; $i++)
{
$boys[$i] = ceil(($males[$i] + $females[$i]) / 2);
$girls[$i] = ceil(($males[$i] + $females[$i]) / 2);
$male_sum += $males[$i];
$female_sum += $females[$i];
$children_sum += $boys[$i];
$children_sum += $girls[$i];
$male_sum_squared += ($males[$i] * $males[$i]);
$female_sum_squared += ($females[$i] * $females[$i]);
$children_sum_squared += ($boys[$i] * $boys[$i]);
$children_sum_squared += ($girls[$i] * $girls[$i]);
}
shuffle($boys);
$males = $boys;
shuffle($girls);
$females = $girls;
echo "<br>generation ".$j."<br>";
echo ($male_sum_squared - ($male_sum * $male_sum) / $no_of_people) / ($no_of_people - 1)."<br>";
echo ($female_sum_squared - ($female_sum * $female_sum) / $no_of_people) / ($no_of_people - 1)."<br>";
echo ($children_sum_squared - ($children_sum * $children_sum) / ($no_of_people * 2)) / (($no_of_people * 2) - 1)."<br>";
echo ($male_sum / $no_of_people) ."<br>";
echo ($female_sum / $no_of_people) ."<br>";
echo ($children_sum / ($no_of_people * 2)) ."<br>";
}
and here’s the results. The format is
variance for males
variance for females
variance for their children
average for males
average for females
average for children
generation 0
8.760640501505
8.7496272561726
4.4591457453287
10.51507
10.49951
10.75752generation 1
4.4591680412804
4.4591680412804
2.2920820723104
10.75752
10.75752
11.00891generation 2
2.2920935328353
2.2920935328353
1.2115594721974
11.00891
11.00891
11.25816generation 3
1.2115655300553
1.2115655300553
0.66460091300456
11.25816
11.25816
11.5079generation 4
0.66460423604236
0.66460423604236
0.39474175610878
11.5079
11.5079
11.75776generation 5
0.3947437298373
0.3947437298373
0.23777411327058
11.75776
11.75776
11.99734generation 6
0.23777530215303
0.23777530215303
0.17508862584314
11.99734
11.99734
12.17864generation 7
0.17508950129502
0.17508950129502
0.22573096505483
12.17864
12.17864
12.34306generation 8
0.22573209372094
0.22573209372094
0.24535135065676
12.34306
12.34306
12.56819generation 9
0.24535257742578
0.24535257742578
0.15111566397831
12.56819
12.56819
12.81446generation 10
0.15111641956419
0.15111641956419
0.03303052515261
12.81446
12.81446
12.9658generation 11
0.033030690306888
0.033030690306888
0.0012883423417204
12.9658
12.9658
12.99871generation 12
0.0012883487834965
0.0012883487834965
0
12.99871
12.99871
13generation 13
0
0
0
13
13
13
Obviously, the next generations will just repeat that, so I cut them out.