Your browser (Internet Explorer 6) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.
X

Langton’s Ant

Resolvi iniciar uma série de posts sobre Vida Artificial (Artificial Life – AL) para aprender um pouco mais sobre as bibliotecas de CreativeCoding, principalmente ProcessingopenFrameworks, e claro, o exemplo mais simples, o HelloWorld da área de AL, é um experimento chamado de Formigas de Langton (Langton’s Ant).

Christopher Langton é um cientista da computação e um dos fundadores da área de Artificial Life. Um dos grandes argumentos contra a Teoria da Evolução das Espécies é que é impossível algo tão complexo como a vida que conhecemos hoje no planeta possa ter surgido de processos aleatórios, como a Seleção Natural, e sem alguma “inteligência” por trás para guiar a evolução. Este é o grande argumento dos que defendem a teoria do Design Inteligente, um concorrente da Teoria da Evolução das Espécies de Darwin. Cada um acredite no que achar mais conveniente,  mas em 1986, Langton elaborou um experimento computacional bem simples para mostrar que comportamentos, ou melhor, padrões complexos podem surgir de sistemas com regras bem simples, sem nenhum tipo de “inteligência” guiando a evolução do sistema. O experimento ficou conhecido como Langton’s ant. Existe um grid quadricular onde cada quadrado pode ter apenas duas cores (branco ou preto neste experimento). Apenas três regras definem o como o sistema evolui.:

  1. a cada iteração, uma “formiga”, exibida em uma cor diferente do grid (vermelho no caso apresentado aqui) pode andar apenas uma unidade em cada uma das direções Norte, Sul, Lest ou Oeste;
  2. quando a formiga entra em um quadrado preto, ela vira 90 graus à esquerda e muda o quadrado para branco;
  3. quando a formiga entra em um quadrado branco, ela vira 90 graus à direita e muda o quadrado para preto.

E é isto. Estas três regras levam a um comportamento complexo, e nada aleatório após um certo número de iterações. Inicialmente, existe um período caótico de movimento, que dura aproxidamente 10 mil interações no caso inicial mais simples (todos os quadrados do grid começam na mesma cor) e, após este período, a “formiga” constrói um padrão que se assemelha a uma avenida de 104 passos que se repetem infinitamente. Este padrão foi provado ser um atrator para o sistema de Langton, mas infelizmente, ninguém conseguiu provar ainda quantos passos são necessários, no caso geral, para se chegar a ele. Apenas se sabe que, independente das condições iniciais, o sistema sempre irá convergir para este padrão de avenida, ou seja, algo em princiípio aleatório como o movimento da formiga pelo grid pode convergir para um padrão “inteligente” (o termo inteligente ainda precisa ser definido cientificamente, e, na minha opinião, o ser humano ainda não sabe dizer o que é “inteligência”), mesmo sem ter um guia externo.

Foi provado que Langton’s Ant é um caso particular de uma Turmite, uma máquina de Turing com entrada bidimensional, um mapa, ao invés de uma fita unidimensional. Mais para frente, incluirei um post sobre turmites.

Tem uma animação feita no ProcessingJS, a versão em JavaScript to Processing, aqui. Se não tiver paciência para esperar até a iteração 10 mil, fiz um video mais curto e postei no vimeo.

O código Processing para o projeto está abaixo. Eu particularmente destesto magic numbers em programação, mas o Processing não permite usar enums.

A animação reseta quando a formiga chega nas bordas. Qualquer dúvida, mande uma mensagem ou deixe um comment.

O próximo post será sobre Game of Life do Conway. Até lá.

[java]
int WIDTH = 800, HEIGHT = 600;
int squareHeight, squareWidth;
int numCol, numLine;
int antX, antY;
color[][] gridColor;
color black, white, ant;
int antDirection, North, South, East, West;

void setup()
{
// Grid Information
numCol = 100;
numLine = 100;
squareWidth = WIDTH / numCol;
squareHeight = HEIGHT / numLine;

// Start position of the Ant
antX = numCol / 2;
antY = numLine / 2;

// Colors of the Grid
black = color(0);
white = color(255);
ant = color(255, 0, 0);

// Ant Direction
North = 1;
South = 2;
East = 3;
West = 4;

antDirection = North;

gridColor = new color[numCol][numLine];
for (int lines = 0; lines < numLine; lines++)
{
for (int columns = 0; columns < numCol; columns++)
{
gridColor[columns][lines] = black;
}
}

size(WIDTH, HEIGHT);
background(0);

// Green (Matrix) Line
stroke(0, 150, 0);
}

void draw()
{
background(0);

// Draw the Grid
for (int lines = 0; lines < numLine; lines++)
{
for (int columns = 0; columns < numCol; columns++)
{
fill(gridColor[columns][lines]);
rect(columns * squareWidth, lines * squareHeight, squareWidth, squareHeight);
}
}

// Draw Ant position in this frame
fill(ant);
rect(antX * squareWidth, antY * squareHeight, squareWidth, squareHeight);

// Compute the new position of the Ant
if (gridColor[antX][antY] == black)
{
// Change color of the square the Ant was in
gridColor[antX][antY] = white;

// Check Ants direction
switch (antDirection)
{
// North
case 1:
antX–;
antDirection = West;
break;

// South
case 2:
antX++;
antDirection = East;
break;

// East
case 3:
antY–;
antDirection = North;
break;

// West
case 4:
antY++;
antDirection = South;
break;
}
}
else
{
// Change color of the square the Ant was in
gridColor[antX][antY] = black;

// Check Ants direction
switch (antDirection)
{
// North
case 1:
antX++;
antDirection = East;
break;

// South
case 2:
antX–;
antDirection = West;
break;

// East
case 3:
antY++;
antDirection = South;
break;

// West
case 4:
antY–;
antDirection = North;
break;
}
}

// Reset if Ant has reached a border
if (antX < 0 || antX >= numCol || antY < 0 || antY >= numLine)
reset();
}

void reset()
{
antX = numCol / 2;
antY = numLine / 2;
antDirection = North;

gridColor = new color[numCol][numLine];
for (int lines = 0; lines < numLine; lines++)
{
for (int columns = 0; columns < numCol; columns++)
{
gridColor[columns][lines] = black;
}
}
}
[/java]