phetsims / natural-selection

"Natural Selection" is an educational simulation in HTML5, by PhET Interactive Simulations
GNU General Public License v3.0
3 stars 7 forks source link

Limited Food can occasionally lead to bunnies taking over the world #158

Closed oliver-phet closed 4 years ago

oliver-phet commented 4 years ago

I've now seen this happen twice testing the sim and I was quite surprised.

Initial conditions: Add Long Teeth Recessive mutation Check Limited Food Add a bunny

I'm not sure if it is intended to allow the simulation with identical initial conditions to lead to both (1) a steady-state small population and (2) bunnies taking over the world

image
oliver-phet commented 4 years ago

Seems like no bunnies died due of starvation towards the end of the log?

[Warning] 2310 console messages are not shown.
[Log] 84 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 51 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 28 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 48 (initialize-globals.js, line 636)
[Log] total dead bunnies = 920 (initialize-globals.js, line 636)
[Log] ====== Generation 141 ====== (initialize-globals.js, line 636)
[Log] 1 bunnies died of old age (initialize-globals.js, line 636)
[Log] 52 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 92 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 62 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 31 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 46 (initialize-globals.js, line 636)
[Log] total dead bunnies = 962 (initialize-globals.js, line 636)
[Log] ====== Generation 142 ====== (initialize-globals.js, line 636)
[Log] 0 bunnies died of old age (initialize-globals.js, line 636)
[Log] 48 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 92 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 57 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 27 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 54 (initialize-globals.js, line 636)
[Log] total dead bunnies = 998 (initialize-globals.js, line 636)
[Log] ====== Generation 143 ====== (initialize-globals.js, line 636)
[Log] 0 bunnies died of old age (initialize-globals.js, line 636)
[Log] 44 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 108 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 78 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 34 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 50 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1066 (initialize-globals.js, line 636)
[Log] ====== Generation 144 ====== (initialize-globals.js, line 636)
[Log] 0 bunnies died of old age (initialize-globals.js, line 636)
[Log] 40 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 100 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 64 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 26 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 60 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1116 (initialize-globals.js, line 636)
[Log] ====== Generation 145 ====== (initialize-globals.js, line 636)
[Log] 1 bunnies died of old age (initialize-globals.js, line 636)
[Log] 40 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 116 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 77 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 32 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 66 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1186 (initialize-globals.js, line 636)
[Log] ====== Generation 146 ====== (initialize-globals.js, line 636)
[Log] 1 bunnies died of old age (initialize-globals.js, line 636)
[Log] 44 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 128 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 81 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 39 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 73 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1263 (initialize-globals.js, line 636)
[Log] ====== Generation 147 ====== (initialize-globals.js, line 636)
[Log] 0 bunnies died of old age (initialize-globals.js, line 636)
[Log] 44 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 144 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 102 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 48 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 67 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1369 (initialize-globals.js, line 636)
[Log] ====== Generation 148 ====== (initialize-globals.js, line 636)
[Log] 0 bunnies died of old age (initialize-globals.js, line 636)
[Log] 52 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 132 bunnies were born (initialize-globals.js, line 636)
[Log] attempting to starve bunnies (initialize-globals.js, line 636)
[Log] 94 bunnies with long teeth died of starvation (initialize-globals.js, line 636)
[Log] 40 bunnies with short teeth died of starvation (initialize-globals.js, line 636)
[Log] total live bunnies = 65 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1451 (initialize-globals.js, line 636)
[Log] ====== Generation 149 ====== (initialize-globals.js, line 636)
[Log] 1 bunnies died of old age (initialize-globals.js, line 636)
[Log] 60 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 128 bunnies were born (initialize-globals.js, line 636)
[Log] total live bunnies = 192 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1392 (initialize-globals.js, line 636)
[Log] ====== Generation 150 ====== (initialize-globals.js, line 636)
[Log] 2 bunnies died of old age (initialize-globals.js, line 636)
[Log] 68 dead bunnies pruned (initialize-globals.js, line 636)
[Log] using bunnyRestRange=[6,10] for population=250 (initialize-globals.js, line 636)
[Log] 380 bunnies were born (initialize-globals.js, line 636)
[Log] total live bunnies = 570 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1326 (initialize-globals.js, line 636)
[Log] ====== Generation 151 ====== (initialize-globals.js, line 636)
[Log] 4 bunnies died of old age (initialize-globals.js, line 636)
[Log] 76 dead bunnies pruned (initialize-globals.js, line 636)
[Log] 1132 bunnies were born (initialize-globals.js, line 636)
[Log] Bunnies have taken over the world. (initialize-globals.js, line 636)
[Log] total live bunnies = 1698 (initialize-globals.js, line 636)
[Log] total dead bunnies = 1254 (initialize-globals.js, line 636)
amanda-phet commented 4 years ago

