Desarrollo de sistemas multiagentes

El tema de estudio del mes pasado era la implementación de sistemas multiagentes o SMA bajo la asesoría del profesor Luis Castillo.  Estuvo muy interesante ya que alcanzamos a hacer varias prácticas utilizando la infraestructura de Jade, un framework para Java.

Como práctica propia desarrollé un prototipo llamado Buscador de talento amigo que resultó hasta interesante.  Su objetivo es el de ayudarnos con algo que nos interesa bastante y frecuentemente: encontrar talento técnico para el desarrollo de nuestros proyectos, o visto desde el otro ángulo: buscar empleo.

La idea original era utilizar la base de datos de contactos de una red social real (Facebook o alguna OpenSocial), sin embargo revisando sus APIs y reglamentos es aparentemente inviable, ya que no permiten legalmente que se extraiga información de estas redes.   Por esto tuve que volver aún mas prototipo a mi prototipo y elaborar mi propia versión de una extremadamente simple red social llamada Mandarina Social donde los usuarios pudieran tener un perfil propio (nombres, profesión, rol e información de ubicación) y tener a otros usuarios como amigos.  El objetivo del sistema es aprovechar esta relación de FOAF.

En términos generales, el sistema le pregunta a un usuario de la red social: cómo es el perfil de las personas que necesita, es decir, que requiere que hayan estudiado: “ingeniería de sistemas“, “zootecnia“, etc; así como alguna información adicional: dónde está ubicada la red social, cuántos perfiles requiere, cuántos niveles de amistad desea verificar y cuánto tiempo desea que el SMA utilice en la búsqueda de talento.

Con esta información el sistema crea a un agente Atendedor quien se encargará de la interacción con el usuario final y que a su vez crea a agentes Buscadores que basados en el perfil del usuario que realiza el requerimiento empiezan a escudriñar a la red social en búsqueda del perfil especificado, saltando entre los contactos amigos del usuario y recursivamente entre los amigos de sus amigos.  Mandarina Social fue desarrollada basada en la especificación hCard de Microformats la cual estandariza ciertas etiquetas (clases CSS en realidad) para demarcar la información del perfil y de las listas de amigos, permitiendo posteriormente su extracción fácil utilizando XPath.  Este enfoque tiene un valor agregado, si se nota, se evita la necesidad de crear una interfaz web para los usuarios humanos y otra, probablemente XML, para el intercambio de datos entre aplicaciones.  Todo se resume en una única versión XHTML/hCard.

Al final de esta etapa de búsqueda se tiene una lista de contactos candidatos que fueron encontrados entre los contactos del usuario.  Los contactos de esta lista incluyen en su información de perfil los datos de su ubicación de la forma: Ciudad, Departamento, País.  Esta información es georreferenciada gracias al agente GeoLocalizador que utiliza al servicio web de Geonames para obtener la ubicación de latitud y longitud de cada uno de los candidatos.

Los candidatos georreferenciados son entregados a un agente Seleccionador quien deberá elegir cuales de los candidatos serán finalmente elegidos.  Esto lo hará basado en la cantidad de perfiles solicitados y un criterio de selección, el cual para este prototipo es la cercanía de los candidatos con respecto al usuario solicitante.  El cálculo de distancias entre candidatos y usuario solicitante es realizado por el agente CalculadorDeDistancias el cual desarrolla su función gracias a la librería JCoord.

Una vez el agente Seleccionador ha decidido cuales de los candidatos son los realmente elegidos, transmite este listado de regreso al agente Atendedor quien gracias al servicio de Google Maps elabora un mapa con las ubicaciones de los contactos con el perfil requerido.  Este mapa junto con el listado de los perfiles es mostrado al usuario como respuesta a su solicitud.

La descripción realizada hasta el momento se complementa con la presentación informal que creé para la muestra del prototipo en sociedad y que incluyo a continuación.

El desarrollo de este prototipo despertó mi curiosidad respecto a los SMA y me permitió darme cuenta que no son abstracciones tan complejas y extrañas como esperaba, mas que un paradigma diferente es una infraestructura que facilita la solución de ciertos tipos de problemas, infraestructura que uno mismo podría terminar desarrollando parcialmente en su propia aplicación pero que no es necesario ya que es provista como una base por la librería, en mi caso de estudio, Jade.  Obviamente existen muchas otras opciones diferentes a Jade, aún mas, dentro de ella hay muchos otros recursos diferentes de los aprovechados con este prototipo, como por ejemplo, la movilidad de agentes entre plataformas físicas gracias a que, según pude apreciar, está desarrollado sobre RMI.  A fin de cuentas, esta es apenas mi primera aproximación al mundo de los agentes.

