viernes, 25 de mayo de 2012

Extra:Autómatas Celulares

Autómatas Celulares (Mejorado)

Para esta entrada modificamos el programa de autómatas celulares que habiamos presentado en la práctica 2 con la idea de mejorarlo.

Nuestra idea de mejorarlo era la de agregar un montón de reglas para que se pudiera elegir que regla usar y no usar siempre la misma (anteriormene solo usabamos una regla, la 30), mas sin embargo como no pudimos encontrar una gran cantidad de ellas (sus resultados, para cada trio de celdas), solo nos dimos a la tarea de agregar 5 reglas, que pensamos que son las mas importantes o utilizadas, ya que de las demas no encontramos mas que muestras de las imágenes que se podían llegar a crear.
Otro edición que se hizo (un poco boba, pero hay que mensionarla) fué la de editar el tamaño de las celdas, para que se pudieran apreciar mejor las figuras que se puedan formar al correr el programa.

Las reglas que anexamos a nuestro programa son:
Regla 150

Código
La parte más importante del código que editamos:
Las reglas se cargan al comienzo del programa, en vectores, se pregunta que regla se desea usar  y  se muestras las opciones disponibles después mediante condiciones se evalúa cual se desea usar.



Después de esto solo seguimos el mismo procedimiento que en la versión anterior para ir validando los grupos de celdas y el resultado después de la validación se toma de los resultados almacenados para cada regla al comienzo del programa.


Resultados
A continuación dejamos unas capturas de pantalla, utilizando en cada una de ellas diferentes reglas:


Resultado Utilizando la Regla 30


Resultado Utilizando la Regla 90


 Resultado Utilizando la Regla 110


 Resultado Utilizando la Regla 150


 Resultado Utilizando la Regla 184



Referencias Bibliográficas
http://en.wikipedia.org/wiki/Elementary_cellular_automaton
http://sist-adaptativos.blogspot.mx/2012/03/practica-no.html

Práctica 4

Sistema multi-agente

Introducción 

Tratamos realizar un sistema básico relacionado con multi-agente  relacionado con un ambiente donde varios agentes realicen una acción.

Objetivo:

Programar un sistema para poder simular un sistema en que los agentes realizaran una acción de recoger algo en su camino y llevar eso objeto a un lugar específico donde este otro agente y que ese agente realice otra tarea con ese objeto mientras el agente anterior regrese a su camino para seguir recogiendo objetos encontrados a lo largo de su trayecto.
Justificación
Se escogió este tipo de sistema por ser sencillo y practico demostrando la funcionalidad de los sistemas multi-agentes de manera sencilla y fácil de entender con este tipo de ejemplos básicos en programación de  multi-agente.

Desarrollo

El programa fue en base  a un código encontrado en la red, el cual modificamos algunas cosas donde tratamos de mejorar el movimiento de los agentes en el ambiente.
El sistema cuenta con dos agentes R1 y R2, donde R1 se mueve en el ambiente de rejilla por rejilla analizando que no haya basura en cada una de las rejillas, si el R1 encuentra basura, R1 recolecta esa basura y la lleva con R2 que se encarga de “incinerarla” mientras que R1 regresa a la posición donde encontró la ultima basura y continua su exploración.
Para poder  compilar el programa es necesario instalar algunos paquetes requeridos, ya que se necesitan para poder realizar de manera simple los sistemas  multi-agente. Los paquetes necesarios son “Jason” el cual es una librería para programación en java y JADE que es necesaria para la programación de agentes y por ultimo JEdit para programar, y es necesario agregar las librerías al proyecto para poder compilar sin complicaciones.
Una mejora podría ser que tu mismo agregues la basura en la casilla que desees y no que se posicione por default, para que el agente valla y recoja esa basura y la lleve al otro agente para incinerar dicha basura y así sucesivamente, esto para hacer mas dinámico el sistema.



Código:






















Resultado:

jueves, 24 de mayo de 2012

Optimizacion Estructural de Grafos. Busqueda de Caminos cortos con el algoritmo Dijkstra

Introducción:
Para esta entrada, eligiéremos una estructura, la modelaremos como un grafo y posteriormente utilizaremos el algoritmo de búsqueda de caminos cortos de  Dijkstra para encontrar la ruta mas corta dado un punto origen a un punto destino.

Justificación:


Dada la intención  de en algún futuro desarrollar un sistema de búsqueda de caminos óptimos a gran escala, que represente datos reales de un determinado lugar como lo puede ser una ciudad, un conjunto de carreteras, etc, se opto por realizar una pequeña implementacion.