Yeah I noticed this about tough food as well. In theory, limited food and tough food should stabilize the population, but since it's a random percentage that gets killed I assumed I was just unlucky.

It looks like not enough bunnies are dying of old age, you're right! That seems very problematic..

pixelzoom commented 4 years ago

I've also seen all bunnies die using the same steps. It's definitely not going to be the same on each run. The percentage of bunnies killed by limited food or tough food is randomly chosen from the ranges [0.6,0.7] and [0.4, 0.7] respectively. So while the population will tend be somewhat stable, it's also possible that it may rebound or decline, depending on what random percentage happens to get applied to each generation.

If you want something that always results in a population that remains stable forever and ever, then this is not it. And I don't know how to achieve that.

I can see how having the bunnies take over the world with limited/tough food might be problematic. If you want to avoid that, then it can probably be accomplished by tweaking the existing ranges. Having all bunnies die sometimes doesn't seem as problematic.

pixelzoom commented 4 years ago

I should mention that scenarios involving wolves are also not reproducible. The percentage of bunnies killed by wolves is randomly selected for each generation from the range [0.34,0.4]. So 2 runs with the same initial conditions are likely to result in different outcomes.

amanda-phet commented 4 years ago

It's just odd because I used to rely on limited food or tough food to let the sim run for many generations. We may want to tweak the percentages.

Perhaps for limited food, we should do [0.6, 0.73] so the "average" kill rate is closer to 0.66. Is this going to be a problem with any multipliers? I don't think so, but please correct me if I'm wrong. This should lead to more long-term stability across many trials.

For tough food, we can nudge it up, to maybe [0.45,0.7] but I think it is less of a concern that the bunnies are stable in this scenario. In the Java version, tough food stabilized (and sometimes killed off) the population. However we don't have to exactly replicate that in this sim, since we have limited food to do that in the HTML5 sim.

@oliver-phet - thoughts?

oliver-phet commented 4 years ago

I think it is very problematic that the vast majority of Limited Food "runs" lead to a ~stable population of 6-12 bunnies, but once in a while leads to bunnies "taking over the world". It just doesn't make sense to me and feels broken. @pixelzoom did you see in the log I posted above that in generations 149-151 0(!) bunnies died of starvation. Surely there is something wrong there.

I know the sim is late in the development process, but I do wonder if Limited Food should affect the fertility of bunnies rather than mortality.

pixelzoom commented 4 years ago

I think it is very problematic that the vast majority of Limited Food "runs" lead to a ~stable population of 6-12 bunnies, but once in a while leads to bunnies "taking over the world". It just doesn't make sense to me and feels broken.

Agreed. Bunnies taking over the world while there is limited food seems wrong.

@pixelzoom did you see in the log I posted above that in generations 149-151 0(!) bunnies died of starvation. Surely there is something wrong there.

Thanks, I missed that note. I don't even see an "attempting to starve bunnies" message, so the food algorithm didn't get run. Are you by any chance running with query parameters, maybe something that is making the sim run too fast and skip over the "food" interval of the clock?

