The magazine of the Melbourne PC User Group
Populate and perish
Ken Holmes
cad@melbpc.org.au |
 |
Among the many fascinating things one may do with a computer are simple
simulations of the interaction between life and its environment. A popular type is the "prey and predator"
variety, which uses the graphic screen as the arena with, say, single pixels as "prey" and small squares as
"predators". To cope with the edges, a "toroidal universe" is used; that is, anything moving off the right
edge of the screen reappears on the left, and anything moving off the top reappears on the bottom. It's like
the surface of an inner tube, no edges.
The prey is scattered randomly over the screen and may have "oases" of greater concentration. Also the supply
of prey is steadily topped up as the program runs to replace those consumed as the roving predators land on
them. They provide food energy for the predators to replace the energy used by them in moving. This type of
program depends on a random number generator to set it up and to control all subsequent behaviour. The random
number is "seeded" by the computer clock at start-up, ensuring that every run is different.
The sample program here initially randomly strews 5000 bacteria (one pixel) across the screen, with the top
left quarter getting an extra 1000. Every program cycle thereafter, the screen gets ten more and the oasis
another four. Ten bugs (3 x 3 pixels) are created with randomly allotted "travel-direction-change" genetic
characteristics, i.e. their tendency to go straight ahead or change heading. They start with 50 energy units,
each move costing one unit and each bacterium consumed providing four units. If its energy reaches zero, the
bug dies; but, if it reaches 100, the bug is replaced by two of the next generation, each having 50 units.
One offspring will have a stronger tendency to circle, the other to move ahead. Circlers tend to eat out
patches and die off while nomads tend to find richer areas and evolve into survivors.
What's happening?
Figure 1 shows the situation shortly after starting, with feverish breeding on and near the oasis which is
already rather moth-eaten (bug-eaten?). Chance determines where the originals are born and what their
circling tendencies are, and thereby determines the early trends of the run. Bug colours indicate that
several generations exist.
It is interesting to note the behaviour of bugs on screen. After a time the cruisers are ranging across the
screen; the oasis becomes less obvious as, although it is steadily breeding more bacteria, it tends to have a
few circling stay-at-homes as well as its share of nomads passing through. You see bugs in denuded patches
dying off, and those in richer areas changing in colour and twinning. If you allow it to run up towards the
maximum (7000) number of recordable "events", you will see that most of the bugs have converted their "half
left" and "half right" tendencies to a "straight-ahead" tendency. They race straight through the oasis and,
with no unusual exploitation of it, the oasis becomes more obvious.
|

Figure 1. Early breeding
|

Figure 2. The "heading-gene" change fingerprint
|
How do you like my genes?
Figure 2 (press "g") is the "heading-change" gene fingerprint of the current bugs, plotted down from the top
with the cumulated tendencies to:
- Maintain heading--green line
- Turn half right--cyan line
- Turn hard right--red line
- Reverse--magenta line
- Turn hard left--brown line
- Turn half left--black line.
(These are screen colours and may print differently.)
The first ten bugs are allotted their genes randomly and will have different values. When they breed, one
offspring has its "straight-ahead tendency" gene increased (the other has it decreased) at the expense of the
"half-right tendency" or "half-left tendency" gene; the other genes are not changed. Each cycle, a random
number for each bug present, will fall in one or other of its tendency ranges and so decide what its actual
heading change will be.
After running for a while, most strains die out with survivors of only one or two of the originals. The total
of tendencies (or distance from top to the lower end of the black line) is unchanged and is the clearest
inherited characteristic. The increase in the favoured "ahead" gene will be evident from the lengthening of
the green lines. On the same screen are the energy levels of the current bugs plotted upwards from the bottom
in colours representing their "generation". Figure 2 was recorded soon after the start and, with population
at 74, already there are survivors of only four of the originals. One strain is dominant with 61
representatives.
|

Figure 3. Population history
|
Don't get historical!
You may press "p" at any time to see Figure 3, the history of population size of both the bugs (limited to
99) and the bacteria. At the start, the bacteria increase, followed soon by the bugs which exploit them and
send them into decline. The rate of decline is proportional to the number of bugs (above the mean), giving
the standard engineering result where two effects vary sinusoidally with one (bacteria population) leading
the other (bug population) by 90 degrees in phase, which persists throughout the run. The bug curve and the
bacteria curve are amplitude modulated, as happens when two frequencies beat together.
At the end of the run, it is oscillating around the equilibrium condition of 56 bugs and 6000 bacteria. This
suggests that starting with 56 bugs might give us immediate equilibrium; however, there is still an initial
die-off to under ten bugs, because they are still circlers that eat out a small patch and starve. The gene
pool is depleted and the run ends usually with only one strain (the cheetah effect). Even if we start with
all rovers, whilst the initial upwards displacement is slightly lessened, bug population still varies
ñ50 percent about the mean. There is no damping near equilibrium and there is a delay until bacteria
become rare, or abundant, enough before the run-away bug population starts to return to the mean. It seems
that equilibrium is just a place you pass through on the way to a boom or a bust--heard that before? Ah, the
joys of programming! You often think you can predict what will happen if you try something--and, when you do,
it doesn't.
You may change some of the parameters to study the effects. These are sometimes surprising but usually
explicable and you see parallels in real-life situations such as animal (or human) population fluctuations,
the rise and fall of civilisations and the vagaries of the stock market. This is the simplest of simulations
and, as with simple structures such as violin strings, has few resonant frequencies. Figure 3 seems to have
two resonances "beating" together, with some noise super-imposed. More realistic systems or structures have
many resonances and the variation or vibration is best described as "noise". Sometimes, some frequencies can
be detected, like that whine in your gearbox.
If you reduce the population limit (default 99) to, say, 50, you will get an ideal(?) world, with no famines,
no deaths, no breeding (or evolution)--"survival of the fattest". Of course, real life is more complicated.
Limiting population would not prevent death, due to our natural life span, but it would certainly minimise
the dying and suffering.
On the other hand, if you lower the food value (default 4) of the bacteria or raise the energy cost of a move
(default 1), you will have an extinct species on your conscience. If you raise the food value to 9,
population will grow rapidly to the limit and five or six of the original ten will have surviving progeny.
You may also change the fertility of the oasis (default 4) to see the effect.
Where did all my megahertz go?
Take the back of an envelope. With the default values, a 486 at 66 MHz goes through about 15,000 program
cycles in a six-minute run, or 6 x 60 x 66 (about 24,000) million processor cycles. Thus each program cycle
uses 1.7 million processor cycles. Assuming an average of 60 bugs, it needs 30,000 cycles to process each
bug. This covers blanking out, determining heading change, heading, new position, food at new position,
adding food energy, subtracting move energy and plotting the new bug. There are also overheads in processing
over 2000 deaths and 2000 breedings, topping-up the food and recording the history.
On each program cycle, 14 new bacteria bring in 56 energy units providing move energy for 56 bugs which
should be the average number with near-equilibrium conditions. The EGA screen has 350 x 640 or 224,000 pixels
and the 56 bugs land on 56 x 9 or 504 of them. If these contain 14 bacteria on average, then the whole screen
must have about 6,200 for equilibrium.
POPULATE.EXE (110 KB) is available for download produced from the C++ version.
I have versions in Assembler and QuickBasic (would run in QBasic) and anyone interested is welcome to the
source code for any version should they wish to develop them into something more complicated, or just to
trace the action.
Reprinted from the March 1998 issue of PC Update, the
magazine of Melbourne PC User Group, Australia
|