Desarrollo:


A continuación mencionaremos las fases en el desarrollo.

Primeramente revisaremos el aspecto teórico.
El algoritmo de Dijkstra, también llamado algoritmo de caminos mínimos, es un algoritmo para la determinación del camino más corto dado un vértice origen al resto de vértices en un grafo con pesos en cada arista. Su nombre se refiere a Edsger Dijkstra, quien lo describió por primera vez en 1959.

Este consiste en ir explorando todos los caminos más cortos que parten del vértice origen y que llevan a todos los demás vértices; cuando se obtiene el camino más corto desde el vértice origen, al resto de vértices que componen el grafo, el algoritmo se detiene .

Nosotros modelamos un grafo con puntos de interés en a Cd. de Monterrey.

El grafo en cuestión es un grafo ponderado no dirigido.

Después transformamos el grafo en su respectiva matriz adyacente.





Esta matriz en cuestión representa los datos del grafo, de esta forma es como podemos computar dichos datos. Aquí representamos los pesos de las aristas como las distancias de un punto a otro,  en caso de no haber un camino directo de un punto a otro, lo podemos marcar con un 0 o con el símbolo de infinito 00

La lógica principal del programa consiste en ir recorriendo cada nodo del grafo y de ahí analizar todas las distancias, de ahí elegimos la mas corta, y guardarla en un arreglo, para posteriormente pasar al siguiente nodo y realizar el mismo proceso. Este algoritmo, simplemente se guía por la búsqueda de un camino con menor peso, sin llegar a considerar otras posibles rutas, que en algunos casos pueden resultar mucho mejores.







El objetivo principal que se tenia previsto era que mediante parámetros especificaríamos los puntos de origen y destino y de ahí se procedería a realizar el proceso, solo que había pequeños detalles, ya que teníamos problemas al elegir determinado nodo, se realizaba el proceso y este volvía a sumar las distancias de los nodos ya procesados. Es por ello que primeramente quisimos implementar algo que me calcule la distancia de un punto a otro y me la imprima, posteriormente implementar algo mas complejo.


Referencias:

http://es.wikipedia.org/wiki/Algoritmo_de_Dijkstra
http://www.youtube.com/watch?v=6rl0ghgPfK0

miércoles, 2 de mayo de 2012

Práctica No. 3: Detección Facial


Práctica No.3

Introducción
El tema que elegimos para esta práctica es el de Detección de Rostros por medio de un programa escrito en python y de una especie de librería que se realiza o se obtiene por medio de un entrenamiento (adquisición y procesamiento de imágenes) para poder reconocer los patrones de las imágenes deseadas.
Todo esto apoyándonos de medios externos como librerías y otras herramientas para facilitar y sobre todo acelerar el proceso, ya que es muy largo.
La librería encargada del procesamiento de las imágenes para el entrenamiento es la llamada OpenCV (Open Source Computer Vision) y algunas herramientas que nos permitieron avanzar más rápido en la recopilación y la organización de las imágenes son: objectmarker, haarconv y algunos archivos .bat que aceleraron la creación de los catálogos de las imágenes a procesar.
Objetivo
El objetivo principal durante el desarrollo de esta práctica fue el de crear un programa que fuera capaz de detectar rostros en imágenes mediante la obtención de éstas con una cámara web, también se puede llamar: detección de rostros en tiempo real, esto con la finalidad de profundizar un poco más en el tema y apoyar de alguna manera el avance de nuestro proyecto en clase.
Objetivo que logramos, aunque no con un 100% en cuanto a la calidad de la detección debido al tiempo que requiere el procesamiento de imágenes.

Justificación
El motivo de nuestra elección se basa en que este tema o práctica es un fragmento en cuanto a la realización de nuestro proyecto en la clase, por lo que nos permitiría acortar la curva de aprendizaje en cuanto a lo requerido en la clase, avanzado un poco más rápido y  además de que con esto nos podemos centrar en un sola actividad e invertir todo nuestro tiempo a un solo tema y no todo lo contrario, ya que tendríamos que dividir nuestro tiempo en la realización de más actividades.

Desarrollo
En cuanto al desarrollo, los principales pasos y los más laboriosos fueron:

1.- La adquisición de los paquetes, software y herramientas necesarias, ya que hay que realizar pruebas (como habíamos comentado en la parte del avance) y verificar la compatibilidad de todos estos paquetes ya que de lo contrario no podríamos haber continuado.
2.- La parte más laboriosa y más importante del proceso fue la de la recopilación y la organización de las imágenes, creación de los catálogos para el proceso de entrenamiento o haartraining como también es conocido debido la aplicación de la librería OpenCV que se utiliza (haartraining.exe). 

Para el proceso de entrenamiento es necesaria la recopilación de fotografías o imágenes, clasificadas en positivas (las imágenes donde no aparece el objeto a reconocer) y positivas (donde si aparece el objeto a reconocer), además de la creación de catálogos, que no son más que archivos .txt con una lista de las direcciones de las imágenes y en el caso de las positivas además de las direcciones hay que agregar las coordenadas de donde comienza el espacio ocupado por el objeto reconocer y también las distancias de largo y ancho del espacio ocupado por el objeto, esto con la finalidad de indicar la posición del objeto dentro de la imagen.
En nuestro caso para realizar el entrenamiento y para que nuestro entrenamiento fuera de una calidad aceptable (excelente sería con el uso a partir de 1500 positivas y 5000 negativas), recopilamos y utilizamos la cantidad de 200 imágenes positivas (que en su totalidad son fotografías de un compañero donde aparece su rostro en diferentes condiciones de iluminación) y 1100 imágenes negativas (que obviamente son imágenes donde no aparece ningún tipo de rostro humano), todas con un tamaño de 320x240 pixeles para tratar de ayudar a localizar más fácilmente el objeto a reconocer y por lo tanto reducir el tiempo de entrenamiento.
Para la creación del catálogo de las positivas no valimos de una herramienta llamada objectmarker y para el catálogo de las negativas de un archivo .bat solo añadía la direccion de las imágenes a un .txt.

Proceso de creación del catálogo positivo utilizando objectmarker
Después hay que crear una muestra de las imágenes positivas, esto haciendo uso de una herramienta incluida en el paquete de OpenCV llamada createsamples.exe que arrojara un archivo .vec (que se utiliza en el siguiente punto) se utiliza dándole opciones que vienen listadas en la documentación de OpenCV, como la cantidad de la muestra y el directorio de salida de la aplicación.

Ya con la muestra y los catálogos listos, procedimos al proceso que involucra la mayor cantidad de tiempo en esta práctica, el entrenamiento que se realiza con la herramienta haartraining.exe y que arrojaría el archivo .xml necesario para la detección de rostros; también se ejecuta con opciones (listadas en la documentación), una opción al haartraining que se llama stages, que es la cantidad de escenarios en los que se evaluará el procesamiento de las imágenes
.
Durante este paso tuvimos que tomar una gran decisión (que podría poner en riesgo la entrega a tiempo de nuestra práctica), el de detener o no el proceso de entrenamiento, ya que debido a la cantidad de imágenes a procesar el tiempo que tardaría era considerablemente alto (que verdaderamente pensamos que tardaría algo de tiempo pero no en esa magnitud) y necesitábamos que terminara para poder continuar, ya que al iniciar el proceso de entrenamiento se le da la opción stages (en nuestro caso 30 para garantizar buena calidad); en nuestro caso el entrenamiento se encontraba en el stage 18 de 30 y la cantidad de tiempo invertido era alrededor de 2 días y horas, entonces la incógnita era si podíamos detener o no el proceso y podríamos utilizar los datos obtenidos durante ese tiempo.

Nos decidimos a detener el entrenamiento y encontramos una herramienta llamada haarconvert.exe que fue creada precisamente con ese objetivo, el de la creación de archivos .xml en base a entrenamiento interrumpidos.
Con esta utilidad construimos nuestro .xml y procedimos a la creación de nuestro código para la realización de las pruebas de nuestra librería creada mediante el entrenamiento trunco.

3.- Después de la recopilación de información, lectura y compresión de algunos ejemplos (la mayoría de ellos con un grado muy alto de complejidad), comenzamos las pruebas para la construcción de nuestro código que ejecutaría nuestra librería (obtenida con el entrenamiento), que en un principio solo ejecutaba le visualización de imágenes en tiempo real (mostrado durante el avance) y que posteriormente modificamos y logramos que se ejecutara y tomara de referencia nuestra librería de entrenamiento. Para verificar que funcionara correctamente o que al menos hiciera lo que nosotros queríamos y para descartar un fallo en nuestro entrenamiento, hicimos uso de un archivo .xml incluido en los paquetes de OpenCV que contenía un entrenamiento de reconocimiento de rostros y que por su puesto funcionaba correctamente.

Código
Los fragmentos mas importantes de nuestro código son: en el que se detectan las caras y en el que se muestras detección de las caras.


 
 
Resultados
Los resultados se pueden visualizar mejor en el video, pero a manera de referencia para verificar la calidad de nuestro programa como ya habíamos comentado, utilizamos un .xml incluido en el paquete de OpenCV y realizamos algunas comparaciones:

En cuanto a calidad de la detección de los rostros:
Obviamente nuestro entrenamiento fue superado pero tomando en cuenta la cantidad de imágenes, el tiempo invertido y el truncamiento del proceso e entrenamiento, el resultado de nuestro programa en cuanto a la detección de rostros supero ampliamente nuestras expectativas.
Para la detección en el nuestro hay que estar un poco más estático, sobre todo cuando se encuentra mas de una cara frente a la cámara, mientras que el otro no necesita de mucha ausencia de movimiento para realizar estas acciones.
Otro factor del que dependen mucho la detección de los rostros, es el de las condiciones de iluminación, bajo las cuales se realice el proceso.

En cuanto a la lentitud del programa durante la ejecución:
Nuestro programa corre un poco más fluido, tal vez debido a la mayor carga por parte del otro entrenamiento en cuanto a imágenes y el procesamiento de estas.


Video
En el primer video se ejecuta el programa haciendo el uso del archivo.xml que obtuvimos a partir del proceso de entrenamiento que llevamos a cabo y en el segundo se ejecuta el programa pero con el .xml incluido en la libreria OpenCV.

Al comparar las dos ejecuciones se llegaron a los resultados ya mencionadas arriba.





Conclusiones
El aprendizaje durante esta práctica ha sido muy extenso y de mucha utilidad, ya que los conocimiento que adquirimos pueden ser aplicados directamente en el proyecto que estamos llevando a cabo en clase y así nos facilitará el desarrollo de éste.
Algunas experiencias y que a la vez pueden ser aplicadas como recomendaciones, son las obtenidas específicamente en el proceso de entrenamiento que básicamente es la administración de los debidos tiempos para cada cosa, ya que como ya lo habíamos mencionado, este proceso requiere de una gran cantidad de tiempo y va a depender directamente de la cantidad de imágenes a procesar y esto está ligado directamente a la calidad del entrenamiento.

Pocas Imágenes = Entrenamiento Veloz = Entrenamiento de Baja Calidad
Muchas Imágenes = Entrenamiento Lento = Entrenamiento de Alta Calidad

Entonces la mejor recomendación que podemos dar, es que hagan una relación debido a los tres puntos anteriores y en base a eso establezcan la cantidad de imágenes que procesaran.

Otra recomendación, muy importante, es que al trabajar con la librería OpenCV y el entrenamiento, este proceso no esta del todo optimizado para realizarse rápidamente, es decir, que el entrenamiento no variará mucho dependiendo de la computadora que se use, es decir, no aprovecha al máximo los recursos de la computadora que se use, por lo que la recomendación cae en una pequeña investigación que realizó un compañero sobre como mejorar este proceso para que fuera más rápido, por lo que nos encontramos con una tecnología un poca más nueva por parte de la compañía Intel, llama Intel TBB (Threading Building Blocks)  que básicamente implementa una aplicación que realiza las mismas tareas que el haartraining incluido en OpenCV, pero con la diferencia de que esta aplicación si se encuentra optimizada para aprovechar mejor los recursos de la computadora en la que se realice el entrenamiento; con esto se puede aprovechar al máximo la capacidad de los procesadores de ultima generación, haciendo uso de todos sus núcleos para el entrenamiento cosa que las aplicaciones estándar de OpenCV no pueden hacer, lo mismo ocurre con las cantidades de memoria RAM disponibles.
Como es de esperarse esta herramienta no viene incluida junto con OpenCV, por lo que hay que descargar aparte y realizar una serie de pasos para poder instalarla y utilizarla.


Referencias Bibliográficas
http://opencv.willowgarage.com/documentation/python/index.html
http://www.slideshare.net/edgar007/opencv-entrenamiento12
http://threadingbuildingblocks.org/
http://www.shervinemami.co.cc/faceRecognition.html
http://wikipedia.org

jueves, 26 de abril de 2012

Avance: Práctica 3
Reconocimiento de Patrones: Detecccion Facial (Face Detection)

