25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Up   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music

QBASIC and JavaScript programs to demonstrate the illusion of increasing complexity in evolution

The article "Why does evolution seem to trend in the direction of greater complexity?" describes how that apparent evolutionary trend can be explained as an illusion.

The reason is demonstrated by the computer program below. There are plenty of C++ programs on this website, so I decided to try something new and write this program in QBASIC and JavaScript. 

It creates an array of 100 character strings, each 1 char long.

It then makes multiple passes through the array, modifying each string as it goes. With an equal probability of occurrence, it either:

  • adds 1 character to its length
  • reduces its length by 1 character, but not below the minimum allowed length of 1 (on the grounds that there are no molecules that contain 0 atoms).

Even though the process theoretically works in both directions, you're already starting with the shortest (simplest) possible strings, so there will appear to be a trend toward increasing complexity, longer and more complicated strings. 

Strings will actually be appearing in longer and shorter lengths all the time, but the only new lengths you see over time will be the longer more complex ones as the Brownian random walk explores the unlimited upside potential of string length while being unable to explore the downside because it started at the lowest possible limit. 


QBASIC

'STRGROW.BAS    10/16/2008		QBASIC
'Copyright (C)2008 Steven Whitney.
'Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.
'Initially published by http://25yearsofprogramming.com.

'Demonstrates that a set of strings that start at a minimum length (1 char)
'and that are randomly lengthened or shortened by 1 in successive passes
'(without allowing length to fall below minimum threshold)
'will accumulate longer average lengths over time.
'This is a trivial demonstration of a statistical explanation
'for the apparent trend toward increasing complexity in evolving systems,
'as described at http://25yearsofprogramming.com/ai/complexdoc/complexdoc01a.htm

DECLARE SUB pass (a$())
DECLARE SUB dostats (a$())
RANDOMIZE TIMER

'SET UP AN ARRAY OF 100 AGENTS WITH A STARTING LENGTH OF 1 CHAR
DIM a$(100)
FOR i = 0 TO 99
	a$(i) = "1"
NEXT i

'WRITE TO A FILE TO VIEW LATER BECAUSE THE QBASIC SCREEN IS TOO SMALL 
OPEN "C:\TEMP\OUTPUT.TXT" FOR OUTPUT AS #1
PRINT #1, "Count", "MinLen", "MaxLen", "AvgLen"

'LOOP REPEATEDLY, LENGTHENING OR SHORTENING EACH AGENT IN THE ARRAY, CALCULATE AND SHOW STATS.
FOR i = 0 TO 1000
	CALL pass(a$())
	CALL dostats(a$())
NEXT i
CLOSE #1
END

'----- 
'WITH EQUAL PROBABILITY, LENGTHEN OR SHORTEN THE STRING BY 1, BUT NOT BELOW MIN LENGTH OF 1.
SUB pass (a$())
FOR j = 0 TO 99
	IF INT(RND * 2) = 0 THEN
		a$(j) = a$(j) + "1"
	ELSE
		IF LEN(a$(j)) > 1 THEN a$(j) = LEFT$(a$(j), LEN(a$(j)) - 1)
	END IF
NEXT j
END SUB

'----- 
'CALCULATE AND SHOW THE STRING LENGTH STATISTICS
SUB dostats (a$())
min = 10000: max = 0: total = 0: count = 0
FOR j = 0 TO 99
	count = count + 1
	IF LEN(a$(j)) < min THEN min = LEN(a$(j))
	IF LEN(a$(j)) > max THEN max = LEN(a$(j))
	total = total + LEN(a$(j))
NEXT j
PRINT #1, count, min, max, total / count
END SUB

QBASIC output

Here are the numbers from the start and from near the end of a 10,000-pass run:

Count         MinLen        MaxLen        AvgLen
 100           1             1             1 
 100           1             2             1.53 
 100           1             3             1.79 
 100           1             4             1.98 
 100           1             5             2.26 
 100           1             6             2.43 
 100           1             7             2.65 
 100           1             8             2.72 
 100           1             9             2.83 
 100           1             10            2.91 
 100           1             11            3.17 
 100           1             10            3.35 
 100           1             305           78.71 
 100           2             304           78.91 
 100           1             305           78.85 
 100           2             304           78.75 
 100           3             305           78.73 
 100           2             306           78.75 
 100           2             305           78.63 
 100           1             306           78.67 
 100           1             307           78.8 
 100           2             308           78.78 
 100           1             307           78.86 

JavaScript

Here is the program translated to JavaScript, my first programming attempt in JavaScript.

<script type="text/javascript">
<!--
/* STRGROW.JS    10/19/2008		JavaScript 
Copyright (C)2008 Steven Whitney.
Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.
Initially published by http://25yearsofprogramming.com.

Demonstrates that a set of strings that start at a minimum length (1 char)
and that are randomly lengthened or shortened by 1 in successive passes
(without allowing length to fall below minimum threshold)
will accumulate longer average lengths over time.
This is a trivial demonstration of a statistical explanation
for the apparent trend toward increasing complexity in evolving systems,
as described at http://25yearsofprogramming.com/ai/complexdoc/complexdoc01a.htm
*/
var outputtext;		//for building the output text
function pass(a$)
{ 
	//WITH EQUAL PROBABILITY, LENGTHEN OR SHORTEN BY 1, BUT NOT BELOW MIN OF 1.
	for(j = 0 ; j < 100 ; j++)
	{
		if(Math.floor(Math.random() * 2) == 0)
			a$[j] += "1";
		else
			if(a$[j].length > 1)
				a$[j] = a$[j].substring(0,a$[j].length - 1);
	}
}
function dostats(a$)
{
	//CALCULATE AND SHOW THE STRING LENGTH STATISTICS
	min = 30000; max = 0; total = 0; count = 0;
	for(j = 0 ; j < 100 ; j++)
	{
		count++;
		max = Math.max(max,a$[j].length);
		min = Math.min(min,a$[j].length);
		total += a$[j].length;
	}
	//&nbsp; prevents IE7 from concatenating spaces
	outputtext += count + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + 
					min + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + 
					max + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + 
					(total / count) + "<br>";
}
function rundemo(outmode)
{
	outputtext = "Count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MinLen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
	outputtext += "MaxLen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AvgLen<br>";
	//AN ARRAY OF 100 AGENTS WITH A STARTING LENGTH OF 1 CHAR
	var a$ = new Array(100);
	for(i = 0 ; i < 100 ; i++)
		a$[i] = "1";
	
	//LOOP REPEATEDLY, LENGTHENING OR SHORTENING EACH AGENT; CALCULATE AND SHOW STATS.
	dostats(a$);				// show starting numbers
	for(i = 0 ; i < 100 ; i++)	// change loop value, if desired, to show more "generations"
	{
		pass(a$);
		dostats(a$);
	}
	//CHOOSE YOUR OUTPUT METHOD
	if(outmode === 1)		// this is used by the Recalculate button
		document.getElementById("JavaScriptOutput").innerHTML = outputtext;
//	else	// document.write in a function within <head> opens a new page, which isn't what I want. 
//		document.write("<p>Use your Back button to return to previous page.</p><pre>" + 
//						outputtext + "</pre>");
}
//-->
</script>

JavaScript output for 100 iterations



 

Valid HTML 4.01 Transitional Valid CSS
Yahoo! Search
Search the web Search this site
View content labeling at ICRA.