Este año se cumplen 4 decadas de el desarrollo de unix en una DEC PDP-7 sobrante en los laboratorios BELL (ahora AT&T). Ken Thompson y Dennis Ritchie lo hecharon a andar para continuar sus torneos de Viajes Espaciales (un juego que Thompson habia desarrollado).
Sus compañeros se burlaban del sistema y le pusieron el nombre UNICS como una mofa a la falla del proyecto MULTICS (UNiplexed Information and Computed Service vs. Multiplexed Information and Computing Service). No hay registro a la fecha de cuando UNICS cambio su nombre por UNIX pero el mundo de la informática lleva ya 40 años de disfrutar de los derivados de esa plataforma.
jueves, 26 de marzo de 2009
viernes, 13 de marzo de 2009
Al inicio de "Sueño con serpientes"
"Hay hombres que luchan un día y son buenos. Hay otros que luchan un año y son mejores. Hay quienes luchan muchos años y son muy buenos. Pero hay los que luchan toda la vida: esos son los imprescindibles."
--Bertolt Brecht
--Bertolt Brecht
jueves, 12 de marzo de 2009
Algoritmo Genético Distribuido Sobre PVM
Sub-poblaciones estáticas con migración
Esta estrategia de paralelización consiste en utilizar un conjunto estático de sub-poblaciones independientes y utilizar un operador genético adicional de migración, mediante el cual, cada cierto número de generaciones se da el intercambio de individuos entre las poblaciones, como una forma de compartir material genético entre las mismas. Esto hace necesario la introducción de un conjunto de parámetros migratorios que determinen la periodicidad del proceso de migración, la cantidad de individuos a migrar en cada ocasión y las poblaciones destino de dichos individuos.
A esta estrategia de paralelización también se le conoce como modelo de islas, algoritmos genéticos distribuidos o algoritmos genéticos de grano grueso y su escalabilidad ha sido comprobada en varios trabajos [1-5].
Existen diversos modelos de migración para los algoritmos genéticos de grano grueso, los cuales incluyen modelos en anillo, y la migración aleatoria [6].
En el modelo de anillo, se determina la población de destino de cada elemento a migrar antes de iniciar el algoritmo. (figura 1)

En el modelo de migración aleatoria la población de destino se elige al azar en cada evento de migración. (figura 2)

