"Is it Chance?"


What it is

"Is it Chance?" is a nice small demonstration of evolution.  You can download the program:  version for Mac OS X, (version for Windows and version for Linux may follow).

I used the ideas from Keith Goodnight, added a few things and also discuss here the algorithm.

Why this program?

I quote from the original goal of Keith Goodnight:

One of the common attacks launched by creationists is the claim that evolution is “mere chance.”

Typically, a creationist will point out how absurd it is that “mere chance” could produce a complex organ or adaptation.

Sometimes the attack will include a probability calculation based on some estimate of the number of mutations required to produce a certain organism from some ancestor, and will show that the odds are so small that the history of the universe is not long enough to expect the “coincidence” to occur.

Is It Chance? is a very simple little program that demonstrates the power of natural selection to accumulate favorable variations is anything but “mere chance.”

The program pits chance against selection in a race to “evolve” a complex target— a sentence entered by the program’s user— from an “ancestor” that is a string of random characters.

What it does

Evolution works by weeding out the organisms that are less well adapted to the environment than others.  At each generation an organism produces a number of offspring, who are copies of the parent.  If they were perfect copies, there would be no evolution.  And then if the environment changes sufficiently, the organisms might all die.  However, at each generation there is a small number of random mutations.  Most of these are useless or even bad, but some will give a slightly better adaptation to the environment.

In this demonstration the well-adapted organism is a piece of text that you can type into the program.  It is the "goal" of evolution.

The program tries to construct that well-adapted organism in two ways:

(1) totally at random:

In each generation the offspring is a set of texts (10 by default) that are made up entirely by randomly picking characters.  If one of the text strings matches the goal the program stops and the task is done.

(2) by selection, inheritance and mutation

In this second case the program starts with a totally random string, like in case 1.  However, in each generation all offspring are now copies of the parent (there are again 10 of these).  That is the inheritance part:  offspring are copies of parents.  But again, if they were perfect, we would never get to the goal.  The program then makes a small number of mutations to the offspring:  a few characters are changed in a totally random fashion.

Now the third aspect of evolution is used:  selection.  From the offspring a single text is selected, that comes closest to the goal, i.e. that one in which the largest number of charcters match those of the goal.  All other offspring are weeded out, and only this best adapted one will be used in the next generation.

How to use it

On startup the program "Is it Chance?" presents this window:

There is a field in which you can type some text, a start button, a speed slider, and a menu at the top.  For the time being we will leave that set at "Simple".

Type some text and press the Start button. After a while you may see something like this:

In this case I typed the text "the quick brown fox", and that is the goal.  Below the word "chance" you can see a random text, of which only one letter corresponds to the goal, the red "q".  A little lower, below the words "selection and mutation" there is another fairly random text, but many more letters correspond to the goal.  That is the text that is the result of several generations of accumulation of good mutations.

There are two other indications:  the lenght of the text is 19 characters and the probability to make that text by randomly writing 19 characters in a row is a little over 4.4x10-33, a number so small it is impossible to pronounce.

When you run it you will see that the first process, pure randomness, will not get anywhere although it is not entirely excluded that it stumbles on the goal.  The selection and mutation process of evolution will reach the goal in a reasonable time.

Things to try

Two things you might try:


Now select the "Advanced" option from the top left menu.  A few more things show up:

  1. there are two more sliders, one in which you can set the number of offspring at each generation.  It is by default 10 as stated earlier.
  2. the mutation rate slider allows you to set the number of mutations that will be spread over the offspring of the selection case.
  3. there are some more indications of what is going on, such as the number of tries it took to get to the goal.  In this particular case I gave the text "in" as the goal, selection found it in 34 tries and the purely random generation also found it but needed 598 tries.

Things to try

Change the mutation rate

Type a reasonably short text and note how many tries it takes with the mutation rate at its default (10).  Then set the mutation rate to the extreme minimum (1) and let it work again on the same text.  It needs a lot more time:  the chance that a good mutation crops up to bring us nearer to the goal is now much lower.

Then set the mutation rate at its maximum and let it work again on the same text.  Note how you can now see that some letters that were already "good" are "destroyed" by mutations.  It takes a lot more time now to get to the goal.  In fact, if the mutation rate could be set very high, we would be in the situation of the totally random approach!

This illustrates that mutations are needed if successive generations are going to be different so that the best adapted ones can be selected.  But if there are too many mutations (such as could happen in radioactive environments) then a lot of offspring is wasted and successive generations cannot accumulate what is good.

The way mutations are applied

In this program the mutations are applied randomly over the offspring.  That means some copies may not get any mutation and others may get more than one.

Change the number of offspring

Set the number of offspring to the minimum:  it will still get to the goal, but with fewer kids progress is slower.  If you do not diminish the mutation rate at the same time, you will get many mutations in each one of the offspring and will not get to the goal again.  If you set the number of offspring high you will get to the goal faster because the chances that one of them is closer is now high.  In nature too a large number of offspring, even if only one utlimately survives, gives a good chance to keep adapting well to the changing environment.

