The last couple of weeks of Web Critters development have been among the most fascinating and intellectually challenging to date.  After nailing down the implementation of a level one ECHO simulation and observing the agents in my little complex adaptive system in action I set about trying to understand exactly what they were and how they acted.

The first step in that process was to model the concept of a “Species” that could stand apart from the actual agents.  My first implementation of species, while technically correct, absolutely annihilated the performance of the simulation and leaked memory like a sieve.  I was suddenly unable to run more than 3500 generations, and that required an abysmal hour of time (instead of 60 seconds as it had previously taken).

It took a couple of days of analyzing the state of Web Critters via WinDbg and SOS (memory inspection tools) before I figured out the source of the sudden slowdown.  My species tracked their predators and prey, and although I removed extinct species from the internal list of species I was tracking, they were retained in the predators/prey lists of other extinct  species, which in turn were linked to even more recent species, and so on – all the way up to the current generation in most cases.  Despite being lightweight, there were so many Species objects in memory that the simulation was crushed under the load; evolutionary algorithms, like those at the core of Web Critters, produce an enormous number of novel variations.

A world of herbivores

With the memory problems out of the way I was able to begin properly analyzing the population of the Web Critters simulation, and the results were unexpected:  although there was initially a good mix of herbivores (diet = 90% resource nodes), omnivores (diet = 11%-89% resource nodes), and carnivores (diet = 0-9% resource nodes), by generation 5000 – about one minute into a simulation – the carnivores and omnivores had all gone extinct and from that point forward I would rarely see less than one hundred percent herbivores.

This both puzzled and worried me because an ECHO simulation should, in theory, be capable of supporting a diverse range of species that are interdependent.  While not strictly mimicking nature, Web Critters should be able to approximate the relationships that it contains.

It took literally days of experimentation and thought to puzzle out the root source of the problem, however I came up with a good explanation of how a simulation progressed, and why these circumstances led to uniform herbivores.

  1. Initially the simulation is seeded with completely random agents, which contains a mix of herbivores, omnivores, carnivores, but is predominantly composed of creatures that are incapable of life.
  2. A mass die-off occurs almost immediately as the majority of random agents simple cannot eke out a living and perish due to a combination of starvation and predation.
  3. As most of the early species die, the carnivores and omnivores that relied on those hapless agents begin to die off in waves, each successive wave eliminating the prey for more species.  Herbivores, on the other hand, benefit from having a stable food source:  a location’s nutrients are static, being refreshed at the start of each generation.
  4. Eventually only herbivores and a precious few carnivores/omnivores are left over, but selection pressure dictates that the herbivores that still suffer predation will evolve their defences, driving the rest of the predators to extinction.
  5. Once the population is wholly herbivores, the only way that a meat-eater can evolve is through a lucky mutation of its offence tag.  Unfortunately, since herbivores tend to evolve defences against their own kind (to prevent cannibalism), these mutation-based carnivores are relatively weak.  As a double-whammy, these new carnivores are also usually able to eat their own kind.
  6. Compounding the new carnivores’ problems is the fact that reproduction in the level one CAS is completely random, and thus successful carnivores breed with herbivores most of the time, which does not guarantee new carnivore births.

With the deck stacked against meat-eating agents, I was forced to hunt around online and dig up some of the scarce papers on ECHO. Peter T. Hraber, of the Santa Fe Institute, had published the results of some of his ECHO experiments back in 1997 and they contained a nugget that seemed worth following.

Dawn of the carnivores

In particular, Hraber hinted that sustained predation was not possible without agents being able to be selective about what they eat.

While there is no capability for selective feeding in a level one ECHO system, level two of the model introduces exactly that concept:   conditional exchange.

Conditional exchange is implemented by introducing a new tag for all agents: the conditional exchange tag.  When choosing a target for a random interaction, instead of simply accepting the first random resource node/agent that is seen an agent can test their conditional exchange tag against the offence tag of the target; if there is a match then an attack is attempted, otherwise a new random target is selected (up to N times).

Yesterday at lunch I sat down and coded up the logic for conditional exchange and, after fixing a rather blatant bug that Bill pointed out, I was able to run the simulation.  Not only did carnivores and omnivores appear and survive, but the population exploded across all types of species.

Generation 184,212: green = herbivore, blue = omnivore, red = carnivore

Whereas before I was seeing 2000-4000 agents (all herbivores) no matter how long I ran the system, the addition of the conditional exchange logic saw life flourish to new levels, with the population ballooning past 15,000 in a relatively short number of generations.  More exciting, diet diversity was way up.  Herbivores are still the most prominent type of species, making up 70% of the total population, but there are 10-15% carnivores at any given time, and another 10-15% omnivores.

What is even more exciting is that it is possible to watch some very natural-looking cycles occur in specific locations within the simulation.  Herbivores may dominate a region at first, but then slowly you can watch meat eaters rise up, and become the primary type of species as the herbivores are culled.  After a while there will be primarily carnivores, who will then start starving to death, thus allowing the herbivores to arise once more.  It is utterly fascinating to watch a completely random simulation mimic the type of species dynamics that are evident in natural populations such as deer and wolves.

Next steps

The two next big features that I’m pushing to implement in Web Critters will be a mating tag which allows for selective reproduction (and thus proper specification) and persistent resources (so that resources can accumulate and/or run scarce).  Selective mating is probably the more important feature to get in place, since it will allow a less chaotic churn to the overall species in the simulation.

Alongside these changes I have a bunch of little improvements (all listed on github) to get in place.  The most important will be to allow  multi-threaded generation processing so that the simulation runs faster.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

One Response to “Building the perfect killer”

  1. Bill says:

    Yay, long lived carnivores! I can die happy now.

Sorry, the comment form is closed at this time.

© 2004-2010 - Systemic Babble is created and maintained by Andrew Anderson. Suffusion WordPress theme by Sayontan Sinha