A pesar de que el prototipo es completamente funcional estas son algunas de las cosas que podría mejorarle en un futuro.

  • Algunas secciones de código son suceptibles de ser optimizadas con refactorización.
  • Sería interesante confirmar la no viabilidad de acceso a las redes sociales reales y en caso se ser posible implementar interfaces para permitir el acceso a su información, en caso contrario, implementar una mejor versión de Mandarina Social.
  • Determinar y solucionar el porqué la manipulación de los datos XHTML de la red social utilizando a XPath genera algunas veces problemas sin motivos aparentes: Connection Reset.
  • Optimizar la distribución de tiempos de espera entre los agentes buscadores.
  • Mejorar la transmisión de mensajes entre agentes, en especial, los que indican condiciones de error.
  • Mejorar el manejo de condiciones de error y su recuperación ante estas o eventos inesperados.
  • Buscar otras formas de interacción con el usuario además de la ya muy conocida ventana de GUI.
  • Mostrar al usuario final través de la GUI los mensajes de estado de los agentes que actualmente se muestran a través de la consola.
  • Solucionar posibles problemas con la muerte (remoción) de los agentes de la plataforma.
  • Verificar el correcto funcionamiento de la concurrencia de solicitudes.

Probablemente mas adelante publique algunos artículos prácticos relacionados con lo aprendido sobre la librería Jade en este blog, alias mi caché mental.

Como para todo lo que aprendo y me emociona, espero por estos temas volver a pasar en un futuro cercano.

Serialización con XML

Esta semana encontré algo que me pareció interesante.  Es la posibilidad de serializar objetos en Java utilizando un codificador XML.  Lo mas interesante se que para realizar esta codificación básica no es necesario de ningún OXM (Object XML Mapper), por el contrario, todo lo necesario viene incluído ya en el J2SE.

Para el ejemplo he creado una clase Worker (POJO) que será serializada y sólo incluye atributos y sus respectivos métodos set/get.  Por presentación también sobreescribí al método toString para presentar el contenido del objeto.

public class Worker
{
    private String username;
    private String password;
    private String name;
    private int age;
    private Date birthDate;

    // ...
}

Creo una instancia de esta clase y asigno valores a sus atributos.

GregorianCalendar birthDate = new GregorianCalendar(2005, 02, 14);  

Worker workerman = new Worker();

workerman.setAge(31);
workerman.setName("Pepito Pimentón");
workerman.setUsername("pepitouser");
workerman.setPassword("pepitopass");
workerman.setBirthDate(birthDate.getTime());

A continuación se procede a codificar el objeto y a generar el archivo XML con su contenido.

// Creates the stream to the file that will storage the serialized object
FileOutputStream outputFile = new FileOutputStream("workerman.xml");

// Relates the XML encoder with the output file stream
XMLEncoder xe = new XMLEncoder(outputFile);

// Serializes the selected object using an XML encoding
xe.writeObject(workerman);

// Closes the XML encoder
xe.close();

Terminado este proceso, deberá existir el archivo workerman.xml con la representación XML del objeto workerman creado anteriormente.  Esta representación de la información podría ser compartida inclusive con otros sistemas/lenguajes/plataformas diferentes a la actual, cosa que podría tener algunos inconvenientes con la serialización convencional de java.io.  El contenido XML (texto plano) probablemente ocupe mas espacio y esto lo haga menos eficiente que una representación binaria.

Por supuesto también es posible realizar el proceso contrario: basados en el archivo workerman.xml con el contenido codificado, obtener la información y crear nuevamente la representación del objeto Worker.

// Creates the stream from the file that storages the already serialized object
inputFile = new FileInputStream("workerman.xml");

// Relates the XML decoder with the input file stream
XMLDecoder xd = new XMLDecoder(inputFile);

// Reads the object from the stream and deserializes it using an XML decoding
clone = (Worker)xd.readObject();

// Closes the XML decoder
xd.close();

El objeto clone deberá contener la misma información que su versión original: workerman.

El contenido del archivo workerman.xml es bastante explícito para su procesamiento en otras plataformas.



 
  
   31
  
  
   
    1110776400000
   
  
  
   Pepito Pimentón
  
  
   pepitopass
  
  
   pepitouser
  
 

Enlace:   XML Serialization Demo (fuentes).

Práctica: distribución de midlets mediante OTA con J2ME – parte I

Durante la sesión Compilación y distribución de midlets se expusieron los métodos de distribución de aplicaciones móviles, en especial los remotos a través de la red (Over-the-air provisioning).

Ahora, contando ya con el primer midlet empaquetado y listo para su distribución (cualquiera de los tres métodos utilizados) nos disponemos durante la presente sesión a implementar de manera práctica este procedimiento.

Para esto se va a utilizar Apache como el servidor HTTP y al emulador de aplicaciones móviles incluído en el JWTK como cliente de las mismas.

A pesar de que el objetivo de la práctica es el de realizar una simulación del proceso de distribución de midlets a nivel local, el procedimiento real en Internet no difiere en mas que en la ubicación en que se localicen los archivos y se especifique a su vez en el atributo MIDlet-Jar-URL del archivo descriptor de la aplicación.

 
  • Introducción.
  • Distribución de midlets.
    • OTA.
    • Flujo de eventos.
  • Herramientas.
  • Servidor de páginas: XAMPP.
    • Instalación.
    • Configuración.
  • Creación del sitio web.
  • Despliegue del midlet.
  • Instalación de la aplicación.
  • Distribución a través de Internet.
  • Enlaces de interés.

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.

Generación del midlet HolaMundo utilizando EclipseME