Esto es de lo que va a tratar nuestra práctica, vamos a utilizar el lenguaje Python en su versión 2.6.6 y la librería OpenCV en su versión 2.1.0, para trabajar sobre Windows.

Basicamente los pasos para nuestra practica son:
  • Adquisición de imágenes: que son los conjuntos de imagenes que va a tomar nuestro programa para crear un conocimiento básico y asi poder validar posteriormente los rostros. Para este paso son necesarias alrededor de 5000 imágenes negativas y 1500 positivas, para que nestro programa sea de nu buen nivel.
  • Crear muestra: Con estas imáges se crea una muestra, que mas que nada son datos que se obtienen de las imágenes para posteiormente ser utilizadas.
  • Entrenamiento: Este es el proceso más importante, ya que usando las nuestras creadas con anterioridad, nuestro programa se entrenara y creara nuevo conocimiento para poder asi ser más exacto y poder validar los rostros.
Un fragmento de código, que solo lanza camara de video y muestra imagenes en tiempo real:

Referencias:
http://sistemasadaptativosd.blogspot.mx/
http://opencv.willowgarage.com/documentation/python/index.html

lunes, 26 de marzo de 2012

Práctica No.2

Práctica No. 2 : Autómatas Celulares


Introducción

Para este ejercicio realizamos una actividad con el Juego de la Vida involucrando el tema de Autómatas Celulares y la Regla 30,  algunos puntos acerca de autómatas celulares dada por Wikipedia.org : 

  • Un autómata celular es un modelo matemático para un sistema dinámico que evoluciona en pasos discretos. 
  • Los autómatas celulares pueden ser usados para modelar numerosos sistemas físicos que se caractericen por un gran número de componentes homogéneos y que interactúen localmente entre sí. 
  • El juego de la vida es el mejor ejemplo de un autómata celular, diseñado por el matemático británico John Horton Conway en 1970.
  • La Regla 30 es una regla unidimensional binaria para Autómatas Celulares introducido por Stephen Wolfram en 1983.

Objetivo

El objetivo que nos planteamos al elegir esta actividad es el de elaborar un programa que simule el Juego de la Vida implementando la Regla 30 para autómatas celulares y que se capaz de, tomando un conjunto de condiciones iniciales(vector inicial), evaluarlo y arrojar una respuesta correcta.



Justificación
La elección de esta opción fue motivada debido a los patrones que se mostraron en clase al ejecutar este tipo de programas, es decir, los "dibujitos" o las animaciones que se pueden elaborar  implementando esta técnica, en resumen, nos llamo mucho la atención todo este tipo de animaciones.

Desarrollo
Desde un principio decidimos que la regla que utilizaríamos sería la Regla 30, ya que anteriormente ya habíamos tenido la oportunidad de trabajar con ella, después de esto 
lo siguiente que hicimos para desarrollar esta actividad fue la de plantear como se analizarían los grupos de células o celdas para poder dar el resultado y tambien como iba a ser guardado ese dato. 
Al haber analizado con detalle lo anterior coincidimos que el tipo de estructura de datos mas acorde al proyecto es la utilización de vectores o listas y que para analizarlos tendríamos que ir recorriendo de 3 en 3 celdas, utilizando rangos para no tocar las demás celdas e insertando el resultado en el vector que almacenaría la respuesta) debido a que el manejo de vectores o listas resulta más fácil en el lenguaje de programación Python (o al menos para nosotros), lo adoptamos y  comenzamos a estudiar y a programar en dicho lenguaje (ya que no teníamos conocimientos acerca del uso de este lenguaje) para seguir el proceso.

La implementación y las pruebas al principio se realizaron solo en modo terminal, hasta que el  programa arrojó los resultados correctos(para comprobarlo, utilizamos el ejercicio de autómatas celulares que venía en la guía que nos proporciono la Dra. Sara para el examen de medio curso) fue cuando entonces comenzamos en su implementación gráfica y continuamos realizando pruebas para este paso(buscando la opción más adecuada para la representación visual de las celdas nos topamos con que podríamos utilizar Labels con su respectivo color para representar las celdas) y continuando con las pruebas, despues teniamos que trabajaren como íbamos a ubicar las celdas(los labels negros/blancos) correctamente, buscamos y encontramos una opción (una función o método) que se utiliza alternativamente al método "pack()" para añadir elementos a una ventana y establecer su ubicación, esta función conocida como "grid()" que recibe como parámetros una coordenada (x,y) para establecer su ubicación en la ventana.
Se realizaron la respectiva pruebas y verificaciones(para que todo estuviera correcto) para esta última modificación y se concluyo el desarrollo de esta actividad.

