Now that’s evolution!
Remember six? She’s a small population of the digital creatures I implemented, called “figures.” Six has a population size of 6, thus the name, and no matter how much room there is, no matter what the maximum population size happens to be, she always has a population size of 6 figures. Meanwhile, each figure will make one copy of itself and then die. There’s a constant stream of figures being born and copying themselves and dying, but the population size never changes/ it’s always 6.
I put six in a larger world. There was enough room for 200 figures. As expected, she still stayed at a 6 figure pop size. Then I started mutation.
Like I said in the last entry, the mutations are nasty, and often kill off an entire population. If that happened, six would be reloaded, back where she started before all this “mutation” business started going on, and do it all over again.
The notion was to see if six could evolve into a population that grows, instead of just holding steady. I set it up so it would beep at me when the population size reached 200, and pause the system so I could take a look at what six had become. I had no clue how long the experiment would run, or if six could be mutated into a growing population at all. I was all set to leave it running in the background while I did any&everything else.
The first time the computer beeped at me, was after 49 seconds.
Hmmm… that was suspiciously quick.
Once the population reaches the maximum population size, in this case 200 figures, the system will kill the oldest figure whenever a new figure is born. Before, six did that herself. She has a built in limit on her population. She makes sure that one figure dies for each figure that is born, regardless of what the system might have to say about it. That was before she was mutated. Now, she’s grown to 200 figures, and it’s the system that decides which figure dies and when.
I continued the run, and all the figures died. The next time my computer beeped at me was fifty-something minutes later. Again, that population couldn’t survive once it hit the maximum population size limit. Another run, and more than an hour later, the same thing happened.
To get passed the populations that couldn’t make any more children once they were too crowded, I set it up so that it would beep at me when the population was at 200 figures, and had made a million new figures after the maximum population size had been reached. The next couple of runs gave me populations that would die right after making a million children. It hit me that the population may have been the kind I was looking for, but somewhere along the long run of making a million more figures, some mutation was making them unstable, maybe even right before the beep. I changed things so that if a population was at or near the maximum population size, if(popSize>=maxPopSize-3), mutations wouldn’t happen, mutate=false.
It ran for hours, beeping at me now and again. Along the way, I’d sometimes take a look at what the current run was up to. Sometimes, it was interesting enough to pause the system, and save the population to look at later. I ended up with several populations, all mutated versions of six, each with their own little quirks.
Sixty-one is a population much like 6. The population is at 61 figures, and stays there. She is also very resistant to mutations. I saved her because I looked at what was happening, and noticed that the population size had been steady at 61 figures for a while. I paused the system, save them, and then started it back up again. Sixty-one ran for well over an hour, absorbing hundreds of mutations. Every now and then, the population would shrink by one or two figures. Eventually, the mutations whittled the population down to zero, and the system stuck in a new copy of 6, starting from scratch. I reloaded and ran sixty-one without mutations active, and that’s when I found out that she’ll hold steady at a pop size of 61, if people will just leave her alone to get on with it.
Unsteady0 and unsteady1 are twins. I saw a population that was at 190. I thought it might be on the way to dying off, but it jumped back up to 200. Then, it dipped back down to 190. I saved it. After the system ran for a while longer, I noticed a few more mutations had happened, but the population was still acting the same. I saved it again.
When I ran unsteady0 without mutations later, I found out that the population size fluctuates between the maximum size, and a low of 190. I put it in a much larger realm, with a max pop size of 2,000. I wanted to see what would happen. The population expanded to 2000, held steady for a time, and then dwindled down to 0. Once it began to die back, no new figures were born.
Finally, we have 6large. This is a 200 figure population that will expand when given more room, and continue to make new figures once the maximum population is reached, without dying off on me. It’s exactly what I hoped that 6 could evolve to. 6large is slow. Slow to grow in population size, and slow to make new figures. In fact, all of them, 6 and her progeny are slow when compared to other populations that can make babies much faster, using far fewer commands.
After getting 6 to evolve in the direction I wanted, I decided to see if I could turn an unstable population into a stable one. Originally I was going to use u.pop. U has 200 figures in his population, in a realm with 300 slots and a maximum population size of 200. He can only make 700,000 new figures before every last figure dies. It was my hope that mutation might help u figure out how to make as many new figures as one could want. The trouble was that u is slow. It takes 40 minutes from the start of a run until u’s figures all die. After the first couple of runs, I got impatient, so I dug around for a different unstable population to work with.
I found after13.pop. This population is left over from an earlier experiment. There are 20 figures in a realm with 30 slots and a max pop size of only 20. Like u, after13 makes around 800,000 baby figures and then everybody dies. The difference is that after13 is done in between ten to fifteen minutes.
Like with six, after13 is loaded, and run while being mutated. If all the figures die out, after13 is reloaded into the realm and both run and mutated again. Like with six, I set it up so that mutations would stop if a population looked promising. This time, instead of turning off mutation when the population was close to the maximum population size, mutation would be deactivated if the mutated form of after13 had managed to make 500,000 baby figures or more, if(longest>=500,000) mutate=false. Once after13 made a million new figures, the system would beep at me and pause so I could take a looksee at what had been wrought.
You’ll notice that after13, even without being mutated, could already make more than 500,000 new figures. As I expected, several populations would reach the million mark, but would turn out to be unable to get much further. I expected it, and judging by what I’d seen while six evolved into 6large, I expected I’d have to do several runs before a population was able to make millions of new figures without dying from it.
The first time it beeped, I saved the population to after13s.pop, the s in the new file name stood, in a burst of optimism, for “stable.” Shutdown the system, deactivate mutation entirely, reload the recently saved after13s, and run it again. The first such saved population made a little more than 555,000 figures before everyone died. That was worse than the original. The second one only made a couple hundred thousand, even worse. I lost track of how many runs I made and how much time it took, but eventually…
I sat down at my computer, after hearing a happy beep sound and looking at the output. Once again, the population had reached a million figures. Running on auto, I saved the population to after13s, all set to test it. What I’d forgotten, was that I had just done that. After13s had just managed to make a million figures without any sign of being unstable, but I’d unthinkingly saved it like it had just been generated. I’d forgotten that this was a final test. With a shrug and a couple crossed fingers, I did the test again. Again, after13s managed to make another million babies without dying off. I didn’t mean to test it up to two-million, but that’s what happened, and she passed said test. Once again, the system had evolved a population in the direction I’d hoped for, changing an unstable population into a stable one.
Directed evolution has happened, even with a nasty, over deadly version of mutation
I’m somewhat torn. On the one hand, I’d like to experiment with changing probabilities and different types of mutation. On the other hand, it already works. On the gripping hand, I really need to get my code ready for release, a tedious but necessary chore.
For now, I’m quite pleased. I wanted a tunable emergent system, and now I’ve got one!