La creación de software no es una tarea fácil, por este motivo es necesario utilizar de la manera mas eficiente posible las herramientas que se tengan a la mano y que permitan un desarrollo mas estructurado, confiable y rápido de los productos de software.

Los ambientes integrados de desarrollo (IDE) son un tipo de estas herramientas, facilitan la manipulación de  los proyectos con un nivel de abstracción tal que evitan al desarrollador tener que atender aspectos repetitivos o de bajo nivel.

Uno de los IDE mas conocidos para el desarrollo de aplicaciones Java es Eclipse, el cual es extendible mediante plugins, permitiéndole aumentar su funcionalidad e incluír el soporte a mas lenguajes de programación, incluyendo a J2ME.

En la presente sesión se llevará a cabo la instalación de Eclipse, su plugin EclipseME y con ellos se realizará la generación del midlet HolaMundo de manera análoga a las sesiones anteriores, pero esta vez utilizando esta herramienta de nivel profesional.

 
  • Introducción.
  • Herramientas.
    • J2SDK y JWTK.
    • Eclipse.
    • Plugin EclipseME.
  • Instalación de Eclipse.
  • Instalación del plugin EclipseME.
  • Configuración del plugin EclipseME.
  • Creación de un proyecto J2ME.
  • Ejecución (emulación) del midlet.
  • Generación del archivo JAR.

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.

Generación del midlet HolaMundo utilizando las herramientas de línea de comando

KToolBar es una herramienta muy útil provista por el JWTK ya que permite abstraer al desarrollador de varias de las actividades necesarias para la generación de los midlets.

Como ejercicio académico es interesante poder realizar estas actividades una a una y desde la línea de comandos para poder observar con precisión su papel e importancia dentro del proceso de desarrollo de las aplicaciones móviles.

A continuación se realizarán las actividades necesarias para compilar preverificar, empaquetar y ejecutar al midlet HolaMundo de manera similar a lo realizado durante la sesión anterior, sin embargo ahora utilizando únicamente los comandos básicos provistos por la plataforma Java.

Para la elaboración de este documento se utilizará Windows Vista, motivo por el cual ciertas ubicaciones o comandos relacionados con el shell podrán variar de acuerdo con el sistema operativo utilizado.

 
  • Introducción.
  • Herramientas de software.
  • Estructura de los directorios.
  • Variables de ambiente.
  • Compilación.
  • Preverificación.
  • Empaquetamiento.
    • Creación del archivo de manifiesto.
    • Creación del archivo JAR.
    • Creación del archivo JAD.
  • Ejecución (emulación).
  • Enlaces de interés.

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.

Generación del midlet HolaMundo utilizando el JWTK

Durante el presente capítulo práctico se realizará la construcción (build), ejecución (emulación) y despliegue del midlet HolaMundo cuyo código fuente fue implementado en capítulos anteriores.

Para esto se utilizarán las herramientas básicas que provee la plataforma Java como lo son el J2SDK y el JWTK.

Esta práctica permitirá también verificar los conceptos teóricos expuestos en los capítulos anteriores.

 
 
  • Introducción.
  • Herramientas necesarias.
    • Editor de texto.
    • Ambiente de desarrollo (J2SDK).
    • Java Wireless Toolkit (JWTK).
  • Instalación de las herramientas.
  • Creación del proyecto.
  • Configuración del proyecto.
  • Estructura de los directorios generados.
  • Edicion del código fuente del midlet.
  • Compilación.
  • Ejecución (emulación).
  • Despliegue del midlet.
  • Archivos generados.
    • Archivo JAD.
    • Archivo JAR.

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.

Midlets con J2ME

El Objetivo del capítulo es el de identificar los estados entre los cuales puede transitar un midlet durante su ciclo de vida, conocer cual es el significado de cada uno de estos estados y que se espera que el desarrollador implemente en ellos así como el identificar los métodos que deberán ser invocados para solicitar/obligar la transición entre estados.

  • Definición
  • Ciclo de vida de un midlet
    • Estado DETENIDO (paused)
    • Estado ACTIVO (active)
    • Estado DESTRUÍDO (destroyed)
  • Métodos modificadores de estado
    • Método startApp()
    • Método pauseApp()
    • Método destroyApp(boolean)
    • Relación entre destroyApp() y notifyDestroyed()
    • Método notifyPaused()
    • Método resumeRequest()
  • Entorno de ejecución

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.

Introducción a la plataforma J2ME

El objetivo del capítulo es el de exponer los diferentes conceptos que se relacionan con la plataforma J2ME tales como su arquitectura, los dispositivos objetivo, su relación con J2SE, las relaciones y diferencias entre configuraciones y perfiles y sus requisitos de hardware y de software.

  • Introducción.
  • Arquitectura de la plataforma J2ME.
  • Configuraciones.
    • CDC.
    • CLDC.
  • Diferencias entre J2SE y CLDC.
  • Perfiles.
    • MIDP.
      • Requisitos de hardware.
      • Requisitos de software.
  • Paquetes opcionales.
  • Máquinas virtuales.
    • Características.

Para mas información consulte el curso Introducción al desarrollo de aplicaciones móviles con J2ME.