What is the changing environment in this demonstration?

It does not change.  The goal text remains the same.  In nature the environment does change, but normally this happens so slowly that organisms have plenty of time to adapt very well to it.  We see plants and animals that are "perfectly" adapted to their niche.  This is not true:  no organism is perfectly adapted, it only looks like that because the changes in the environment are so slow.

Climate Change

Climate change as we are experiencing right now is a very fast change.  Because evolution works slowly, many organisms, perhaps including ourselves, may not be able to survive this fast change.

Advanced showing offspring

This is the last mode:  one more indication shows up, the list of offspring generated at each generation.  It looks like this:

You can see that three of the ten offspring in this snapshot are the same, no mutations occurred in them, though some have multiple ones.  There is nothing more to try in this mode than in the advanced mode.

Discussion of the program code

The program was written in RunRev Studio.  You can download a free version of RunRev.  This free version has some limitations but they are not important for reconstructing the program.  You can then inspect the full code by downloading the RunRev object and opening it with RunRev Media.

Below is the important part of the code.  Note that I omitted all the stuff to do with the user interface, only the central part is listed here.


command Evolve

if the State of me is "Running" then


send "Evolve" to me in (the endvalue of scrollbar "Speed" - the thumbposition of scrollbar "Speed")*MillisecondsBetweenGenerations milliseconds

end if

end Evolve





command Generate


local Match, NumberMatched, NewRandom


set the caseSensitive to true

add 1 to NumberOfGenerations



-- at each step we generate NumberOfOffspring random texts of the length of the user's text

if ByChance["stillgoing"] then

put NumberOfGenerations into field "ChanceTries"

repeat with i=1 to NumberOfOffspring

put empty into NewRandom

repeat LengthUserText times

put char random(nAllowed) of AllowedCharacters after NewRandom

end repeat

put NewRandom into ByChance["tries"][i]

end repeat

    -- select the best match:

    put BestMatchOf(ByChance["tries"]) into Match

    put ByChance["tries"][item BestMatch of Match] into field "ByChance"; ShowMatches "ByChance"

    put HighMatch&space

    put item HighMatch of Match after msg

    put item HighMatch of Match into NumberMatched

    if NumberMatched > field "BestChanceMatch" then put NumberMatched into field "BestChanceMatch"

    if NumberMatched is LengthUserText then put false into ByChance["stillgoing"]

  end if



-- generate NumberOfOffspring texts derived from the previous evolving text

-- the first time the evolving text is empty so no character matches and all will be random

if BySelection["stillgoing"] then

put NumberOfGenerations into field "SelectionTries"

-- make NumberOfOffspring copies

repeat with i=1 to NumberOfOffspring

put BySelection["evolved"] into BySelection["tries"][i]

end repeat

-- spread the desired number of mutations by randomly mutating one character in a random copy,

-- this will possibly give more than one mutation in some copies and no mutations in others

repeat with i=1 to the thumbposition of scrollbar "MutationRate"

put char random(nAllowed) of AllowedCharacters into char random(LengthUserText) of BySelection["tries"][random(NumberOfOffspring)]

end repeat

-- select the best match:

put BestMatchOf(BySelection["tries"]) into Match

put BySelection["tries"][item BestMatch of Match] into BySelection["evolved"]

put BySelection["evolved"] into field "BySelection"; ShowMatches "BySelection"

put item HighMatch of Match into NumberMatched

if NumberMatched > field "SelectionMatches" then put NumberMatched into field "SelectionMatches"

if NumberMatched is LengthUserText then

put false into BySelection["stillgoing"]

set the SelectMutations of me to the SelectMutations of me & "," & NumberOfGenerations

end if

if the visible of field "Offspring" then -- show the generated offspring

lock screen

put empty into field "Offspring"

repeat with i=1 to NumberOfOffspring

put BySelection["tries"][i] into line i of field "Offspring"

end repeat

set the textcolor of line item BestMatch of Match of field "Offspring" to "red"

unlock screen

end if

end if


end Generate




function BestMatchOf Strings

-- returns the index and the number of matching characters of the

-- string in array Strings that best matches string UserText


local Matches, HighMatchValue, BestMatchValue


set the caseSensitive to true

put 0 into HighMatchValue

repeat with Child=1 to NumberOfOffspring

put 0 into Matches

repeat with j=1 to LengthUserText

if char j of UserText is char j of Strings[Child] then

add 1 to Matches

end if

end repeat

if Matches > HighMatchValue then

put Matches into HighMatchValue

put Child into BestMatchValue

end if

end repeat

-- if none had a match, pick the first one:

if HighMatchValue = 0 then put 1 into BestMatchValue

return BestMatchValue & "," & HighMatchValue

end BestMatchOf



command ShowMatches FieldName

-- mark the matching characters in red

set the caseSensitive to true

repeat with j=1 to LengthUserText

if char j of UserText is char j of field FieldName then

set the textcolor of char j of field FieldName to "red"

end if

end repeat

end ShowMatches



Valid XHTML 1.0 StrictValid CSS

next planned revision: 2009-01