April 2008 - Posts
En enero, me vi sorprendido por una implementación de grid computing en el browser, leer
Grid Computing in the browser
En estos últimos años hemos asistido al crecimiento de potencia y uso de JavaScript, con nuevas librerias y el uso intensivo de sus capacidades de prototipos y redefinición de funciones. Eso y otros elementos (como el XMLHttpRequest) han hecho surgir lo que se ha llamado Ajax. También tenemos librerías que convierten código en el servidor en código en el cliente, tengo que estudiar Volta de Microsoft, por ejemplo.
Esta semana, gracias a la lista de ClubSmalltalk me entero del estado del proyecto de Diego Gomez Deck (a quien creo recordad de las reuniones de SUGAR, Smalltalk User Group de Argentina, en los noventa): el Smalltalk Web Toolkit, pueden ver el blog del proyecto:
http://ceibo.wordpress.com/
Copio la descripción que enviara Hernan G, a esa lista:
¿Cuáles son las cualidades de este nuevo framework?
SWT rompe con la asimetría del protocolo HTTP, es decir, a través del hack Comet, ahora el servidor puede enviar contenido a los clientes conectados. Esto hace que se quiebre la barrera impuesta por el protocolo HTTP y el servidor no solamente pueda enviar contenido solo con un pedido del cliente, sino que a través de esto, en cualquier evento que se produzca en el servidor pueden ser informados los clientes (o los navegadores).
¿Cuál es su arquitectura?
SWT consta de una parte cliente y una servidora. Es decir, el comportamiento del cliente lo desarrollamos íntegramente sobre Smalltalk. Gracias a un framework que traduce de Smalltalk a Javascript contamos con un mini-ambiente Smalltalk del lado del navegador. A partir de este esquema, se puede contar con un MVC (Model-View-Controller) distribuido. Este MVC logra ciertas optimizaciones para presevar el recurso más limitado, la red.
¿De donde obtengo más información?
En el blog ceibo.wordpress.com podrán encontrar información de cómo usarlo, ejemplos, links a downloads, tutoriales, etc.
Ceibo es un proyecto de barajas 3D sobre la web que usará SWT como arquitectura.
Interesante lo de Comet:
http://es.wikipedia.org/wiki/Comet
Comet es una técnica de programación Web muy similar a AJAX, que utiliza XMLHttpRequest, se utiliza para la entrega de datos entre cliente servidor a través del protocolo HTTP, y la entrega de datos se hace sin que el cliente lo haya solicitado.
Comet también es conocido como server push, HTTP push, HTTP streaming, Pushlets, Reverse Ajax, y otros.
Jeje... de nuevo el XMLHttpRequest... grande el chiquitín.... :-)
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Estuve jugando con el nuevo CTP release de Microsoft Robotics Developer Studio. Tiene nuevas características, como instalación y ejecución de un diagrama de Visual Programming Language en muchos nodos.
Para explorar algo de esta nueva funcionalidad, escribí el sueño de todo programador: un programa de dibujo distribuido multiusuario...;-)... Bueno, es uno bastante simple, pero funciona, y puede ejecutarse en varias máquinas, exponiendo y compartiendo nuestros más inspirados dibujos de mouse. El código puede ser descargado desde aquí.
El proyecto
Tengo la versión 1.5 del MSRS y el nuevo CTP MRDS (nueva sigla), ejecutándose en la misma máquina, sin mayores problemas. Comencé creando un nuevo proyecto del tipo Simple Dss Service RDS 2008:
El proyecto contiene un service component llamado DssScribble, y un Windows form, que está a cargo del dibujo:
Al comienzo del service component, crea el formulario, y lo connecta para usar los ports y su cola de dispatcher:
protected override void Start()
{
base.Start();
// Add service specific initialization here.
WinFormsServicePort.Post(new RunForm(CreateForm));
}
private Form CreateForm()
{
return new CanvasForm(_mainPort, linePort, TaskQueue);
}
Cada línea que el usuario dibuja en la ventana es enviada al service component, para ser distribuido a cada subscriptor interesado en el dato:
[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> PostLineHandler(PostLine postLine)
{
SendNotification<PostLine>(_submgrPort, postLine);
yield break;
}
Las líneas son recibidas en el NewLineHandler (el modo de conectar dos componentes es via VPL, como veremos más adelante). El linePort es el port para comunicarse con la instancia del formulario:
[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> NewLineHandler(NewLine newLine)
{
linePort.Post(newLine.Body);
newLine.ResponsePort.Post(DefaultUpdateResponseType.Instance);
yield break;
}
El service component no tiene estado. Uso una clase para transportar la información de las nuevas líneas a dibujar y distribuir:
[DataContract()]
public class DssScribbleState
{
}
[DataContract()]
public class DssScribbleLine
{
[DataMember()]
public int fromX;
[DataMember()]
public int fromY;
[DataMember()]
public int toX;
[DataMember()]
public int toY;
public DssScribbleLine()
{
}
public DssScribbleLine(int fromX, int fromY, int toX, int toY)
{
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
}
Dibujando con VPL
El Visual Programming Language es una herramienta fascinante, lleno de "features". Se puede arrastrar y soltar services components desde la toolbar. Cuando esta herramienta es lanzada, se puede buscar el DssScribble service en el área inferior izquierda:
Arrastré dos instancias del DssScribble service component, y las renombre a DssScribble1 y DssScribble2:
Conecté las instancias, así pueden escuchar sus notificaciones. Cada línea producida en una instancia es transmitida a la otra. De esta manera, lo que dibujemos en una ventana, aparecerá en la otra.
La conexión es entre la notificación PostLine y la notificación NewLine:
Para lanzar la aplicación, ir al menú Run -> Start. Aparece una ventana, mostrando el log de mensajes:
Esperamos unos momentos, y dos instancias del componente DssScribble son creados, cada uno mostrando un formulario. Podemos dibujar en cualquiera de los dos, arrastrando el mouse, siendo reproducido el dibujo en el otro formulario:
Este es mi autorretrato: una lágrima se me escapa, de la emoción de un dibujo distribuido.... ;-)
Ejecutando en nodos distribuidos
La IDE del VPL IDE tiene un diseñador de nodo. A la derecha, hay una rama Node en el árbol del proyecto. Cada nodo representa un DSS host conteniendo servicios DSS. Agregué dos nodos, el primero conteniendo una instancia del Scribble y arrastré la segunda instancia al segundo nodo:
Noten el panel inferior derecho: definí ahí las propiedades para el nodo Windows0, en el mismo localhost, pero con otras puertas (el primer nodo correrá en las puertas 50000/50001). En otro proyecto, probé tener una máquina remota, y la aplicación distribuida funcionó sin problemas. Podemos definir varios nodos, cada uno en una máquina distintas, poner en ellos instancias de DssScribble, enlazarlas por notificaciones, y podemos dibujar con nuestro compañeros de trabajo.... ;-)
Para ejecutar la aplicación en forma distribuida, se debe compilarla. Usar el menú Build -> Compile as a Service . Debe ingresarse un directorio donde generar el código y la solución. Entonces, la herramienta VPL compila solución, y genera los paquetes de instalación. Se puede abrir la solución generada con Visual Studio (el código es muy interesante, bastante astuto, implementando, por lo que ví, una máquina de pila, ver los métodos Decrement, Increment).
Cada nodo debe tener corriendo un servicio llamado package deployer, que ejecuta en otra puerta (la misma para todos los nodos, el valor asumido es 55555). Ir a ejecutar el directorio bin de Microsoft Robotics Developer Studio, y ejecutar el rundeployer.cmd:
Nota: si queremos compilar el servicio de nuevo, debemos parar el deployer: el generador de código usa el directorio bin y trae conflictos con el deployer andando.
Ahora, estamos listos para distribuir nuestra "killer app": ejecutar Run -> Run on distributed nodes. El sistema avisa de tener los deployers ya andando:
Y la magia comienza: cada nodo es contactado, y la aplicación es instalada en ellos. Un nodo DSS es iniciado en cada nodo, y sus correspondientes instancias de servicios son creadas. En este ejemplo, tendremos dos nuevas ventanas de consola, ejecutando cada una un nodo DSS. Esta es la ventana de mi segundo nodo:
Ahora, cada noda muestra su ventana de dibujo, y la diversión comienza.... :-)
Notas
No estoy usando partners en este ejemplo. En cambio, uso notificaciones de eventos, en este caso, nuevas líneas, así otros componentes pueden recibir esas notificaciones. Podemos escribir otros componentes, otras ventanas de dibujo, para recibir y procesar las líneas. Una idea es usar las coordenadas de una nueva línea para controlar el motor de un robot, o para persistir las líneas producidas usando un componente de persistencia nuestro. Para controlar el motor de un robot, podemos usar VPL, sin necesidad de reescribir el componente original.
Conclusiones
Usando VPL podemos componer nuevas aplicaciones usando componentes ya existentes. Podemos crear nuestras propias actividades. Y usando diagramas de nodos (en VPL o usando el DSS Manifest Editor) con el packager deployer, podemos distribuir la aplicación en muchos físicos nodos, en cualquier manera que creamos conveniente. Pero debemos definir cada nodo y componente: no hay facilidades para programar una grilla, con nodos dinámicos. Una aplicacion gridificada para DSS puede ser escrita, pero en mi opinión, debe ser creada con código nuestro. Idea para explorar: escribir una aplicación de control, usando package deployer, instalara tareas en los nodos en una grilla.
Todas estas herramientas abrieron mi cabeza. Escribir DSS services components es una nueva forma de pensar y programar, algo que quise explorar por años: cómo escribir objetos con un proceso de mensajes de una vía, en una forma distribuida y paralala (AjAgents está motivado por esa objetivo). Me imagino un sistema que modele las ideas de Minsky sobre la mente humana.
Bueno, es un nuevo mundo. Dorothy: no estamos más en Kansas... ;-)
Angel "Java" Lopez
http://www.ajlopez.com
Esta semana pasado, el gigante de Redmond anunció su nueva creación, Live Mesh (tech preview):
https://www.mesh.com/Welcome/Welcome.aspx
Gracias al post de Arvindra Sehmi:
http://blogs.msdn.com/asehmi/archive/2008/04/24/introducing-live-mesh.aspx
tenemos ahí una lista de comentarios sobre el nuevo bebé Microsoft. Esta nuevo producto de Redmond no es fácil de describir brevemente, pero merece que se le preste atención. Es una incursión de Microsoft en Web 2.0 y en su propia creación, Software plus Service.
(para bloggers, noten el uso de enlaces con screenshots, buena idea Arvindra!)
Este video explica la arquitectura a alto nivel (gracias a Matias Woloski por este link)
http://channel9.msdn.com/Showpost.aspx?postid=399577
In la lista de artículos de Arvindra, encuentro esta introducción de la inefable Mary Jo Foley
Ten things to know about Microsoft's Live Mesh
Leamos el punto uno:
1. The definition. As has become the norm with so many of its Software + Services products and strategies, Microsoft isn’t the best at coming up with a succinct Live Mesh definition. The closest I found (in a Live Mesh reviewer’s guide) was this: “Live Mesh is a ’software-plus-services’ platform and experience from Microsoft that enables PCs and other devices to ‘come alive’ by making them aware of each other through the Internet, enabling individuals and organizations to manage, access, and share their files and applications seamlessly on the Web and across their world of devices.” If I were in charge of defining Live Mesh, I think I’d go with “a Software + Services platform for synchronization and collaboration.”
Acá detecto algunas ideas de Bill Joy para Jini, una tecnología que nació demasiado temprano:
The Jini Technology Vision
Jini technology redefines the concept of a client. Instead of a fixed set of "local" devices, Jini technology supplies the Java client with a federation of remote "plug and play" devices in a dynamic configuration (the Jini Federation) that is personalized for each client. With Jini technology, the network truly becomes the client computer!
Toda esta nueva movida de MS podría ser el resultado visible de algunas ideas de Ray Ozzie, expresadas hace años en el notable memo:
The Internet Services Disruption
Supongo que Microsoft se está moviendo más y más hacia (recordemos el asunto Yahoo). Es una compañía que adopta la frase de Andy Grove: solo los paranoicos sobreviven. Tienen apuesta en RIA (Rich Internet Applications), Silverlight, Web 2.0, Rich Client... Todos los números de la ruleta están cubiertos, aún el doble cero... ;-)
Una nota: me asombra, que después de todo este esfuerzo, Microsoft todavía siga revelando nuevas herramientas solamente pare residentes de EE.UU. Google, por el contrario, pone sus innovaciones a disposición del mundo, sean betas o lo que sea. Toc, toc, McFly.... algún MS VP leyendo esto? ;-)
Angel "EverMeshed" Lopez
http://www.ajlopez.com
El domingo pasado, el bueno de Arvindra Sehmi referenció en un post suyo a un trabajo mío sobre una killer application que escribí: un scribble distribuido :-) Pero luego también escribió sobre este robot:
Es de Boston Dynamics, according to Wikipedia:
http://www.bostondynamics.com/
http://en.wikipedia.org/wiki/Boston_Dynamics
Boston Dynamics is a small engineering and robotics design company best known for the development of BigDog, a quadruped robot designed for the U.S. military with funding from DARPA [1], and DI-Guy, COTS software for realistic human simulation. Early in the company's history, it worked with the American Systems Corporation under a contract from the Naval Air Warfare Center Training Systems Division (NAWCTSD) to replace naval training videos for aircraft launch operations with interactive 3D computer simulations featuring DI-Guy characters. [2]
Marc Raibert is the company's president and project manager. He spun the company off from the Massachusetts Institute of Technology in 1992.[3]
Que bien resuelto está el tema de caminar y mantener el equilibrio y balance en distintas situaciones, y hasta hacer algún galope. Es notable que se haya logrado un algoritmo que implemente esa conducta. Según el bueno de Leandro Boffi (que además de mago se dedica a la robótica), eso se llama equilibrio dinámico.
Bueno, dejo algunos enlaces en
http://del.icio.us/ajlopez/robotics (últimamente, muy orientado a Microsoft Robotics Developer Studio)
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
En estos días, estuve investigando algo sobre grid computing y Microsoft Robotics Studio, usando DSS y CCR. Encontré un interesante documento:
High Performance Multi-Paradigm Messaging Runtime Integrating Grids and Multicore Systems
Los autores son Xiaohong Qiu, Geoffrey C. Fox, Huapeng Yuan, Seung-Hee Bae, de la Indiana University de Bloomington, y George Chrysanthakopoulos, Henrik Frystyk Nielsen, de Microsoft Research. Nielsen y Chrysanthakopoulos son los "creadores" del Concurrency and Coordination Runtime (CCR) y de Decentralized Software Services (DSS), tecnologías que son pilares de Microsoft Robotics Studio, y que pueden ser usandas más allá de robótica. Más información sobre estas tecnologías en:
http://www.microsoft.com/robotics
El "abstract" del documento dice:
eScience applications need to use distributed Grid environments where each component is an individual or cluster of multicore machines. These are expected to have 64-128 cores 5 years from now and need to support scalable parallelism. Users will want to compose heterogeneous components into single jobs and run seamlessly in both distributed fashion and on a future “Grid on a chip” with different subsets of cores supporting individual components. We support this with a simple programming model made up of two layers supporting traditional parallel and Grid programming paradigms (workflow) respectively. We examine for a parallel clustering application, the Concurrency and Coordination Runtime CCR from Microsoft as a multi-paradigm runtime that integrates the two layers. Our work uses managed code (C#) and for AMD and Intel processors shows around a factor of 5 better performance than Java. CCR has MPI pattern and dynamic threading latencies of a few microseconds that are competitive with the performance of standard MPI for C.
¿Que es MPI? Son las siglas de Message Passing Interface. Según la Wikipedia:
Message Passing Interface (MPI) is both a computer specification and is an implementation that allows many computers to communicate with one another. It is used in computer clusters.
Hay una There is a implementación de Microsoft:
Microsoft Message Passing Interface (MS MPI) is an implementation of the MPI2 specification by Microsoft for use in Windows Compute Cluster Server to interconnect and communicate (via messages) between High performance computing nodes. It is mostly compatible with the MPICH2 reference implementation, with some exceptions for job launch and management. MS MPI includes bindings for C and FORTRAN languages. It supports using the Microsoft Visual Studio for debugging purposes.
Gua! FORTRAN..... Esos buenos viejos días! ;-). Recuerdo haber trabajado con la implementación de Lisp en Fortran del bueno de Gregory Chaitin, en el siglo pasado. Pero no hay vuelta atrás, parafraseando a David Hilbert: Nadie nos expulsará del paraiso que Java y .NET han creado para nosotros.... ;-). Pueden leer la cita original en este interesante thread.
Pero estoy divagando. Volvamos al tema.
Los principales sitios sobre MPI son:
http://www.mpi-forum.org/
http://www.open-mpi.org/
http://www.lam-mpi.org/
Yo estaba pensando en implementar algo de las ideas de MPI en .NET o Java, cuando encuentro:
http://www.purempi.net/
PureMpi.NET is a completely managed implementation of the message passing interface. The object-oriented API is simple, and easy to use for parallel programming. It has been developed based on the latest .NET technologies, including Windows Communication Foundation (WCF). This allows you to declaratively specify the binding and endpoint configuration for your environment, and performance needs. When using the SDK, a programmer will definitely see the MPI'ness of the interfaces come through, and will enjoy taking full advantage of .NET features - including generics, delegates, asynchronous results, exception handling, and extensibility points.
PureMpi.NET allows you to create high performance production quality parallel systems, with all the benefits of in .NET
Es una implementación lista para bajar y usar, con VS 2005 o VS 2008. Usa generics para implementar canales tipados en MPI.
Me bajé la librería, y la instalé en una máquina con Visual Studio 2008. El programa de instalación agregó un nuevo template de proyecto, Mpi.NET:
Cree un proyecto, que aparece:
Modifiqué el Program.cs a:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mpi;
namespace Mpi.NET1
{
class Program
{
static void Main(string[] args)
{
ProcessorGroup.Process("MPIEnvironment",
delegate(IDictionary<string, Comm> comms)
{
Comm comm = comms["MPI_COMM_WORLD"];
Console.WriteLine(comm.Rank);
IAsyncResult result =
comm.BeginSend<string>(0, "", "Rank: " + comm.Rank, TimeSpan.FromSeconds(30), null, null);
if (comm.Rank == 0)
{
for (int i = 0; i < comm.Size; i++)
{
string receivedMsg =
comm.Receive<string>(i, Constants.AnyTag, TimeSpan.FromSeconds(30));
Console.WriteLine(receivedMsg);
}
}
comm.EndSend<string>(result);
});
}
}
}
La clase ProcessGroup se encarga de los procesos a ejecutar. Notar el uso de delegados para especificar el proceso. Un proceso MPI recibe un diccionario de objetos Comm, que son los canales para comunicarse con otros procesos MPI.
La clase ProcessGroup tiene esta estructura (según la información de metadata):
namespace Mpi
{
public class ProcessorGroup : IDisposable
{
public ProcessorGroup(Environment environment, Processor processor);
public ProcessorGroup(string environment, Processor processor);
public Environment Environment { get; }
public ICollection<IAsyncResult> Results { get; }
public void Dispose();
protected virtual void Dispose(bool disposing);
public static void Process(string environmentConfigName, Processor processor);
public void Start();
public void WaitForCompletion();
}
}
El número y configuración de procesadores puede ser definida en el archivo App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Mpi" type="Mpi.ConfigurationSection, Mpi"/>
</configSections>
<Mpi>
<Environments>
<Environment name="MPIEnvironment">
<Hosts>
<Host comms="MPI_COMM_WORLD"
client="MpiClient1"
service="MpiService1" />
<Host comms="MPI_COMM_WORLD"
client="MpiClient2"
service="MpiService2"/>
<Host comms="MPI_COMM_WORLD"
client="MpiClient3"
service="MpiService3"/>
</Hosts>
</Environment>
</Environments>
</Mpi>
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:8080/MpiService" binding="netTcpBinding"
bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient1">
<identity>
<userPrincipalName value="" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:8081/MpiService" binding="netTcpBinding"
bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient2">
<identity>
<userPrincipalName value="" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:8082/MpiService" binding="netTcpBinding"
bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient3">
<identity>
<userPrincipalName value="" />
</identity>
</endpoint>
</client>
<behaviors>
<serviceBehaviors>
<behavior name="MpiServiceBehavior">
<serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false"
includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MpiServiceBehavior" name="MpiService1">
<endpoint address="net.tcp://localhost:8080/MpiService" binding="netTcpBinding"
bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" />
</service>
<service behaviorConfiguration="MpiServiceBehavior" name="MpiService2">
<endpoint address="net.tcp://localhost:8081/MpiService" binding="netTcpBinding"
bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" />
</service>
<service behaviorConfiguration="MpiServiceBehavior" name="MpiService3">
<endpoint address="net.tcp://localhost:8082/MpiService" binding="netTcpBinding"
bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" />
</service>
</services>
</system.serviceModel>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
</configuration>
Jeje, usan <host..>... Me recuerda a AjMessages... ;-)
La ejecución de programa produce:
Bueno, no vamos a decir "Huy, que bruto que programa", pero es mi primer programa MPI. Hay 3 "ranks", porque así esta configurado en el archivo de arriba.
Encontran varios ejemplos ejecutables en la distribución de Pure MPI.NET. En mi opinión, es una interesante implementación de ideas de MPI, con algunas vueltas de tuerca adaptadas al mundo .NET: generics y delegates , bienvenidos.
¿Grid y MPI? Puede ser. Tengo que estudiar las referencias mencionadas en el "paper" que nombré al principio. Aunque ese trabajo está dedicado a cuestiones de alto rendimiento, tiene un buen resumen conceptual de los modelos de ejecución, y las relaciones posibles entre MPI, CCR, y DSS.
(Había publicado este artículo en "anglish", Angel's English, en:
Message Passing Interface, CCR, DSS, and Pure MPI.NET
)
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com
El año pasado había implementado un ejemplo con AjAgents usando CCR:
Agentes usando Concurrency and Coordination Runtime (CCR)
Agents using Concurrency and Coordination Runtime (CCR)
Escribí en mi blog en "anglish" (Angel's English) algunas ideas para explorar:
Agents in a Grid
Recordemos que Concurrency and Coordination Runtime es parte de Microsoft Robotics Studio, puede leer más sobre esta librería en
Concurrent Affairs: Concurrency and Coordination Runtime
y consultar mis enlaces de Delicious
http://del.icio.us/ajlopez/ccr
http://del.icio.us/ajlopez/msrs
En estos días, extendí mi ejemplo AjAgentsCCR-0.1.zip con dos nuevos proyectos. Uno de consola AjAgents.Genetic01, y otro de ventanas AjAgents.WinGenetic01:
La idea básica es ejecutar un algoritmo genético usando agentes, los elementos de AjAgents, que se envían mensajes usando ports de CCR. Cada agente procesa sus mensajes entrantes, y envía mensajes salientes a otros agentes, en paralelo. El problema que encaro es el clásico Travelling Salesman Problem. Leo en la Wikipedia:
If a salesman starts at point A, and if the distances between every pair of points are known, what is the shortest route which visits all points and returns to point A?
La ventana de ejemplo es sencilla:
La clase Genoma representa el viaje (una lista de Points y un valor de distancia total):
class Genoma
{
public List<Point> travel = new List<Point>();
public int value;
}
class Point
{
public int x;
public int y;
}
Al comenzar la ejecución, los agentes son creados y conectados:
best = new BestSoFar();
evaluator = new Evaluator();
mutator = new Mutator();
collector = new Collector();
evaluator.Collector = collector;
collector.Mutator = mutator;
collector.Evaluator = evaluator;
collector.BestSoFar = best;
mutator.Evaluator = evaluator;
Un genoma inicial es creado:
Genoma genoma = new Genoma();
Random rnd = new Random();
for (int k = 0; k<40; k++)
{
Point pt = new Point();
pt.x = rnd.Next(12);
pt.y = rnd.Next(12);
genoma.travel.Add(pt);
}
genoma.value = evaluator.CalculateValue(genoma);
El agente BestSoFar dispara un evento. El formulario se registra como observador de ese evento, para refrescar el mejor viaje calculado y dibujarlo. El programa envía el genoma inicial generado al agente Mutator, varias veces, para generar la primeras poblaciones:
best.NewBest += BestGenoma;
for (int k = 0; k < 60; k++)
{
mutator.Post("Mutate", genoma);
}
Noten el uso del método Post, básico en AjAgents. Cada agente implementa ese método, que invoca un método en el agente, usando una puerta de CCR para invocar el método final. El método es ejecutado entonces no en el momento, sino en forma "paralela", en un thread que maneja el pool de threads de CCR.
Un diagrama simple para explicar la interacción entre agentes:
El Mutator envía cada genoma al Evaluator. Este agente calcula el valor asignado a ese genoma. Lo envía a el Collector. Este implementa una nueva idea para este ejemplo: en vez de tener una clase Population o similar, el Collector recive genomas, y cuando tiene n o más genomas, determina los mejores del conjunto, envía el mejor a BestSoFar, y reenvía los mejores a Mutator, para generar una nueva lista de genomas a evaluar. Como método típico de ejemplo, tomemos uno de la clase Collector:
void ProcessList(List<Genoma> list)
{
list.Sort(comparer);
bestsofar.Post("Process",list[0]);
evaluator.Post("Evaluate",list[0]);
evaluator.Post("Evaluate",list[1]);
for (int k = 0; k < 4; k++)
{
mutator.Post("Mutate",list[k]);
mutator.Post("Mutate",list[k]);
}
}
Tengo que mejorar el algoritmo genético. Ahora, sólo usa mutación, sin hacer "crossover" (cruzamiento) entre los mejores genomas. El resultado que consigue ahora, no es óptimo: puede dar como resultado un máximo local, pero no la mejor solución. La idea del ejemplo es ver ejecutando AjAgents con CCR, en una prueba de concepto.
Conclusiones
Uno puede ver cada agente como una pequeña célula u organismo, que reacciona a mensajes externos y envía mensajes a otros agentes. Cada agente está levemente acoplado a los demás. En estos ejemplos, los agentes son creados y relaciones por código, pero bien podrían ser creados y relacionados usando algún framework de inyección de dependencias, como Spring.NET o el nuevo Unity Application Block de Microsoft.
En lugar de usar solamente ports de CCR, podría escribir los agentes como DSS Service components (ver Microsoft Robotics Studio para más información sobre DSS); el algoritmo podría ser distribuido en una grilla ("gridified") y cada agente interactuar con otros, independientemente de su ubicación..
Pero eso es otra historia....;-)
En esta semana, ha sido anunciada la nueva versión de Microsoft Robotics Developer Studio 2008:
http://blogs.msdn.com/msroboticsstudio/archive/2008/04/09/microsoft-robotics-developer-studio-2008-ctp-april-available.aspx
La tercera nueva característica ahí anunciada, sería muy interesante para implementar "miniagentes" distribuidos:
Support for creating applications that run on multiple DSS nodes using Visual Programming Language and DSS Manifest Editor. This makes it much simpler to create applications that run across nodes, either on the same machine or across the network. When an application containing multiple nodes is to be started, VPL creates individual deploy packages for each node and fires them up across the network.
(este artículo es la versión en español de mi versión "anglish":
Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)
)
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Ayer publiqué las primeras lecciones del curso de introducción a Java en línea. En este post, que iré actualizando, quiero listar las lecciones que voy agregando a cada curso. Este tipo de post me permite tener una evidencia de avance.
Actualización: 21 de Abril, aparecieron las primeras lecciones del curso de Sitios con PHP y MySQL
Acá van las primeras lecciones agregadas:
2008-04-08 El lenguaje Java
2008-04-08 Java y Unicode
2008-04-08 Comentarios
2008-04-09 Variables y Tipos
2008-04-10 Tipos de Datos Enteros
2008-04-11 Tipos Reales
2008-04-12 Caracteres
2008-04-13 Operando con bits
2008-04-14 Sentencias y comandos
2008-04-15 La sentencia if-else
2008-04-16 Funciones matemáticas
2008-04-17 Errores con operaciones enteras
2008-04-17 Operaciones con reales
2008-04-18 Problemas reales
2008-04-18 Conversiones
2008-04-19 Operaciones aritméticas
2008-04-19 Más sobre operaciones aritméticas
2008-04-19 Incrementar y decrementar
2008-04-20 Tamaños de enteros
2008-04-21 Sitios con PHP y MySQL
2008-04-21 Introducción a PHP
2008-04-21 Qué es PHP
2008-04-21 Primera página en PHP
2008-04-21 Instalando PHP y MySQL
2008-04-22 Relaciones
2008-04-22 Valores booleanos
2008-04-23 Cadenas de caracteres
2008-04-23 Asignaciones
2008-04-24 Precedencia y asociatividad de operadores
2008-04-25 If anidados
2008-04-26 El operador condicional
2008-04-27 Múltiple decisión con switch
2008-04-28 Alcance de variables
2008-04-29 Ciclos con while y do-while
2008-04-30 El gran comando for
2008-05-01 Etiquetas, cortes y algo más
2008-05-02 Retornando de métodos
2008-05-03 Arreglos
2008-05-04 Arreglos de objetos
2008-05-05 Vectores de vectores
2008-05-06 Un ejemplo de arreglos
2008-05-07 Strings
2008-05-08 Constructores de String y encapsulamiento
2008-05-09 Métodos de String
2008-05-10 Expresiones Regulares
2008-05-11 Primer For (PHP y MySQL)
2008-05-12 Imprimiendo una expresión (PHP y MySQL)
2008-05-13 Introducción al curso (JavaServer Pages)
2008-05-13 Objetivos (JavaServer Pages)
2008-05-13 Requisitos (JavaServer Pages)
2008-05-14 El servidor Tomcat (JavaServer Pages)
2008-05-15 Arrancando el Tomcat (JavaServer Pages)
2008-05-16 Listando las aplicaciones (JavaServer Pages)
2008-05-17 Imprimiendo con echo y comentarios (PHP y MySQL)
2008-05-18 Usando tablas y funciones (PHP y MySQL)
2008-05-19 Escribiendo y usando una función (PHP y MySQL)
2008-05-20 Mezclando PHP y HTML (PHP y MySQL)
2008-05-21 Usando un if (PHP y MySQL)
2008-05-22 Usando variables globales (PHP y MySQL)
2008-05-23 Arreglos (PHP y MySQL)
2008-05-24 Agregando elementos (PHP y MySQL)
2008-05-25 Los arreglos son asociativos (PHP y MySQL)
2008-05-26 La función array (PHP y MySQL)
2008-05-27 Ordenando arreglos (PHP y MySQL)
2008-05-28 Arreglos de arreglos (PHP y MySQL)
2008-05-29 Manejo de Formularios (PHP y MySQL)
2008-05-30 Procesando datos de un formulario (PHP y MySQL)
2008-05-31 Enviando por POST (PHP y MySQL)
2008-06-01 Usando $_REQUEST (PHP y MySQL)
2008-06-02 Introducción a Ajax (Ajax)
2008-06-03 Enlaces (Ajax)
2008-06-04 La configuración de PHP (PHP y MySQL)
2008-06-05 Datos en las variables (PHP y MySQL)
2008-06-06 Otros tipos de datos en formularios (PHP y MySQL)
2008-06-07 Clases y Objetos (Java)
2008-06-08 Clases en Java (Java)
2008-06-09 Atributos en una clase (Java)
2008-06-10 Threads (Java)
2008-06-11 Acceso a bases de datos (Java)
2008-06-12 Parámetros opcionales (PHP y MySQL)
2008-06-13 Parámetros por referencia (PHP y MySQL)
2008-06-14 Leer archivo en un arreglo (PHP y MySQL)
2008-06-15 Primera Clase (Java)
2008-06-16 Manejo de Archivos (PHP y MySQL)
2008-06-17 Leyendo líneas (PHP y MySQL)
2008-06-18 Leyendo archivos (PHP y MySQL)
2008-06-19 Leyendo recursos de Internet (PHP y MySQL)
2008-06-20 Primera página (JSP)
2008-06-21 Agregando código Java (JSP)
2008-06-22 Produciendo salida HTML con Java (JSP)
2008-06-23 Compilación de las páginas (JSP)
2008-06-24 La clase compilada (JSP)
2008-06-25 Traduciendo nuestro JSP a Java (JSP)
2008-06-26 Expresiones en JSP (JSP)
2008-06-27 Usando out (JSP)
2008-06-28 Usando Eclipse (Java)
2008-06-29 Lanzando el programa (Java)
2008-06-30 Creando un proyecto Java (Java)
2008-07-01 Declarando import (JSP)
2008-07-02 El objeto request (JSP)
2008-07-03 Introducción a AjGenesis (AjGenesis)
Los próximos cursos a publicar son:
- Introducción a .Net con VB.Net
- Introducción a .NET con C#
- Programando sitios con JavaServer Pages
Son los cursos que habitualmente dicto presencialmente, pasados en limpio.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Finalmente, despues de mucha demora, pude terminar la puesta a punto de un pequeño sistema de lecciones en línea (simples páginas dinámicas, con contenido, y algún manejo de usuario), que no podía llamarse de otra forma que AjLearning.... ;-). Y el primer curso que comienzo a publicar (hoy hay 4 lecciones) es uno de Introducción a Java, abierto a programadores, gratuito, en línea.
Visitar
http://www.ajlopez.net/cursos
Como comento en la introducción al curso:
Este curso sobre programación Java nació de manera inesperada. Luego de años de dar cursos y charlas y conferencias, sobre programación, en Java, .NET y PHP, arquitectura de sistemas, metodologías, tecnologías y lenguajes, siempre me quedaba la sensación de no haber transmitido de una forma correcta alguna parte del temario encarado, o que los asistentes, con tiempo limitado, no habían podido detenerse en un punto importante, para practicarlo y entenderlo cabalmente. Por otra parte, esa experiencia me sirvió para ir depurando, mejorando, el tratamiento de cada tema. Y algo que quería transmitir, era la potencia de cada tecnología, así como alguna guía, entre tantas opciones, sobre cómo desarrollar una aplicación, o cómo entender un lenguaje determinado. Otra limitación de un curso presencial o charla, es que, en general, lo transmitido sólo llega a los asistentes de ese curso o seminario en particular. Siempre he pensado que debería haber alguna forma de lograr llegar a más gente, de alguna otra manera.
Ya había escrito en los noventa, un libro sobre Java. Escribir un libro puede ser un trabajo agotador y estresante, con fechas límite de entrega, y cantidad de páginas a producir en tanto tiempo. Cada página y ejemplo desarrollado, al revisarlo podría parecer totalmente inadecuado, obligando a la reescritura y elaboración de material nuevo. Ahora, con años más de trabajo, veo que algo conseguí transmitir en ese libro, pero que hace falta actualizarlo y adecuarlo a nuevas posibilidades del lenguaje.
Desde entonces, la web ha ido explotando, y hoy los informáticos nos encontramos consultando la red de redes en cada momento, para aprender nuevos trucos, consultar ejemplos, y buscar artículos sobre los problemas que tenemos que resolver. Uniendo estas realidades, la red, mis cursos presenciales, y el texto de un libro, me gustaría brindarles de alguna forma, mis conocimientos sobre Java y otras tecnologías, que me parecen que deben estar en la bolsa de conocimiento de cada programador moderno.
Entonces, estas lecciones en línea nace de la necesidad de pasar en limpio algunos temas que doy en mis cursos presenciales. Me pareció interesante poner en texto y ejemplos concretos, lo que vemos en los cursos presenciales que doy en Buenos Aires, Argentina, y alredores.
Hay multitud de recursos de programación en Java, y en otras tecnologías. Igualmente, espero que estas lecciones sirvan a los que viene a mis cursos presenciales, a los que no, a los que no pueden asistir, o cualquier programador inquieto que quiera comenzar a ver este fascinante lenguaje y tecnología.
Estas lecciones no son un producto terminado. Es un producto en constante evolución, y espero que constante mejora. Es parte de Uds., también, aprovecharlo, comentarlo, criticarlo, mejorarlo. Su primera colaboración puede ser "feedback" y difusión de estas lecciones.
El objetivo es ayudar al lector de estas páginas a entender un poco más, este maravilloso mundo que es la programación de software. Java es una excusa para esto, pero una excusa muy difundida, que espero que puedan aprovechar en el día a día, para el trabajo, y para la creación, que eso es lo que al final somos: creadores de software.
Ahora hay publicadas apenas 4 lecciones. Siguiendo con la idea de A post a day keeps the doctor away, desde mañana publicaré una lista de las lecciones que voy agregando día a dia. Es la forma de hacer un curso: incrementalmente, esperar a que esté todo terminado implica que no esté nunca terminado.
Bueno, espero "feedback", sugerencias, críticas, ¿qué otros cursos querrían ver publicados? Los próximos que vienen, son: Introducción a .NET (basado en el que estoy dictanto ahora en el MUG), y JavaServer Pages. Hay "features" a implementar, como lista de correo por curso, y comentarios en línea a cada lección.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Hace unos meses, me preguntaban por email por algunos temas interesantes de desarrollo de software. La pregunta original estaba más orientada a tecnologías .NET, pero creo que puedo contestar de forma útil, de una manera más general. Igualmente, aparecerán temas de .NET en este post, y otro que seguirá.
Al plantearme escribir sobre el tema, me propuse cubrir varios temas que me interesan, pero vi entonces que si cubría todos en un solo artículo, sería muy largo. Así que va primero esta parte sobre Inteligencia Artificial, y más adelante esta semana, escribiré sobre otros temas que me parecen interesantes, como lenguajes en .NET, Software as a Service, Grid Computing, Generación de Código y Domain Specific Languages.
Trataré hoy algunos temas que me interesan y me llamaron la atención, dentro de lo que se ha llamado Inteligencia Artificial, un término muy amplio, y que cubre hoy varias disciplinas, con distintos objetivos.
Sobre la Inteligencia Artificial
¿Por qué proponer esta área como tema de desarrollo? Porque a la gran parte de los desarrolladores de software, nos fascina. ¿Qué mejor objetivo que conseguir comportamiento inteligente de un sistema de software y hardware? ¿Qué otro tema mueve más que éste en el ámbito de la creación de software? Ha sido desarrollado por décadas, y aún hay temas abiertos. Mas bien, el optimismo inicial que hizo que se denominara a esta rama "Inteligencia Artificial", se ha ido desvaneciendo, pero también ha habido éxitos, y nuevos caminos que no se habían tomado en principio (recordemos el abandono de los Perceptrones, debido en gran parte a la crítica de Minsky y Papert).
Quiero que quede claro que la inteligencia artificial hoy no es un área homogénea. Ha quedado bajo ese nombre histórico multitud de ramas. Y los métodos para implementar los objetivos planteados, van desde la fuerza bruta, hasta algoritmos novedosos (no naturales), hasta la emulación de lo que sabemos del funcionamiento de organismos naturales (humanos y no humanos).
Algoritmos genéticos
Creo que es un área ya bastante visitada, pero que tiene puntos de contacto con otros temas de este post, como vida artificial y aprendizaje automático. Para investigar:
Genetic Algorithms and Genetic Programming (multitud de enlaces)
What is Genetic Algorithms?
Genetic Programming
Genetic Algorithms
Survival of the Fittest: Natural Selection with Windows Forms (en .NET)
An introduction to Genetic Algorithms In Java
AIAI Technology Genetic Algorithms
Genetic Algorithms and the Traveling Salesman Problem (en C++ para Windows)
Aprendizaje automático
Es un tema fascinante. La implementación de algoritmos que hagan que un sistema de software avance en su capacidad de resolver un problema, es un área alentadora. Muchos organismos aprenden durante su vida lo que no viene innato en su funcionamiento. ¿No podremos conseguir ese tipo de aprendizaje, o algún que lo emule? Esto resolvería el problema de programar todo el comportamiento de un agente inteligente "a priori", como cableado, y permitiría, bien implementado, adaptarse a un ambiente cambiante. Para estudiar
UCI Machine Learning Group
Machine Learning in Games
Machine Learning (AI on the Web)
Planeación
Uno de los primeros temas que aprendí hace décadas. Y sigue de alguna forma abierto a innovaciones. Es evidente que una de nuestras operaciones mentales es la formación de planes, aún planes parciales, incompletos, con información faltante. Pueden investigar leyendo:
What is Partial-Order Planning?
Review of An introduction to Least Commitment Planning
Selected History of Partial Order Planning, Part 1 (donde aparece Sacerdoti, mi primer referente en el tema)
Selected History of Partial Order Planning, Part 2
(vi que en la Universidad Nacional del Centro de la Provincia de Buenos Aires, acá en Argentina, estuvieron trabajando en estos temas).
Vida Artificial
Se ha argumentado que, antes de conseguir comportamiento inteligente, hay que conseguir organismos, artificiales. Es una rama algo alejada de la IA principal, y hasta se la considera una rama aparte. A mí me gustaría incluirla en este post.
Siempre me pareció impresionante el proyecto Tierra:

http://www.his.atr.jp/~ray/tierra/index.html
Vean las "fotos" de:
http://www.his.atr.jp/~ray/pubs/images/index.html
Otro proyecto que también investiga el tema evolución es:
Darwin at home el resultado de aplicar Fuidiom
Fluidiom Implementado en Java, sería interesante implementar algo similar en .NET y DirectX/OpenGL
Juegos
Este es un tema para mí interesantísimo. Permite explorar algoritmos en un problema controlado, y aparte divertido. Para tener un panorama de los problemas actuales, hay que visitar el grupo de la Universidad de Alberta:
http://www.cs.ualberta.ca/~games/
Pueden visitar el grupo de Research de Microsoft:
Applied Games
Ahí encontraran uno de mis temas favoritos:
Computer Go in Microsoft
Hay otro grupo de investigación sobre el tema en Beijing: