O jogo da vida de Conway.

Bem ta ai uma coisa legal que eu vi recentemente. Mas antes de falar do Jogo da vida de Conway, vamos falar da seleção natural, ou teoria da seleção natural, chame do que quiser, nomenclatura não é meu forte mesmo, mas dificilmente alguém não saberá do que se trata.

Um problema, na verdade não da teoria, mas da pessoas, é conseguir visualizar como regras simples podem gerar espécies como as que temos hoje. Estratégias ou comportamentos que muitas vezes parecem ir contra a “evolução da espécie” (leia autruismo aqui, mas isso é tópico para outro post), mas ainda sim são explicados com a seleção natural, que na verdade são regras simples.

Mas como assim regras simples?

É só abstrair para o fato que seleção natural precisa de:

Coisas que geram copias de si mesmas, mas coisas diferentes tem chances diferentes de gerar copias de si mesmas, essas copias nem sempre são idênticas aos originais e existe uma espaço limitado que cabe no máximo n coisas.

Seleção natural é simplesmente essas regras rolando geração apôs geração, a dinâmica devido a essas regras. Infelizmente a seleção natural é simples assim.
E conforme o tempo passa, gerações passam, essas regras simples vão gerar espécies fascinantes, coloridas, com os mais variados comportamentos, formas e estratégias, algumas até que a gente tem que quebrar a cabeça para entender.

Bem mas não é sobre isso esse post, esse post é sobre o jogo da vida. Mas porque ele é legal? Quem passou por esse post aqui, talvez tenha clicado no link de um site que avaliava uma formula matemática, o “y+2=Y”, chamado wolfram alpha, so que wolfram vem do sobrenome de um cara, que pensou naquele sistema, esse cara se chama Stephen Wolfram.

Esse cara publicou um livro chamado “A New Kind of Science”, um novo tipo de ciência, onde ele discute algumas coisas, entre elas, estuda o que são chamados de Cellular automaton, e como estes precisam de estudos empíricos, testes, para serem melhor entendidos, e não são apenas uma fórmula matemática.

Dali eu cai num exemplo de cellular automaton que é exatamente o Jogo da vida, que foi idealizado pelo Conway.
Bem eu sempre gostei do jeito como algumas pessoas, como o Richard Dawkins, Stephen Jay Gould, Richard Feynman e Stephen Hawking conseguiam deixar conceitos complicados, simples, usando muitas vezes de exemplos e analogias.

Mas analogias para a seleção natural são complicadas, exemplos são fáceis dentro da própria teoria para ilustrar o processo, mas analogias ou outros sistemas para comparar são difíceis, que sistemas reproduzem seleção natural? Vírus de computador?

O jogo da vida do conway é um exemplo legal.

Porque?

Porque ele é baseado em regras simples, vejam só.

Pensa que a gente tem um quadrado, uma tela, onde cada pixel, quadradinho preto, é um ser vivo, ou uma célula.

As regras são as seguinte para jogo da vida de Conway:

Todo pixel, ou célula com menos de duas células vizinhas morre, algo como uma população muito baixa, ou de solidão se preferir. Todo pixel, ou célula com duas ou três células vizinhas sobrevive e vai para a próxima geração. Todo pixel, ou célula com mais de três células vizinhas morre de superpopulação e não vai para a próxima geração. Todo pixel, ou célula morta com exatos três vizinhos se torna viva, como por reprodução dessas células vizinhas.

E pronto acabou. Agora sim começa a parte legal. O sistema é bem simples não, as regras são simples. No entanto, isso gera formas extremamente complexas, que geram cópias de si mesmas, geram coisas que se movimentam. Geram padrões que parecem tão complexos que nem parecem que vieram de algo tão simples, assim como a seleção natural agindo nos organismos, nas espécies, algo muito simples faz coisas que parecem extremamente complexas, parecem não, são complexas, mas as regras são simples.

No R, eu achei uma implementação bem simples do jogo da vida, e resolvi testar. Começando com uma distribuição aleatória de pontos, da para ver o que vira, e olha que legal minha primeira simulação.

conway

Primeiro, para a segunda geração, a gente ve algumas estruturas estáveis, persistentes ao longo do tempo, como quadrados grandes, que são exatamente um pontinho rodeado de mais três, logo todos persistem, até serem perturbados, perturbados por essa coisa gigante que fica crescendo muito louca ao longo das gerações.