I know the sim is late in the development process, but I do wonder if Limited Food should affect the fertility of bunnies rather than mortality.

I don't think we should go here. This would also mean that there would be no way to see data for food, since it would be combined with birth+death at 12:00 on the generation clock.

oliver-phet commented 4 years ago

Thanks, I missed that note. I don't even see an "attempting to starve bunnies" message, so the food algorithm didn't get run. Are you by any chance running with query parameters, maybe something that is making the sim run too fast and skip over the "food" interval of the clock?

I'm using ?ea&brand=phet&secondsPerGeneration=1&log and for some of these test I was holding down the 'Fast Forward' button. If that button allows the sim to run too fast and skip over important events, I think we should revisit the behavior of that button or see if things could be changed so that the food interval can't be skipped?

amanda-phet commented 4 years ago

Something very buggy is happening in @oliver-phet 's case above. The population graph looks really really strange. Death from starvation happens a third of the way through the generation, and you can see the graph is not showing that.

When I run 1.0.0-rc.1 with log turned on (in Chrome), the population remains pretty stable for under 30 generations, and then it slowly starts to increase. I would like to change the percentages, as noted in https://github.com/phetsims/natural-selection/issues/158#issuecomment-668910002, to allow the population to hopefully stabilize for longer, but this issue should probably focus on the strange bug in the original post.

pixelzoom commented 4 years ago

When I run 1.0.0-rc.1 with log turned on (in Chrome), the population remains pretty stable for under 30 generations, and then it slowly starts to increase.

@amanda-phet are you running with secondsPerGeneration query parameter, or using the fast-forward button?

pixelzoom commented 4 years ago

I'm assuming that this is a prerequisite for the 1.0 prototype, for https://github.com/phetsims/QA/issues/522. So labeling as "blocks-sim-publication". If that's incorrect, please let me know asap.

amanda-phet commented 4 years ago

@amanda-phet are you running with secondsPerGeneration query parameter, or using the fast-forward button?

I've run a number of trials for this and I think the issue is the range. If the average random value is closer to 0.66 then over a long period of time I'd expect the population to remain stable. Since the average random value is currently 0.65, I would expect the population to slowly increase over time, which is exactly what is happening.

I never reproduced Oliver's buggy graph or skipping over the starvation period. I occasionally used the fast-forward button and ?log but that's it.

I'm assuming that this is a prerequisite for the 1.0 prototype, for phetsims/QA#522.

Correct. I see this issue covering two things at this point. (1) Update the percentage values so over time the population is more likely to be stable (but has random variation, and that's ok) (2) Identify the steps to reproduce @oliver-phet 's bug.

pixelzoom commented 4 years ago

@oliver-phet's bug is very likely due to https://github.com/phetsims/natural-selection/issues/167.

pixelzoom commented 4 years ago

@amanda-phet in https://github.com/phetsims/natural-selection/issues/158#issuecomment-668910002 you proposed changes for query parameters limitedFoodPercentToKill and toughFoodPercentToKill:

Perhaps for limited food, we should do [0.6, 0.73] ...

For tough food, we can nudge it up, to maybe [0.45,0.7] ...

I went ahead and changed to those values in the above commit. Let me know if I misunderstood.

pixelzoom commented 4 years ago

Something very buggy is happening in @oliver-phet 's case above. The population graph looks really really strange. Death from starvation happens a third of the way through the generation, and you can see the graph is not showing that.

This is because he was running the clock at an extreme speed. The clock only snaps to 12:00, it does not snap to 4:00 (food) or 8:00 (wolves) -- but it will, see #170. There was such a huge time-step that food was actually applied much later in the clock cycle that it should have been.

pixelzoom commented 4 years ago

Food.starveBunnies has been heavily refactored. I've moved things that we discovered in this issue to #169, where we'll sanity-check the new implementation. So closing this issue.