Implementación de autómata celular

Buenas a todos, tengo que implementar un autómata celular en java, para, con ayuda de algoritmos genéticos, solucionar el problema de la mayoría.

Lo voy a hacer en java porque es lo que más entiende el que me va a corregir... el caso es que me han aparecido algunas dudas.

Para el autómata he pensado en una clase "Organismo" con los siguientes atributos y operadores:
- Una lista de células
- Una array con los distintos estados que puede tomar una célula en nuestro organismo.
- Una tabla de reglas, que són las que marcan el cambio de estado de una célula en concreto.
+ evolucionar() provoca una evolución de un paso en el organismo, tomando la tabla de reglas
+ evolucionaCelula(celula) provoca la evolución de una célula enconcreto

Para la célula:
- Estado , representa el estado en que se encuentra mi célula
+ cambiaEstado(nuevo_estado) cambia el estado de la célula

Ademas de todas las operaciones get, set, y add que me puedan ser útiles.

Vamos con el problema... la tabla de reglas:

La tabla de reglas tiene esta pinta.
Imagen
(para un ejemplo sencillo)

El valor del centro representa mi célula, y el de los extremos los de las células adyascentes. Por ejemplo en la primera columna si mi célula está muerta (vale 0) y las dos adyascentes también pues permanece muerta. y en la última columna, si mi célula está viva (vale 1) y las de los extremos tambien (valen 1) entonces mi célula muere.

Se me han ocurrido algunas formas de diseñar en java una tabla de reglas, pero todas me parecen bastante chapuceras, y para una tabla de reglas sencilla puede funcionar, pero también tengo que trabajar sobre modelos de autómatas multidimensionales y eso ya se me podría ir de las manos.

Alguna sugerencia sobre los tipos de datos que me puede ser mas correctos?

He pensado en crear mi propio tipo abstracto de datos, Tabla de Reglas, con las operaciones comunes de una tabla de reglas, pero no se yo...

En fin, a ver si alguno puede echarme una mano. El tema de usar el algoritmo genético una vez que tengo el autómata celular mas o menos lo tengo controlado.

Saludos.
¿Por qué no conviertes la 'clave' (estado de tu célula y adyacentes) en un número y lo usas como índice para un array/vector?

No se tampoco qué esperas... el modelo de tabla creo que es el mejor. Aunque hay optimizaciones en espacio relativamente fáciles, no creo que merezcan la pena.

- ferdy
Ferdy escribió:¿Por qué no conviertes la 'clave' (estado de tu célula y adyacentes) en un número y lo usas como índice para un array/vector?

No se tampoco qué esperas... el modelo de tabla creo que es el mejor. Aunque hay optimizaciones en espacio relativamente fáciles, no creo que merezcan la pena.

- ferdy



Lo que dices arriba tiene todo el sentido, y ya lo había pensado, ya que las 7 columnas de una tabla de reglas para radio 1 (abarca 1 adyasceente a la izquierda y 1 adyascente a la derecha) son los números en binario del 0 al 7. y para radio 2 serían los números binarios del 0 al 31.

Mas que nada quería ver si había alguna implementación mejor... ya que nos evalúan, entre otras cosas, la eficiencia en espacio y tiempo. Aunque supongo que evaluarán la eficiencia del algoritmo genético (que es la parte que les interesa del trabajo)... ya comentaré si me surgen mas dudas.

En el método evolucionaCelula miro la célula de la izquierda, la mia y la de la derecha, voy a la tabla de reglas y cambio el valor de mi célula por el que viene en la tabla. Perfecto. Muchas gracias.
Hrm... la historia es, una tabla es relativamente 'eficiente' en espacio y acceso O(1). Si la tabla fuera demasiado grande, deberías intentar comprimirla.

Es más, si realmente quieres destacar, puedes hacerlo todo solo guardando un número (o alguno más según el grado de vecindad, radio y dimensión) Pero no se si dejarte eso como 'ejercicio mental'........ :)

- ferdy
Ferdy escribió:Hrm... la historia es, una tabla es relativamente 'eficiente' en espacio y acceso O(1). Si la tabla fuera demasiado grande, deberías intentar comprimirla.