Código
Los fragmentos de código más importantes de nuestro programa son en los que se analiza el vector base y se arroja la solución en otro :




Resultados
Los resultados obtenidos fueron los esperados, ya que el objetivo era que aplicando la Regla 30 se pudiera validar un conjunto de condiciones iniciales y se obtuviera una respuesta correcta. 

Los resultados se pueden apreciar mejor en el siguiente video, donde en primera instancia se evalúa el problema que se planteó en la guía del examen de medio curso y posteriormente se evalúan un conjunto de condiciones ingresadas al azar(sin sentido):



Dibujito :P


Conclusiones
En general, el aprendizaje en esta práctica fué y es muy grande, ya que nos vimos en la necesidad de implementar y aprender el lenguaje Python, tal vez no en su totalidad, pero si de una manera un poco más adentrada que otros cursos.
En cuanto a experiencias y recomendaciones se puede mencionar que para la realización de esta práctica(y muy posiblemente aplicable en otros casos) era necesario que la demostración final tenía que ser visual(gráfica),  este punto no fue el centro durante el desarrollo, si no que nos enfocamos primero en que funcionara correctamente aún en modo terminal y al final se implemento la parte gráfica.

Sabemos que nuestro programa no esta perfeccionado del todo, pero realiza las funciones para las cuales fue desarrollado, mas sin embargo se puede añadir nuevas opciones, que tal vez fueron pasadas por alto debido a su poca funcionalidad o su alta complejidad, y que fueron evitadas para no involucrar más tiempo en el desarrollo y poder entregar a tiempo, como por ejemplo:
  • Analizar mas conjuntos de condiciones iniciales, para elaborar más patrones de diseño.
  • Validar que los elementos que se ingresan sean exclusivamente de tipo binario.
  • Realizar un mejor manejo del uso de memoria para las listas o vectores
  • Establecer una especie de "zoom-in/zoom-out" para tener una mejor visión del resultado cuando se realizan evaluaciones de vectores grandes y/o grandes cantidades de iteraciones/ciclos.
Referencias:
-Definición de Autómatas Celulares en Wikipedia.
-Graficos con Phytom. Tkinter.  
-Guia de aprendizaje Phytom.


jueves, 23 de febrero de 2012

Laboratorio Programación de Sistemas Adaptativos. Practica1

Introducción:
El objetivo de esta práctica de Laboratorio, consiste en programar algoritmos que se adapten a su entorno.
Aplicándolo a un caso práctico,  se planea un Sistema de Semáforos que se adapten a su entorno.
Resolución del problema:
Nuestra principal idea consistió primeramente en definir cada uno de los carriles, posteriormente analizar la lógica de cada uno de los semáforos, es decir si uno estará en verde, cual cambiara en rojo.
Posteriormente trabajar en la parte de adaptación, es decir: se planeo originalmente que el carril detectara hasta que punto debería de cambiar, para permitir el acceso o restringirlo.
Por ejemplo si en un determinado carril se comienza a llenar con objetos que simulan vehículos, dar preferencia a una luz verde a ese carril.
Para ello, se planeo utilizar Treads donde se manejen cada uno de los carriles, de esta forma un hilo podría estar generando instancias, independientemente de los otros hilos.
Problemática:
Los retos a los que nos enfrentamos al tratar de resolver esta práctica fueron los siguientes:
Al trabajar con hilos, nos planteamos la siguiente pregunta: ¿Cuántos hilos implementaremos?
Si trabajábamos con esto, nuestro principal reto seria la sincronización de los mismos.
Pasamos mucho tiempo analizando esta temática, que dejamos a segundo término otras cuestiones igualmente importantes.

¿Que Aprendimos?
Nos involucramos mucho en el manejo de hilos en Java.
Aprendimos a enfocarnos más a la problemática principal a resolver  y no primeramente en  cosas secundarias.
Como coordinarnos mejor  para las futuras practicas.

En conclusión, nuestra practica no fue completamente lo que esperábamos, ya que por varios factores, no se concluyo por completo. En si este "Simulador" se sincroniza para cada cambio de luz.
Seguiremos trabajando en el,  y en los próximos días publicaremos los resultados obtenidos. 

Los dejamos con un breve vídeo de los resultados trabajados hasta el momento:

http://www.youtube.com/watch?v=ypaaiUmn58A&feature=youtu.be&fb_source=message