Los efectos de la migración sobre los algoritmos genéticos en paralelo han sido abordados en [7-9]. En estos textos se obtienen resultados satisfactorios migrando porciones pequeñas de las sub-poblaciones (en el rango del 20%) lo cual es compatible con el objetivo de minimizar el uso del ancho de banda entre procesadores.
También existen diferentes estrategias para seleccionar los individuos a migrar que van desde la elección elitista de los individuos con mejor adaptación de cada población hasta la selección por torneo. La determinación dinámica de los parámetros migratorios se ha tratado en [5, 6, 10].
En este tipo de algoritmo, se denomina intervalo de migración al número de generaciones que se ejecutan en cada procesador antes del intercambio de material genético con los demás, mientras que a la cantidad de individuos que se seleccionan para migrar cada vez, se le denomina razón de migración.
Aplicación de prueba Sobre PVM
Para la aplicación de este algoritmo es conveniente tomar un ejemplo de optimización. El problema que se eligió para probarlo inicialmente es la minimización de la función de Goldstein-Price descrita en [11] la cual ha sido utilizada para el estudio de algoritmos genéticos. Esta función tiene un mínimo global en fG*(0,-1) = 3.
Después de efectuar varias pruebas empíricas con el algoritmo genético sin paralelizar, se escogió un conjunto de parámetros que en principio arrojaron soluciones prometedoras, estos parámetros se utilizaron como base para hacer pruebas del efecto de la variación del tamaño de población:
• Representación real, cromosoma X = [x1,x2].
• Rango de búsqueda para X (-100,100).
• Error máximo permitido 0.1 (cuando el error es mayor, se considera una convergencia prematura).
• Número máximo de generaciones GMAX = 100.
• Selección por torneo, con tamaño de torneo Z=2.
• Probabilidad de cruce PC = 0.7.
• Parámetro de cruzamiento generado de manera uniforme en (0,1).
• Probabilidad de mutación PM =0.1.
El código fuente escrito en C con migración para optimizar la función Goldstein-Price con licencia GPL puede descargarse desde
http://sistemas.itlp.edu.mx/mcastro/mdga.tgz
REFERENCIAS BIBLIOGRÁFICAS
1. Alba, E. and J.M. Toya, Analyzing Synchronous and Asyncrhonous Parallel Distributed Genetic Algorithms. Future Generation Computer Systems, 2001. 17(4): p. 451-465.
2. Alba, E. and M. Tomassini, Parallelism and Evolutionary Algorithms. IEEE Transactions on Evolutionary Computation, 2002. 6(5): p. 443-462.
3. Alba, E. and J.M. Troya, A Survey of Parallel Distributed Genetic Algorithms. 1997, Universidad de Málaga, Campus de Teatinos. p. 32.
4. Tomoyuki, H., M. Mitsunori, and T. Yusule, The Differences of Parallel Efficiency between the Two Models of Parallel Genetic Algorithms on PC Cluster Systems. Proceedings of The Fourth International Conference/Exhibition on High Performance Computing in Asia-Pacific Region, 2000: p. 945-948.
5. Berntsson, J. and M. Tang, Dynamic Optimization of Migration Topology in Internet-based Distributed Genetic Algorithms. Proceedings of the 2005 conference on Genetic and evolutionary computation GECCO '05, 2005: p. 1579-1580.
6. Hiroyasu, T., M. Miki, and M. Negami, Distributed Genetic Algorithms with Randomized Migration Rate, in IEEE Proceedings of Systems, Man and Cybernetics Conference SMC'99. 1999, IEEE Press. p. 689-694.
7. Matsumura, T., et al., Effects of Chromosome Migration on a Parallel and Distributed Genetic Algorithm. Proceedings. Third International Symposium on Parallel Architectures, Algorithms, and Networks, 1997. (I-SPAN '97), 1997: p. 357-361.
8. Rebaudengo, M. and M. Sonza Reorda, An Experimental Analysis of the Effects of Migration in Parallel Genetic Algorithms. Proceedings Euromicro WorkShop on Parallel and Distributed Processing, 1993, 1993: p. 232-238.
9. Alba, E., C. Cotta, and J.M. Troya, Numerical and Real Time Analysis of Parallel Distributed GAs with Structured and Panmictic Populations. Proceedings of the IEEE Conference on Evolutionary Computing (CEC), 1999. 2: p. 1019-1026.
10. Noda, E., et al., Devising Adaptive Migration Policies for Cooperative Distributed Genetic Algorithms. Proceedings of the IEEE Conference on Evolutionary Computation, 2002.
11. Jamshidi, M., et al., Robust Control Systems With Genetic Algorithms. Control Series, ed. R.H. Bishop. 2002, USA: CRC Press. 210.
Esta estrategia de paralelización consiste en utilizar un conjunto estático de sub-poblaciones independientes y utilizar un operador genético adicional de migración, mediante el cual, cada cierto número de generaciones se da el intercambio de individuos entre las poblaciones, como una forma de compartir material genético entre las mismas. Esto hace necesario la introducción de un conjunto de parámetros migratorios que determinen la periodicidad del proceso de migración, la cantidad de individuos a migrar en cada ocasión y las poblaciones destino de dichos individuos.
A esta estrategia de paralelización también se le conoce como modelo de islas, algoritmos genéticos distribuidos o algoritmos genéticos de grano grueso y su escalabilidad ha sido comprobada en varios trabajos [1-5].
Existen diversos modelos de migración para los algoritmos genéticos de grano grueso, los cuales incluyen modelos en anillo, y la migración aleatoria [6].
En el modelo de anillo, se determina la población de destino de cada elemento a migrar antes de iniciar el algoritmo. (figura 1)

Figura 1: Migración en anillo entre 7 poblaciones.
En el modelo de migración aleatoria la población de destino se elige al azar en cada evento de migración. (figura 2)

Figura 2: Migración aleatoria entre 7 poblaciones.
Los efectos de la migración sobre los algoritmos genéticos en paralelo han sido abordados en [7-9]. En estos textos se obtienen resultados satisfactorios migrando porciones pequeñas de las sub-poblaciones (en el rango del 20%) lo cual es compatible con el objetivo de minimizar el uso del ancho de banda entre procesadores.
También existen diferentes estrategias para seleccionar los individuos a migrar que van desde la elección elitista de los individuos con mejor adaptación de cada población hasta la selección por torneo. La determinación dinámica de los parámetros migratorios se ha tratado en [5, 6, 10].
En este tipo de algoritmo, se denomina intervalo de migración al número de generaciones que se ejecutan en cada procesador antes del intercambio de material genético con los demás, mientras que a la cantidad de individuos que se seleccionan para migrar cada vez, se le denomina razón de migración.
Aplicación de prueba Sobre PVM
Para la aplicación de este algoritmo es conveniente tomar un ejemplo de optimización. El problema que se eligió para probarlo inicialmente es la minimización de la función de Goldstein-Price descrita en [11] la cual ha sido utilizada para el estudio de algoritmos genéticos. Esta función tiene un mínimo global en fG*(0,-1) = 3.
Después de efectuar varias pruebas empíricas con el algoritmo genético sin paralelizar, se escogió un conjunto de parámetros que en principio arrojaron soluciones prometedoras, estos parámetros se utilizaron como base para hacer pruebas del efecto de la variación del tamaño de población:
• Representación real, cromosoma X = [x1,x2].
• Rango de búsqueda para X (-100,100).
• Error máximo permitido 0.1 (cuando el error es mayor, se considera una convergencia prematura).
• Número máximo de generaciones GMAX = 100.
• Selección por torneo, con tamaño de torneo Z=2.
• Probabilidad de cruce PC = 0.7.
• Parámetro de cruzamiento generado de manera uniforme en (0,1).
• Probabilidad de mutación PM =0.1.
El código fuente escrito en C con migración para optimizar la función Goldstein-Price con licencia GPL puede descargarse desde
http://sistemas.itlp.edu.mx/mcastro/mdga.tgz
REFERENCIAS BIBLIOGRÁFICAS
1. Alba, E. and J.M. Toya, Analyzing Synchronous and Asyncrhonous Parallel Distributed Genetic Algorithms. Future Generation Computer Systems, 2001. 17(4): p. 451-465.
2. Alba, E. and M. Tomassini, Parallelism and Evolutionary Algorithms. IEEE Transactions on Evolutionary Computation, 2002. 6(5): p. 443-462.
3. Alba, E. and J.M. Troya, A Survey of Parallel Distributed Genetic Algorithms. 1997, Universidad de Málaga, Campus de Teatinos. p. 32.
4. Tomoyuki, H., M. Mitsunori, and T. Yusule, The Differences of Parallel Efficiency between the Two Models of Parallel Genetic Algorithms on PC Cluster Systems. Proceedings of The Fourth International Conference/Exhibition on High Performance Computing in Asia-Pacific Region, 2000: p. 945-948.
5. Berntsson, J. and M. Tang, Dynamic Optimization of Migration Topology in Internet-based Distributed Genetic Algorithms. Proceedings of the 2005 conference on Genetic and evolutionary computation GECCO '05, 2005: p. 1579-1580.
6. Hiroyasu, T., M. Miki, and M. Negami, Distributed Genetic Algorithms with Randomized Migration Rate, in IEEE Proceedings of Systems, Man and Cybernetics Conference SMC'99. 1999, IEEE Press. p. 689-694.
7. Matsumura, T., et al., Effects of Chromosome Migration on a Parallel and Distributed Genetic Algorithm. Proceedings. Third International Symposium on Parallel Architectures, Algorithms, and Networks, 1997. (I-SPAN '97), 1997: p. 357-361.
8. Rebaudengo, M. and M. Sonza Reorda, An Experimental Analysis of the Effects of Migration in Parallel Genetic Algorithms. Proceedings Euromicro WorkShop on Parallel and Distributed Processing, 1993, 1993: p. 232-238.
9. Alba, E., C. Cotta, and J.M. Troya, Numerical and Real Time Analysis of Parallel Distributed GAs with Structured and Panmictic Populations. Proceedings of the IEEE Conference on Evolutionary Computing (CEC), 1999. 2: p. 1019-1026.
10. Noda, E., et al., Devising Adaptive Migration Policies for Cooperative Distributed Genetic Algorithms. Proceedings of the IEEE Conference on Evolutionary Computation, 2002.
11. Jamshidi, M., et al., Robust Control Systems With Genetic Algorithms. Control Series, ed. R.H. Bishop. 2002, USA: CRC Press. 210.
PVM
PVM (Parallel Virtual Machine) es un paquete de software libre desarrollado por el Oak Ridge National Laboratory. Con PVM es posible hacer que una colección heterogénea de computadoras conectadas en red funcione como una sola computadora paralela, lo cual permite la ejecución y programación de aplicaciones paralelas en red, mediante el modelo de paso de mensajes.
PVM está escrito en C y cuenta con librerías que soportan la generación de aplicaciones en C, C++ y Fortran.
Algunas de las características principales de PVM incluyen las siguientes:
• Conjunto de máquinas definido por el usuario: El usuario puede elegir a través de una consola, de entre las máquinas conectadas al cluster, en cuales de ellas se va a ejecutar una tarea. Incluso las máquinas que forman parte de ese conjunto pueden ser agregadas o eliminadas dinámicamente, lo cual es una característica importante para la implementación de tolerancia a fallos.
• Acceso traslúcido al hardware: Los usuarios pueden utilizar un acceso transparente al hardware, en el que se permite que PVM decida la asignación de tareas o puede asignarse de manera explícita cuál máquina ejecutará cada tarea, para explotar mejor las capacidades del hardware.
• Computación basada en procesos: La unidad de paralelismo en PVM es una tarea, que es un hilo independiente de control que se alterna entre los estados de comunicación y cálculos. No existe un mapeo directo entre tareas y procesadores. De hecho es posible ejecutar varias tareas en una sola máquina.
• Modelo de paso de mensajes Explícito: Un conjunto de tareas cooperan en la solución de un problema enviándose mensajes entre sí. El tamaño de los mensajes sólo está limitado por la cantidad de memoria de cada computadora.
• Soporte de heterogeneidad: PVM soporta la heterogeneidad en términos de computadoras, redes y aplicaciones. Con respecto al paso de mensajes, PVM permite que mensajes que contienen más de un tipo de datos puedan ser intercambiados entre computadoras con diferentes formas de representación de datos.
• Soporte de multiprocesadores: PVM utiliza las facilidades nativas de paso de mensaje en computadoras paralelas, para hacer uso de las ventajas de este tipo de hardware subyacente. Algunos distribuidores proveen versiones de PVM optimizadas para sus arquitecturas particulares, que pueden comunicarse con las versiones públicas de PVM.
El sistema PVM está compuesto por dos partes: la primera parte es un daemon (llamado pvmd3 y a veces abreviado como pvmd) que se ejecuta en cada computadora conectada a la máquina virtual. Este proceso residente o daemon es el responsable de mantener la comunicación que
permite el paso de mensajes y la creación y eliminación de tareas en el cluster.
La segunda parte es un conjunto de librerías que permiten a las aplicaciones hacer uso de las características que ofrece PVM.
Instalación
Un cluster PVM está compuesto por un nodo maestro y varios nodos esclavos.
Para instalar PVM, es necesario que los nodos que van a ser incluidos en el cluster puedan accederse entre ellos mediante sus hostnames. Esto puede lograrse configurando un DNS o agregando dichos nombres en los archivos de hosts de cada uno de los nodos.
Para la ejecución de los procesos de forma remota, PVM utiliza por omisión RSH. Sin embargo, debido a que este es un protocolo que ya ha caído en desuso, se recomienda que se configure en cada nodo el servicio SSH. Posteriormente se puede recompilar PVM con la opción de utilizar SSH o simplemente crear una variable de entorno que le indica a PVM que utilice SSH y no RSH como su método de ejecución remota.
Para instalar PVM en Scientific Linux, basta con seleccionar el paquete al momento de instalar el sistema operativo, o instalarlo posteriormente desde los discos de la distribución.
Si se tiene acceso a internet, se puede instalar el paquete mediante un
yum -y install pvm
También es posible descargar y compilar el código fuente de PVM desde:
http://www.netlib.org/pvm3/index.html
Antes de utilizar el paquete, deben crearse las siguientes variables de entorno en cada nodo del cluster:
• PVM_ROOT: que debe contener la ruta donde esta instalado PVM. Para Scientific Linuxes: /usr/share/pvm3
• PVM_ARCH: que debe contener el nombre de la arquitectura para la cual se ha compilado (o se va a compilar) PVM. Por ejemplo LINUXI386 para computadoras que ejecutan una versión de Linux con un procesador compatible con el 386 de Intel.
• PVM_RSH: Que permite seleccionar el programa que se utilizará para lanzar procesos en cada nodo del cluster. Se recomienda utilizar /usr/bin/ssh.
Para que estas variables se carguen de manera automática, al iniciar la sesión de cada usuario que vaya a utilizar PVM, se pueden agregar las siguientes líneas a su archivo .bashrc:
PVM_ROOT=/usr/share/pvm3
PVM_ARCH=LINUXI386
PVM_RSH=/usr/bin/ssh
export PVM_ROOT PVM_ARCH PVM_RSH
De forma opcional, es recomendable agregar al PATH el directorio donde se encuentran las librerías de pvm, lo cual permite la ejecución de la consola y aimk (una herramienta para la compilación automática que funciona sobre make). Esto se logra agregando la cadena $PVM_ROOT/lib a la variable PATH
Por ejemplo:
PATH=$PATH:$HOME/bin:$PVM_ROOT/lib
Acto seguido, pueden compilarse en cada nodo las aplicaciones de ejemplo de PVM que vienen en el directorio $PVM_ROOT/examples. Esto puede hacerse cambiándose a dicho directorio y ejecutando el comando aimk all, el cual compila todos los ejemplos incluidos con PVM.
Los ejecutables son depositados automáticamente por aimk en el directorio $PVM_ROOT/bin/$PVM_ARCH.
Una vez hecho esto en cada nodo del cluster es posible dar de alta una máquina paralela virtual ejecutando el comando PVM en el nodo maestro y agregando, desde esta consola cada uno de los nodos esclavos mediante el comando add , SSH pedirá el password para poder acceder a cada uno de ellos. Para esto, es recomendable que en cada computadora se cree una cuenta con el mismo nombre de usuario, que permita acceder al cluster. El comando quit, permite salir de la consola de pvm sin dar de baja el cluster y ejecutar los ejemplos (como master1 o hello) desde la línea de comandos.
La página del proyecto PVM permite acceder a un manual de referencia muy completo, escrito por sus desarrolladores, que cubre la instalación y el desarrollo de aplicaciones en esta plataforma. Dicho manual está disponible en formato postscript y html en:
http://www.csm.ornl.gov/pvm/pvm_home.html
PVM está escrito en C y cuenta con librerías que soportan la generación de aplicaciones en C, C++ y Fortran.
Algunas de las características principales de PVM incluyen las siguientes:
• Conjunto de máquinas definido por el usuario: El usuario puede elegir a través de una consola, de entre las máquinas conectadas al cluster, en cuales de ellas se va a ejecutar una tarea. Incluso las máquinas que forman parte de ese conjunto pueden ser agregadas o eliminadas dinámicamente, lo cual es una característica importante para la implementación de tolerancia a fallos.
• Acceso traslúcido al hardware: Los usuarios pueden utilizar un acceso transparente al hardware, en el que se permite que PVM decida la asignación de tareas o puede asignarse de manera explícita cuál máquina ejecutará cada tarea, para explotar mejor las capacidades del hardware.
• Computación basada en procesos: La unidad de paralelismo en PVM es una tarea, que es un hilo independiente de control que se alterna entre los estados de comunicación y cálculos. No existe un mapeo directo entre tareas y procesadores. De hecho es posible ejecutar varias tareas en una sola máquina.
• Modelo de paso de mensajes Explícito: Un conjunto de tareas cooperan en la solución de un problema enviándose mensajes entre sí. El tamaño de los mensajes sólo está limitado por la cantidad de memoria de cada computadora.
• Soporte de heterogeneidad: PVM soporta la heterogeneidad en términos de computadoras, redes y aplicaciones. Con respecto al paso de mensajes, PVM permite que mensajes que contienen más de un tipo de datos puedan ser intercambiados entre computadoras con diferentes formas de representación de datos.
• Soporte de multiprocesadores: PVM utiliza las facilidades nativas de paso de mensaje en computadoras paralelas, para hacer uso de las ventajas de este tipo de hardware subyacente. Algunos distribuidores proveen versiones de PVM optimizadas para sus arquitecturas particulares, que pueden comunicarse con las versiones públicas de PVM.
El sistema PVM está compuesto por dos partes: la primera parte es un daemon (llamado pvmd3 y a veces abreviado como pvmd) que se ejecuta en cada computadora conectada a la máquina virtual. Este proceso residente o daemon es el responsable de mantener la comunicación que
permite el paso de mensajes y la creación y eliminación de tareas en el cluster.
La segunda parte es un conjunto de librerías que permiten a las aplicaciones hacer uso de las características que ofrece PVM.
Instalación
Un cluster PVM está compuesto por un nodo maestro y varios nodos esclavos.
Para instalar PVM, es necesario que los nodos que van a ser incluidos en el cluster puedan accederse entre ellos mediante sus hostnames. Esto puede lograrse configurando un DNS o agregando dichos nombres en los archivos de hosts de cada uno de los nodos.
Para la ejecución de los procesos de forma remota, PVM utiliza por omisión RSH. Sin embargo, debido a que este es un protocolo que ya ha caído en desuso, se recomienda que se configure en cada nodo el servicio SSH. Posteriormente se puede recompilar PVM con la opción de utilizar SSH o simplemente crear una variable de entorno que le indica a PVM que utilice SSH y no RSH como su método de ejecución remota.
Para instalar PVM en Scientific Linux, basta con seleccionar el paquete al momento de instalar el sistema operativo, o instalarlo posteriormente desde los discos de la distribución.
Si se tiene acceso a internet, se puede instalar el paquete mediante un
yum -y install pvm
También es posible descargar y compilar el código fuente de PVM desde:
http://www.netlib.org/pvm3/index.html
Antes de utilizar el paquete, deben crearse las siguientes variables de entorno en cada nodo del cluster:
• PVM_ROOT: que debe contener la ruta donde esta instalado PVM. Para Scientific Linuxes: /usr/share/pvm3
• PVM_ARCH: que debe contener el nombre de la arquitectura para la cual se ha compilado (o se va a compilar) PVM. Por ejemplo LINUXI386 para computadoras que ejecutan una versión de Linux con un procesador compatible con el 386 de Intel.
• PVM_RSH: Que permite seleccionar el programa que se utilizará para lanzar procesos en cada nodo del cluster. Se recomienda utilizar /usr/bin/ssh.
Para que estas variables se carguen de manera automática, al iniciar la sesión de cada usuario que vaya a utilizar PVM, se pueden agregar las siguientes líneas a su archivo .bashrc:
PVM_ROOT=/usr/share/pvm3
PVM_ARCH=LINUXI386
PVM_RSH=/usr/bin/ssh
export PVM_ROOT PVM_ARCH PVM_RSH
De forma opcional, es recomendable agregar al PATH el directorio donde se encuentran las librerías de pvm, lo cual permite la ejecución de la consola y aimk (una herramienta para la compilación automática que funciona sobre make). Esto se logra agregando la cadena $PVM_ROOT/lib a la variable PATH
Por ejemplo:
PATH=$PATH:$HOME/bin:$PVM_ROOT/lib
Acto seguido, pueden compilarse en cada nodo las aplicaciones de ejemplo de PVM que vienen en el directorio $PVM_ROOT/examples. Esto puede hacerse cambiándose a dicho directorio y ejecutando el comando aimk all, el cual compila todos los ejemplos incluidos con PVM.
Los ejecutables son depositados automáticamente por aimk en el directorio $PVM_ROOT/bin/$PVM_ARCH.
Una vez hecho esto en cada nodo del cluster es posible dar de alta una máquina paralela virtual ejecutando el comando PVM en el nodo maestro y agregando, desde esta consola cada uno de los nodos esclavos mediante el comando add , SSH pedirá el password para poder acceder a cada uno de ellos. Para esto, es recomendable que en cada computadora se cree una cuenta con el mismo nombre de usuario, que permita acceder al cluster. El comando quit, permite salir de la consola de pvm sin dar de baja el cluster y ejecutar los ejemplos (como master1 o hello) desde la línea de comandos.
La página del proyecto PVM permite acceder a un manual de referencia muy completo, escrito por sus desarrolladores, que cubre la instalación y el desarrollo de aplicaciones en esta plataforma. Dicho manual está disponible en formato postscript y html en:
http://www.csm.ornl.gov/pvm/pvm_home.html
miércoles, 11 de marzo de 2009
Frases
Have the courage to be ignorant of a great number of things, in order to avoid the calamity of being ignorant of everything
-- Sydney Smith
Freud decía que:
"Existen dos maneras de ser feliz en esta vida: una es hacerse el idiota y la otra serlo".
Empiezo a considerar la primera opción, pero me gustaría creer que existe una tercera manera de ser feliz en la vida
-- Sydney Smith
Freud decía que:
"Existen dos maneras de ser feliz en esta vida: una es hacerse el idiota y la otra serlo".
Empiezo a considerar la primera opción, pero me gustaría creer que existe una tercera manera de ser feliz en la vida
martes, 10 de marzo de 2009
Bienvenidos
Bienvenidos a mi blog, donde espero tener entradas sobre linux, tecnología, algoritmos genéticos, software libre y lo que se me vaya ocurriendo.
Suscribirse a:
Comentarios (Atom)