Es más, si realmente quieres destacar, puedes hacerlo todo solo guardando un número (o alguno más según el grado de vecindad, radio y dimensión) Pero no se si dejarte eso como 'ejercicio mental'........ :)

- ferdy



Nunca he querido que nadie haga nada por mi... iré comentando progresos. Gracias ferdy
Una pista:

http://en.wikipedia.org/wiki/Rule_30
http://en.wikipedia.org/wiki/Rule_110
http://en.wikipedia.org/wiki/Rule_184

Lo único que cambia en la definición de esos autómatas es la 'regla'. Es sencillo extender esto a mayores índices de vecindad.

- ferdy
Lo pillé xD

Mil gracias.

La regla 30 toma los siguientes cambios 00011110 que es 30 en binario.

Ya me rayaba a mi lo de la clasficación de las reglas. no sabía que criterio se usaba para nombrarlas.

Gracias.

EDIT:
Pues me viene de perlas el saber esto, porque, entre otras cosas, lo que hay que hacer es un algoritmo genético que calcule la regla que hay que usar para llegar a un determinado estado final.

El algoritmo genético irá probando diferentes reglas, combinandolas entre ellas y mutándolas, y una forma rápida para generar las reglas es también una forma de mejorar la eficiencia.

EDIT: Again, ya tengo listo el autómata celular unidimensional, ahora le metes como argumento de entrada un número (el número de regla) y la evoluciona();

Por ejemplo para la regla 30:

Mi salida:

Imagen

Que a gran escala sería:

Imagen

Parametriza el diseño de esta concha:

Imagen


De hecho... si alguno habeis visto la peli de "guía del autoestopista galáctico" sabreis que la respuesta al sentido de la vida es "42", y creo que el porqué de ese número tiene algo que ver con los autómatas celulares.
Hi again, he seguido avanzando en el tema, ya tengo mi applet en java rulando, para autómatas unidimensionales y bidimensionales...

Imagen
Imagen
Imagen
Imagen
(esto ultimo es una animación del juego de la vida)


La putada viene a la hora de echar a andar el algoritmo genético... documentandome he encontrado que las reglas para solucionar el problema de la mayoría son, como mínimo, de radio 3.

De radio 3 hay 2^128 reglas... y con números tan elevados el algoritmo genético, segun los parámetros del mismo, puede estar funcionando horas, e incluso días. Si lo configuro para que tarde menos nunca encuentra una solución. De hecho los valores interesantes en cuanto a convergencia de evoluciones (al final se llegará a un estado final) son aquellos cercanos a la regla 0 o a la regla (2^128 -1)... y generalmente, al inicializar una población al azar de N elementos, desde el 0 hasta el 2^128, la probabilidad de obtener valores cercanos a estos límites es prácticamente nula.

La población del algoritmo genético (cada uno de los cromosomas) será una regla aleatoria.

Así es como tengo configurado el algoritmo genético:

La función objetivo que uso es la siguiente:

-Para cada cromosoma, calculo un número I de configuraciones iniciales de un autómata celular; evoluciono el autómata hasta un estado final, o un número determinado de veces, y calculo la fracción de evoluciones cuyo estado final sea el correspondiente a la solución del problema de la mayoría.

Los cruces entre cromosomas los hago del siguiente modo:

-Selecciono una fracción de la población que de el mejor resultado ("élite") y la paso directamente a la siguiente generación, el resto de cromosomas los hayo por cruces simples entre los miembros de la élite.

Las mutaciones se hacen sobre la siguiente generación provisional.

Tanto para las mutaciones como para los cruces, calcúlo un índice aleatorio que va a ser donde se cruzarán los cromosomas o donde mutará el cromosoma en cuestión.

Iteramos IT veces y nos quedamos con la regla de mejor resultado.

Espero que algún entendido del tema me pueda solucionar el problemilla que comento del algoritmo genético... nunca me da una solución buena.

Si alguien quiere el código MP, si veo que es necesario pondré 1 link
7 respuestas