claudeb: A white cat in purple wizard robe and hat, carrying a staff with a pawprint symbol. (Default)
[personal profile] claudeb

This is mostly of interest to computer history nerds.

Nils Aals Barricelli was an early computer scientist. Among other accomplishments, he pioneered what we now call genetic algorithms. I've learned about him from my friend [personal profile] sandwolf5, who uses a fictional version of his work as the origin story of L.A.I.R.A., from the eponymous trilogy of novels (and the epic saga it spawned).

Now for the fun part: Barricelli's page on the chess programming wiki (turns out he also pioneered computer chess) lists this algorithm for "symbiogenetic" reproduction. It looks more like a cellular automaton to me, but whatever:

integer array this generation, next generation [1 :512];
begin
 loop: for i : = 1 step 1 until 512 do 
       begin 
       n := j := this generation[i];
reproduce: if j = 0 then goto next i;
       k := modulo 512 of (i) plus: (j);
       if next generation[k] > 0 then 
       goto mutation else 
       next generation[k] := n;
       j := this generation[k];
       goto reproduce;
  mutation:
  next i: end;

  copy next generation into this generation;

  print this generation;

  goto loop;
end;

The description is fairly incomplete. For one thing, it says this is Algol code. Um, which version? I'll assume Algol 60, the ancestor of Pascal. It also doesn't state the range of integers (10-bit?) or what the next generation array is initialized to. So my C++ port makes some assumptions:

// C++ port of the symbiogenetic algorithm by Nils Aals Barricelli.
// Source: https://www.chessprogramming.org/Nils_Barricelli

#include <cstdlib>
#include <ctime>
#include <cstdio>

int this_gen[512];
int next_gen[512];

int main() {
	std::srand(std::time(0));

	// Guess at the absent init code from the original page.
	for (size_t i = 0; i < 512; i++) {
		// Turns out it only works with very small numbers.
		this_gen[i] = std::rand() % 3 - 1;
		// Not sure if this is needed or correct here.
		next_gen[i] = 0;
	}

	do {
		for (size_t i = 0; i < 512; i++) {
			printf("%3d ", this_gen[i]);
			if (i % 16 == 15)
				printf("\n");
		}

		for (size_t i = 0; i < 512; i++) {
			int j = this_gen[i];
			int n = j;
			while (j != 0) {
				int k = (i + j) % 512;
				if (next_gen[k] > 0)
					break;
				else
					next_gen[k] = n;
				j = this_gen[k];
			}
		}
		for (size_t i = 0; i < 512; i++)
			this_gen[i] = next_gen[i];
		puts("Press Ctrl-C to stop or Enter for next gen:");
	} while (std::getchar() != EOF);
}

(I picked C++ due to its ubiquity; most people who will read this far are likely to have a compiler installed. And yes, identifiers in Algol 68 at least could have spaces in them.)

Well, it kinda works for a couple of generations, on some runs. Maybe I'm doing something wrong. In any event I don't see any pattern in the numbers of anything. Maybe someone more informed can enlighten me? But it's good practice.

Edit: this page says you're supposed to start with integers from -1 to +1, but now it doesn't seem to work at all anymore, not even by chance. I remain baffled.

Edit 2: Just in case, I also made a version of the code that reproduces the original tangle of goto statements. It still doesn't work.

(will be screened)
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

Profile

claudeb: A white cat in purple wizard robe and hat, carrying a staff with a pawprint symbol. (Default)
Claude LeChat

Links

Most Popular Tags

Style Credit

Page generated 22 Mar 2026 22:19
Powered by Dreamwidth Studios