domingo, 7 de agosto de 2011

Nanolife: Evolução, vida artificial e maquinas de Turing.

    A alguns meses atrás, pesquisando sobre vida artificial encontrei um projeto chamado Nanopond. Um simulador de vida artificial com uma ideia muito interessante. O programa roda uma matriz, onde os espaços vazios podem ser ocupados por "celulas". Cada célula é uma maquina de Turing, pois seu código genético é lido como um programa. Tal código genético é escrito numa linguagem parecida com brainfuck, que já foi várias vezes comprovado ser uma linguagem Turing Completa. Então, teoricamente, cada célula pode fazer tudo o que um computador faz. Mas além dos comandos básicos da linguagem brainfuck, este código genético tem comandos que essa célula executará, como se reproduzir ou girar 90°. Com esses comandos básicos e um pouco de tempo de computação resultados, no mínimo, interessantes aparecem, verdadeiras colônias de células começam a emergir até um ponto que falta espaço e alimento. Nesse momento a competição começa e é possível ver a seleção natural agindo em tempo real.
    Inspirado com esse programa, resolvi criar uma versão minha desse, com algumas modificações, que ao meu ver deixam a coisa um pouco mais interessante.
Na minha versão cada célula tem um código genético como a versão original, uma array, que serve de memória, inicialmente preenchida por zeros, um valor que determina a posição atual da memória (memoria[valor]), outro valor que determina a energia que essa célula tem e outro valor que determina o tempo restante de vida dessa célula (valor que é igual para todas as células). Há 9 tipos de "opcodes genéticos", que são executados a cada turno do programa. Tais comandos são: adiciona ou subtrai 1 do index da memória; adiciona ou subtrai 1 do valor da memória em que o index aponta; abre ou fecha um loop while; verifica se a célula em frente é compatível (a compatibilidade é verificada pegando 4 index randômicos e verifica-se se o valor do código genético nesses endereços são iguais entre as 2 células), se for compatível o valor no endereço atual da memória é igual a 1, se não for compatível ou for um espaço vazio o endereço da memória é 0; o endereço da memória é igual a rotação (0 - de frente para direita, 1 - para cima, 2 - para esquerda e 3 - para baixo); e por ultimo um comando que lê o valor que está no endereço atual da memória. Dependendo o valor que estiver nesse endereço a célula toma alguma ação, consumindo energia.
Se o for valor no endereço atual da memória for:

  1. A célula gira no sentido horário.
  2. A célula gira no sentido anti-horário.
  3. A célula move um pixel para a direção que está virada.
  4. A célula move um pixel para a direção contrária a que está virada.
  5. A célula cria uma cópia quase(mutação) idêntica de si mesma à sua frente e dá 1/5 de sua energia para ela.
  6. A célula pega metade da energia da célula à sua frente.
  7. A célula tenta dividir sua energia com a célula à frente, é somada a energia dessas 2 células e é dividia entre as duas (média aritmética).

    A cada turno é verificado o tempo de vida e a quantidade de energia de cada célula, se em um momento a célula tiver idade maior que um valor predeterminado ou sua energia for menor ou igual a zero, essa célula será deletada. Energia é adicionada ao sistema criando novas células com código genético randômico a cada turno.
20 minutos de simulação, e já é possível ver uma colônia com um padrão bem evidente.
    Como é um programa simples, com complexidade O(n) e foi implementado em C não há problemas com velocidade (a simulação roda com 500.000 células a 1 FPS). Após 20 minutos rodando o programa já é possível ver colonias adaptadas (imagem à cima). Normalmente demora um tempo até aparecer alguma espécie que consiga vingar, mas depois que o processo começa a espécia tende a super população, limitada somente pela disponibilidade de alimento e espaço. Logo a mutação começa a agir e grupos de células começam a desenvolver novos comportamentos. Até o ponto que começam a competir com os outros grupos. Formando assim uma nova espécie.
Imagens:
2 espécies evidentes ainda se expandindo.

Código fonte no github (Sobre GPLv3 - Mateus Zitelli).