To falando desses dois carinhas aqui:

Esse:

E esse:

São padrões bem simples, tanto que apareceram ao acaso facinho.

Mas na pagina do wikipedia, a gente vê algumas formas que parece que tem um padrão de movimento, outras que parecem naves viajando pela matriz, porque a imagem é na verdade uma matriz gigante com 0 para pixels mortos e 1 para pixel vivos, uma busca no google vai mostrar muitas imagens legais.

Mas olhas esses aqui:

Esse aqui deve ser difícil conseguir iniciando com uma matriz ao acaso, mas é so ver como ele é, e qual a probabilidade de atribuir um pontinho como vivo ou morto no começo que da para calcular a chance de ele aparecer ao acaso 🙂

Mas olha esse aqui:

Aqui a gente precisa de uma matriz bem grande, e muitas gerações para ver esse padrão legal.

Olhas so como alguns casos parecem com espaçonaves:

Ou essa que deixa para tras Gidlers, aquela coisinha que da tirinho.

Mas esse é um exemplo muito legal, de como a gente não precisa de modelos complexos, para chegar a resultados complexos, como na seleção natural, algumas regrinhas simples, um sistema bem simples na sua essência produz resultados magníficos, que as vezes demoramos a vida inteira contemplando sem conseguir entender completamente o que esta acontecendo.

Hehe, que fase profunda heim ^^.

Lembrando que esse script está no repositório recologia la no github.

#########################################################################
#Jogo da vida
#Script Original:
#http://johnramey.net/blog/2011/06/05/conways-game-of-life-in-r-with-ggplot2-and-animation/
#########################################################################
#install.packages("foreach")
library(foreach)
 
#Determina quantos vizinhos cada celula da matriz tem.
#Serve para implementar as regras do jogo
 
how_many_neighbors <- function(grid, j, k) {
  size <- nrow(grid)
  count <- 0
  if(j > 1) {
    count <- count + grid[j-1, k]
    if (k > 1) count <- count + grid[j-1, k-1]
    if (k < size) count <- count + grid[j-1, k+1]
  }
  if(j < size) {
    count <- count + grid[j+1,k]
    if (k > 1) count <- count + grid[j+1, k-1]
    if (k < size) count <- count + grid[j+1, k+1]
  }
  if(k > 1) count <- count + grid[j, k-1]
  if(k < size) count <- count + grid[j, k+1]
  count
}
 
#Retorna uma lista de matrizes, após a primeira, cada matriz é uma iteração.
#size: Tamanho da matriz
#num_reps: número de repetições
#prob: Chance de vida e morte para a configuração inicial.
 
game_of_life <- function(size=50,num_reps=10,prob=c(0.5,0.5),inicial=NA) {
  grid <- list()
  if(is.na(inicial)) {
    grid[[1]] <- replicate(size, sample(c(0,1), size, replace = TRUE, prob = prob))
  } else {
    grid[[1]] <- inicial
  }
  dev_null <- foreach(i = seq_len(num_reps) + 1) %do% {
    grid[[i]] <- grid[[i-1]]
    foreach(j = seq_len(size)) %:%
      foreach(k = seq_len(size)) %do% {
 
        #Aplicar as Regras de Conway
        num_neighbors <- how_many_neighbors(grid[[i]], j, k)
        alive <- grid[[i]][j,k] == 1
        if(alive && num_neighbors <= 1) grid[[i]][j,k] <- 0
        if(alive && num_neighbors >= 4) grid[[i]][j,k] <- 0
        if(!alive && num_neighbors == 3) grid[[i]][j,k] <- 1
      }
  }
  grid
}
 
game_grids <- game_of_life(size = 50, num_reps = 20, prob = c(0.9, 0.1))
 
 
#Plotando cada matriz da lista com image, usando o Sys.sleep para ter um intervalo
#por plot
 
for(i in 1:length(game_grids)) {
  image(game_grids[[i]],col=c("white","black"),xaxt="n",yaxt="n")
  box()
  title(paste("Geração ",i))
  Sys.sleep(time=1)
}

Leave a Reply

Your email address will not be published. Required fields are marked *