Comportamientos de los Agentes

2.1 Qué es un comportamiento 2.2 Añadir y eliminar comportamientos 2.3 Métodos de un comportamiento 2.4 Ejecución de los comportamientos 2.5 Flujo de control de un agente 2.6 Tipos de comportamiento
2.6.1 Comportamiento genérico 2.6.2 Comportamientos simples 2.6.3 Comportamientos compuestos 2.6.4 Comportamientos temporales

2.7 Ejercicios

2.1 Qué es un comportamiento
Un comportamiento o behaviour hace referencia a una funcionalidad que incorpora el agente. Los comportamientos especifican tareas o servicios que realiza un agente para lograr sus objetivos. Cada comportamiento puede realizar una tarea simple como "Envia este mensaje" o "compra X " aunque también se pueden crear comportamientos compuestos. Cada tarea del agente sará una instancia de una clase que deber heredar de la clase Behaviour.

class MiComportamiento extends Behaviour{ … }

Por este motivo, e código JAVA que implementa esa funcionalidad ha de importar el paquete:

jade.core.behaviours.*

Aunque bastaría con importar simplemente la clase Behaviour que se encuentra en:

jade.core.behaviours.Behaviour

Nota: En el siguiente enlace se encuentra una descripción de todos los métodos disponibles en la Clase Behaviour Los agentes están programados en base a sus comportamientos. La programación basada en comportamientos debe realizar los siguientes pasos:

1. Determinar qué debe ser capaz de hacer el agente.
2. Asociar cada funcionalidad con un comportamiento. 3. Escoger el tipo de comportamientos 4. Dejar a JADE la tarea del scheduling (un solo comportamiento se está ejecutando en cada instante).

2.2 Añadir y eliminar comportamientos
La clase Agent provee dos métodos para añadir y borrar comportamientos a un agente: addBehaviour(Behaviour) y removeBehaviour(Behaviour). Estos métodos permiten gestionar la entrada y salida de los objetos Behaviour en la cola del planificador. El planificador va ejecutando según una política round-robin los objetos behaviour que se encuentran en una cola FIFO. Los comportamientos pueden ser añadidos o eliminados en cualquier momento de la vida del agente, desde el método setup() o desde cualquier otro comportamiento, incluso desde otros agentes. Crear un comportamiento no es más que crear una clase privada dentro de la clase del agente y asociarlo a ese agente mediante el método addBehaviour(Behaviour). Añadir un comportamiento debe ser visto como la ejecución de un nuevo thread dentro del agente. En el siguiente ejemplo se puede ver como se añade un comportamiento desde el método setup() del agente.

import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente extends Agent{ protected void setup(){

//Aqui es donde se añade el comportamiento. addBehaviour(new MiComportamiento1()); } //Este es el comportamiento. private class MiComportamiento1 extends Behaviour{ public void action(){ System.out.println("Mi nombre es: "+getName() ); System.out.println("Soy el comportamiento del agente"); } public boolean done(){ return true; } } }

En el siguiente ejemplo se muestra como se puede añadir un comportamiento desde otro comportamiento. Para ello usaremos una variable de la clase Behaviour llamada myAgent que funciona como una referencia al agente que esta ejecutando el comportamiento, es decir, al agente al que pertenece el comportamiento.

import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente extends Agent{ protected void setup(){ //Aqui es donde se añade el comportamiento. addBehaviour(new MiComportamiento1()); } //Este es el comportamiento. private class MiComportamiento1 extends Behaviour{ public void action(){ System.out.println("Mi nombre es: "+getName() ); System.out.println("Soy el primer comportamiento"); myAgent.addBehaviour(new MiComportamiento2()); } public boolean done(){ return true;

. } } } Además de añadir nuevos comportamientos.} } //Este es el otro comportamiento private class MiComportamiento2 extends Behaviour{ public void action(){ System. import jade. import jade. // Inicialización del agente protected void setup() { //Creamos un comportamiento: un objeto de la clase MiComportamiento1 comp = new MiComportamiento1().practica2.out. addBehaviour(comp).*.behaviours. si en el ejemplo anterior quisiéramos borrar el primer comportamiento desde el segundo comportamiento bastaría con hacer una llamada a removeBehaviour() dentro del método action del segundo comportamiento: package examples. } public boolean done(){ return true. } //Definición de un comportamiento private class MiComportamiento1 extends Behaviour{ // define la acción a ser ejecutada cuando se ejecute el comportamiento. public class Ejemplo1 extends Agent{ private Behaviour comp. también se pueden eliminar comportamientos de un agente con el método removeBehaviour(Behaviour).core.Agent. //Aqui es donde se añade el comportamiento.println("Soy el segundo comportamiento").core. Así.

out. // Añade un comportamiento desde otro comportamiento. } } } 2.println("Soy el primer comportamiento"). Es invocado cuando se produce el evento asociado al comportamiento.//Borramos el primer comportamiento. } public boolean done(){ return true.removeBehaviour(comp).3 Métodos de un comportamiento Toda clase que herede de Behaviour deberá implementar: .    Este método define la acción a ser ejecutada cuando se ejecute el comportamiento.out. Es recomendable que los métodos action() no tengan un tiempo de ejecución alto ya que mientras que se ejecutan no pueden ser interrumpidos por otro comportamiento.addBehaviour(new MiComportamiento2()).out. éste se elimina de la cola de comportamientos activos.el método action(). } // Determina si el comportamiento ha sido completado o no. myAgent.println("Mi nombre es: "+getName() ). public boolean done(){ return true. System. // Si el comportamiento ha finalizado. myAgent. .println("Soy el segundo comportamiento"). } } //Definición de un segundo comportamiento private class MiComportamiento2 extends Behaviour{ public void action(){ System.public void action(){ System. Debe incluir el código de las acciones a realizar cuando se ejecute el comportamiento.

Agent. } // Definición de un comportamiento private class MiComportamiento extends Behaviour{ private int estado = 0.println("La escala ha terminado"). Si el comportamiento ha finalizado. import jade.out. Se puede utilizar una marca que se activa cuando se quiere que finalice el comportamiento (se evalúa su valor en el método done()).Devuelve un booleano (true si ha terminado o false en caso contrario). case 1: System. // Función que realiza MiComportamiento public void action(){ switch(estado){ case 0: System.out.. break. public class Ejemplo2 extends Agent{ // Inicialización del agente protected void setup(){ // Añade un comportamiento addBehaviour(new MiComportamiento()).println("Re"). import jade. .out. break.println("Do"). } // Finalización del agente protected void takeDown(){ System. El siguiente ejemplo muestra como el funcionamiento de los método action() y done() de un comportamiento.core.core.el método done().out.behaviours.*.practica2. Este método determina si el comportamiento ha sido completado o no. break. package examples. éste se elimina de la cola de comportamientos activos. break.println("Mi"). case 3: System.println("Fa").out.     Es invocado cuando finaliza la ejecución del método action(). case 2: System.

out.case case case case 4: System.*.println("Sol"). un objeto de la clase Behaviour puede bloquearse durante una cantidad limitada de tiempo que se pasa por valor al método block(). myAgent.break. } } estado++.Agent. Cuando el método action() termina. si el comportamiento no termina. Este no afecta a los demás comportamientos de un agente. Una vez finalizado.println("La"). éste pasa a la lista de comportamientos bloqueados durante el tiempo que indique el método block() o hasta que se reciba un nuevo mensaje. package examples. public class Ejemplo3 extends Agent{ // Inicialización del agente .behaviours. public boolean done(){ return (estado > 7). el método block() coloca el comportamiento en la cola de comportamientos bloqueados. import jade. break. 5: System. Este método permite bloquear un comportamiento hasta que algún acontecimiento ocurra (típicamente. break.println("Si"). Además. break.out. 6: System. 7:{ System. El método block() no para la ejecución del comportamiento sino que espera a que finalice el método action().core.practica2.core. import jade. Debe tenerse en cuenta que el método block() no es como el método sleep() de los Threads.println("Do").out.doDelete(). expresado en milisegundos.out. hasta que un mensaje llegue). } } } Un comportamiento también puede ser bloqueado utilizando el método block(). } // Comprueba si el comportamiento ha finalizado.

println("Esta es la ejecucion "+numeroEjecuciones). } // Comprueba si el comportamiento ha finalizado public boolean done(){ if(numeroEjecuciones>10) { myAgent. // // Función que realiza MiComportamiento public void action() { System. System.println("Despues de 1000 milisengundos").protected void setup() { addBehaviour( new MiComportamiento() ).doDelete().out. //lo bloqueamos durante un segundo block(1000). } else return false.println("****Agente finalizado****"). } // Finalización del agente protected void takeDown() { System.out.out. } } } Un comportamiento bloqueado puede reiniciar su ejecución (desbloquearse) cuando alguna de las siguientes condiciones ocurre: . return true. numeroEjecuciones++. } // Definición de un comportamiento private class MiComportamiento extends Behaviour { int numeroEjecuciones = 1.

Cuando se produce la llegada de un mensaje. } // Definición de un comportamiento private class MiComportamiento extends Behaviour{ . si un objeto se ha bloqueado durante dos segundos. El método restart() es llamado explícitamente por el comportamiento. . todos los objetos de la cola de bloqueados se planifican y deben comprobar si el mensaje es para ellos o no. Una interrupción asociada con este comportamiento por el método block() expira.behaviours.practica2.*.El método onEnd() se ejecuta antes de finalizar el comportamiento (después de que el método done() devuelva true) y devuelve un entero que representa un valor de terminación para el comportamiento. Se debe recordar que onEnd() se llama después de que el comportamiento se haya completado y haya sido eliminado de la cola de comportamientos del agente. addBehaviour(new MiComportamiento()).core. Sin embargo. Estos métodos pueden ser sobrescritos por el usuario para ejecutar acciones anteriores o posteriores a la ejecución del método action(). import jade. public class Ejemplo4 extends Agent { // Inicialización del agente protected void setup(){ // Añadir un comportamiento. . Por ejemplo. import jade. en el caso de que un objeto no sea el destinatario debe volver a bloquearse. así se fuerza el desbloqueo. La clase Behaviour también proporciona dos métodos llamados onStart() y onEnd().Agent.   El agente al que pertenece ese comportamiento recibe un mensaje ACL. Estos métodos se implementan solamente una vez. Este valor dependerá de las condiciones de ejecución implementadas en el comportamiento. llamando al método reset() dentro de onEnd() no es suficiente para que se repita cíclicamente la tarea representada por ese comportamiento y además se debe añadir dicho comportamienro de nuevo al agente como se muestra en el siguiente ejemplo: package examples. el objeto se desbloqueará. al finalizar este tiempo.El método onStart() se ejecuta justo antes de la ejecución del método action(). En este caso el comportamiento se saca de la cola de comportamientos bloqueados y se coloca al final de la cola de comportamientos activos.core.

addBehaviour(this). myAgent. } // Comprueba si el comportamiento ha finalizado public boolean done(){ return true. } // Funcion a realizar por el comportamiento public void action(){ System.out. return 0.println("Hola a todos.println("Despues de 1 segundo"). .out.// Este método se ejecuta justo antes de la ejecución del método action() public void onStart() { System. } } } 2. reset(). los comportamientos no son ejecutados concurrentemente. //lo bloqueamos durante un segundo block(1000).out. System. La política de planificación se realiza de forma preemptiva para todos los comportamientos activos de la cola circular.4 Ejecución de los comportamientos Cada agente tiene un planificador o scheduler de comportamientos. sin poder interrumpirla hasta que ésta acabe (esto ocurre cuando finaliza el método action())."). } // Se ejecuta antes de finalizar el comportamiento public int onEnd(){ // Hace que el comportamiento se reinicie al finalizar. ejecutando un comportamiento hasta que libera el control. En contra de lo que pudiera parecer. es decir.println("Esto se hace cada vez que se inicia el comportamiento").

en un agente pueden estar activos a la vez tantos comportamientos como sea necesario. La mayor parte de estos comportamientos serán utilizados para el intercambio de mensajes: . entonces éste se coloca en la cola de los comportamientos bloqueados. cuando el método action() se está ejecutando.Se puede pensar que los comportamientos son como los hilos de ejecución JAVA.o ya sea para enviarlos. Cuando este comportamiento se desbloquea (por una de las razones vistas anteriormente) se saca de la cola de bloqueados y se coloca al final de la cola de comportamientos activos. Esto es así para que cada agente equivalga únicamente a un único thread. Es importante recordar que. a diferencia de las threads en JAVA. ningún otro comportamiento (de ese mismo agente) puede continuar su ejecución hasta que termine dicho método.ya sea para recibirlos y actuar en consecuencia . Sin embargo. mientras que en JAVA lo decide la máquina virtual. Igual que las threads en Java. con el consiguiente ahorro de ciclos de CPU y memoria que esto implica. el decidir qué comportamiento se ejecuta en cada momento es tarea del programador. . El funcionamiento de los comportamientos está implementado a 2 niveles:   Una cola circular de los comportamientos activos Una cola con los comportamientos bloqueados Un comportamiento puede bloquearse (block()) cuando el método action() termina.

Se ejecuta su método b. se vuelve a comenzar. lo primero a ejecutar es el método setup(). Si está ejecutado se elimina del conjunto de comportamientos del agente y no vuelve a ejecutarse. Tras esto se comprueba que el agente sigue vivo y después se selecciona el siguiente comportamiento a ejectuar del conjunto de comportamientos que aun le quedan al agente.5 Flujo de control de un agente En la figura que se muestra a continuación se representa el flujo de control de un agente básico: Inicialización. En otro caso. es decir. Como puede verse. el camino que atraviesa un agente desde que comienza su ejecución hasta que finaliza y se elimina. realización de la tarea y limpieza y finalización.action() y tras esto se pregunta si ha finalizado.2. . Es posible que no lo haya hecho ya que un comportamiento puede ser o un simple trozo de código que se ejecuta una sola vez o bien varias veces dependiendo de otros factores.

¿Cómo sería la ejecución de un agente que tenga el siguiente comportamiento? a) No se ejecuta puesto falta por definir el método onStart(). b) El comportamiento se bloquea durante 1 segundo y el planificador pasa el control al siguiente .

. Los agentes JADE programan sus comportamientos con un solo hilo y el decidir qué comportamiento se ejecuta en cada momento es tarea del desarrollador del agente. El paquete jade.6 Tipos de comportamientos En muchas ocasiones los agentes realizan. public void action(){ while (salir) { if (cont > 0) { salir = true. haciendo que cada agente sea equivalente a un único hilo. } public boolean done(){ return true. con el consiguiente ahorro de ciclos de CPU y memoria. } cont++. JADE proporciona un sistema de comportamientos (behaviours) que ayudan al usuario a construir sistemas multiagente y reutilizar código. } block(1000). private int cont = 0.behaviours contiene las clases que se usan para implementar comportamientos básicos de agentes. funcionalidades complejas que pueden llegar a implicar tareas simultáneas forzando a implementar agentes multihilo. d) Finaliza siempre puesto que el método done() devuelve siempre true. c) No finaliza nunca puesto que el método action() no finaliza. Por tanto. pero sólo uno de ellos se ejecutará en un momento determinado.core. pueden estar activos varios comportamientos a la vez. lo que puede causar problemas. public class MiComportamiento extends Behaviour { private boolean salir = true. o tratan de realizar.comportamiento de la cola. } } 2. De esta manera se eliminan los problemas de sincronización entre comportamientos concurrentes que acceden al mismo recurso.

1 Comportamiento Genérico Se corresponde con la clase abstracta Behaviour. Finalizan cuando cierta condición se cumple. Mantienen un estado del agente y en base a él se ejecutan diferentes operaciones. Un ejemplo sencillo de este tipo de comportamiento es el código escrito en el apartado 2. Se utilizarán los siguientes metodos: 1.6.2 Comportamientos simples Este tipo de comportamientos se corresponden con la clase SimpleBehaviour que representa a comportamientos atómicos. que suelen realizar tareas simples. 2.2.3.6. reset ():Devuelve el comportamiento a su estado inicial. .

import jade. public class OneShot extends Agent{ public void setup() { MyOneShotBehaviour c = new MyOneShotBehaviour().6.core.2.6.*. } private class MyOneShotBehaviour extends OneShotBehaviour { public void action() { System.out. } } }// 2. Se mantiene activo tanto tiempo como esté activo el agente. } protected void takeDown(){ System.2.out.2.Agent.core.1 OneShotBehaviour En este tipo de comportamiento el método done() siempre devuelve "true". addBehaviour(c). . import jade.practicaTres.println("Ejecucion finalizada"). package examples.2 CyclicBehaviour Representa un comportamiento que debe ejecutarse una serie de veces. de forma que sólo se ejecuta una vez y de forma ininterrumpida. myAgent. Hay riesgo de que se pueda quedar con toda la CPU.doDelete().println("Ejecutamos la accion una sola vez").    El método done() devuelve false.behaviours.

scheduleFirst(): Programa al primer hijo para ser ejecutado. Está compuesta por diferentes subcomportamientos que se pueden ejecutar siguiendo diferentes políticas de planificación.println("Ejecutamos la accion ciclicamente"). addBehaviour(c).Agent.practicaTres. 3.3 Comportamientos compuestos Esta clase abstracta modela comportamientos a partir de la composición de otros comportamientos (hijos).*. } private class MyCyclicBehaviour extends CyclicBehaviour { public void action() { System.out. Se utilizarán los siguientes metodos: 1.package examples. que puede ser del tipo:SequentialBehaviour. } } }// 2. getCurrent(): Devuelve el comportamiento hijo que actualmente está programado para ejecutarse. import jade. public class Cyclic extends Agent{ public void setup() { MyCyclicBehaviour c = new MyCyclicBehaviour(). .6.println("Ejecucion finalizada").core. checkTermination(): Se ejecuta después de la ejecución de cada hijo para saber cuando se debe terminar el comportamiento. import jade. Las diferentes políticas vienen determinadas por la subclase elegida.core. ParallelBehaviour y FSMBehavior.out. scheduleNext(): Programa al siguiente hijo para ser ejecutado. 2.behaviours. 4. } protected void takeDown(){ System.

Cada subcomportamiento representa un estado de la máquina y las transiciones se van produciendo según la salida de dichos estados.3.6.2. .1 FSMBehaviour Esta clase permite definir una Máquina de Estados finita mediante subcomportamientos.

int evento ): Registra las transiciones entre estados. Hay que identificar los estados definiendo unas constantes cómo etiquetas. registerState(behaviour b. String n ): Registra los estados intermedios. que será devuelto por el método onEnd() de cada comportamiento. registerFirstState(behaviour b.Se utilizarán los siguientes metodos: 1. El agente finaliza cuando se termina de ejecutar algún sub-comportamiento que se haya registrado como estado final. Las transiciones puede ser por defecto o teniendo en cuenta un valor de salida del comportamiento origen. Este tipo de transiciones no están marcadas con una etiqueta. registerLastState(behaviour b. y definiendo transiciones entre estados. y sólo se ejecutan en el caso de que el retorno del estado anterior no coincida con ninguna otra transición.     . 5. registerDeafultTransition(String s1. registrando cada uno de ellos cómo primer estado. String s2. String s2) es otro de los métodos de la clase FSMBehaviour que permite definir una transición por defectoentre dos estados. Hay que registrar los distintos comportamientos que componen FSMBehaviour a modo de estados. 2. último estado o estado(s) intermedio(s). por lo que la implementación de estados y transiciones debe realizarse en el constructor. String n ): Registra el estado final. se implementa la acción que debe realizar el comportamiento. String n ): Establece cúal es el estado inicial. De manera secuencial. valor que dependerá de las condiciones de ejecución que se implementen en cada estado/comportamiento. registerTransition(String s1. Hay que tener en cuenta una serie de cuestiones como:  FSMBehaviour carece de método action(). 3. en su método onStart() o justo después de añadir el comportamiento en el nacimiento del agente. 4.

} public void onStart(){ registerFirstState(new OneBehaviour(). registerTransition(ONE_STATE.package examples. private final int DOS = 2. private String entrada="".*.String ent){ super(_agente).Agent. private final int TRES = 3. ERROR_STATE). DOS).entrada). registerState(new TwoBehaviour(). import java. TWO_STATE. registerState(new ThreeBehaviour(). public void setup() { entrada="231231231". THREE_STATE. MiFSMBehaviour b = new MiFSMBehaviour(this. } private class MiFSMBehaviour extends FSMBehaviour{ private int transicion=0. entrada=ent. registerDefaultTransition(TWO_STATE. TWO_STATE = "DOS". ERROR_STATE= "CERO". THREE_STATE = "TRES". TWO_STATE). private String entrada="". registerTransition(THREE_STATE. ERROR_STATE). registerDefaultTransition(ONE_STATE. import jade.ERROR_STATE).core.behaviours. registerLastState(new ErrorBehaviour(). private final int CERO = 0. registerTransition(TWO_STATE. addBehaviour(b). } . THREE_STATE). ONE_STATE = "UNO".UNO).ONE_STATE). public class FSM extends Agent { private static final String private static final String private static final String private static final String private final int UNO = 1.ONE_STATE.lang. ERROR_STATE).practicaTres.TRES).*. import jade.core. registerDefaultTransition(THREE_STATE. public MiFSMBehaviour(Agent _agente.

} } } //class MiFSMBehaviour }//class MiAgente .checkTermination(currentDone.currentResult).} public int onEnd() { return getEntrada(). entrada=entrada. } private class OneBehaviour extends OneShotBehaviour { public void action(){System. return tipoEvento.println("() Estado del segundo comportamiento").} } private class ThreeBehaviour extends OneShotBehaviour { public void action(){System.out. } public int getEntrada(){ int tipoEvento = CERO.println(" ** Terminado estado numero: "+currentName).parseInt(entrada. return super.protected boolean checkTermination(boolean currentDone. if (entrada.out.substring(1.length()).int currentResult){ System.length()<1) return tipoEvento. } public int onEnd() { return getEntrada().println("() Primer estado").substring(0.entrada.out.} } private class ErrorBehaviour extends OneShotBehaviour { public void action(){System. else tipoEvento=Integer.} } private class TwoBehaviour extends OneShotBehaviour { public void action(){System.out.println("() Error de estado").1)).println("() Estado del tercer comportamiento"). } public int onEnd() { return getEntrada().out.

Contador(this. 3)). import jade. 4)). } = new SequentialBehaviour(this).*. public class MiAgente2632 extends Agent{ public void setup() { SequentialBehaviour s s.addSubBehaviour(new s.Agent. 3)). int lim.2 SequentialBehaviour Esta subclase de CompositeBehaviour ejecuta los subcomportamientos de manera secuencial y termina cuando todos ellos han terminado (termina la ejecución de action()). Contador(this. Contador(this.addSubBehaviour(new s. import jade.out. "B".6. Contador(this. "A". . "C".3.println("ejecucion finalizada").core. } private class Contador extends SimpleBehaviour { int c. 5)). Se utiliza cuando una tarea compleja se puede descomponer en una secuencia de pasos atómicos.behaviours. "E".practicaTres. package examples.2. 2)).addSubBehaviour(new addBehaviour(s). Para añadir los subcomportamientos se utiliza el método addSubBehaviour() y se ejecutarán en el orden en que sean agregados. Contador(this.core.addSubBehaviour(new s.addSubBehaviour(new s. protected void takeDown(){ System. "D".

c = 0.String nombre. } public void action () { c++. this. Define las constantes que han de ser notificadas al constructor para que el comportamiento termine cuando:    todos los subcomportamientos lo han hecho (ParalellBehaviour. this. } } } 2. System.6.3 ParallelBehaviour Esta subclase de CompositeBehaviour ejecuta los subcomportamientos de manera concurrente y termina cuando se cumple una determinada condición sobre la terminación de los subcomportamientos.out.WHEN_ALL) (por defecto) un subcomportamiento cualquiera termine (ParalellBehaviour. public Contador(Agent a. int lim) { super(a).lim = lim.println("contador " + nombre + ": " + c).WHEN_ANY) cuando un número especificado de subcomportamientos terminen (indicar un entero) Para añadir los subcomportamientos se utiliza el método addSubBehaviour() como en el comportamiento secuencial. String nombre. this.nombre = nombre.3. } public boolean done () { return c == lim. .

import jade. ParallelBehaviour. ParallelBehaviour.addSubBehaviour(new Contador(this. 4)). "E".package examples. "A".WHEN_ANY). "D".addSubBehaviour(new Contador(this. 3). s.addSubBehaviour(new Contador(this. 5)).behaviours. s. 2)). public class MiAgente2633 extends Agent{ public void setup() { ParallelBehaviour s = new ParallelBehaviour(this. 3)). "C".core.addSubBehaviour(new Contador(this. addBehaviour(s).practicaTres. import jade.addSubBehaviour(new Contador(this.core. //ParallelBehaviour s = new ParallelBehaviour(this. s. } . "B".*. s.WHEN_ALL). s.Agent. //ParallelBehaviour s = new ParallelBehaviour(this. 3)).

4 Comportamientos temporales JADE proporciona además dos comportamientos adicionales sencillos para ejecutar operaciones en determinados instantes de tiempo. String nombre. this.c = 0. } public void action () { c++.6.protected void takeDown(){ System. this. System.lim = lim.println("ejecucion finalizada").out. String nombre. } public boolean done () { return c == lim. } } } 2. int lim. Cosas que es importante recordar: .out. int lim) { super(a). this. public Contador(Agent a.println("contador " + nombre + ": " + c).nombre = nombre. } private class Contador extends SimpleBehaviour { int c.

core. public miTicker(Agent a. 1000)).Agent. El método stop() detiene el comportamiento desde el que se llama a dicho método sin esperar. minticks = 0. intervalo).currentTimeMillis().practicaTres. sino también la ejecución de todos los comportamientos del agente. 4.behaviours. Además contamos con el método getTickCount() que devuelve el número de ticks desde el último reseteo del comportamiento. protected void setup(){ tini = System. long intervalo){ super(a. de tal manera que sólo será relevante la última de estas sentencias.core. su invocación detendrá no sólo la ejecución del comportamiento actual. } private class miTicker extends TickerBehaviour{ int minticks. } . import jade. package examples. addBehaviour(new miTicker(this. sino que inicia un contador que evitará que se vuelva a ejecutar el mismo comportamiento hasta haber superado un tiempo establecido u ocurra un determinado acontecimiento (por ejemplo la llegada de un mensaje o una llamada al método restart()). public class MiAgente2641 extends Agent{ long tini. El método block() no detiene la ejecución del comportamiento actual.6. El método sleep() es heredado de la clase Thread y cada agente se ejecuta en un único hilo por tanto.1. import jade. 2.1 Comportamiento TickerBehaviour Permite definir un comportamiento cíclico que ejecutará periódicamente una tarea (el periodo se indica en el constructor) que será implementada sobrecargando el método abstracto onTick(). Llamar más de una vez al método block() durante la ejecución del mismo comportamiento no tiene efecto. JADE sólo soporta una invocación a este método por cada comportamiento. Sus métodos action() y done() ya están implementados. 3. 2.*.4.

2 Comportamiento WakerBehaviour Este comportamiento implementa un comportamiento one-shot que se ejecuta una vez haya transcurrido un tiempo especificado. después del cual el comportamiento se dará por completado.println("reseteo!"). al mismo tiempo que comprobaremos como se comporta un agente cuando ejecutamos el método sleep() a diferencia de block().. if (nticks == 5) { System.*. public class .] tick = " + nticks + ".out. import jade. En el siguiente ejemplo veremos el funcionamiento de WakerBehaviour. extends Agent { .4.out. } else { System.reset(). reset().tini.currentTimeMillis() .core..core.. package .Agent.. mitick = " + minticks). //minticks = 0. } protected void onTick() { long tfin = System.public void reset () { super. // obtenemos el numero de ticks desde el último reset minticks++.println("[" + tfin + "ms. mitick = " + minticks + " y reseteo"). System.println("[" + tfin + "ms. } } } } 2.. Los métodos action() y done() ya están implementados y la funcionalidad del comportamiento debe ser implementada sobrecargando el método abstracto onWake().out.behaviours.] tick = " + nticks + ". import jade.6. int nticks = getTickCount().

currentTimeMillis()-tini) + "ms.out. están implementadas como extensiones de Simplebehaviour y Behaviour 2...out..currentTimeMillis(). /* addBehaviour( new .*/ } } Por último indicar que aunque TickerBehaviour y WakerBehaviour son conceptualmente subclases de las clases Cyclic y OneShot.. } catch (InterruptedException e) { System.println("error").currentTimeMillis()-tini) + "ms.println("[ 1 ] Tiempo transcurrido: "+ (System... 10000){ protected void .7 Ejercicios Ejemplo: Veremos un ejemplo de un agente que muestra por pantalla los días de la semana y al acabar la .. protected void setup() { tini = System.() { System.out..(.println("[*2*] Tiempo transcurrido: " + (System. 1000) { protected void ..."). addBehaviour( new ... } } )..sleep(5000)..(. } } } ). try { Thread.() { System.").private long tini.

.*. } // Comprueba si el comportamiento ha finalizado.out. import jade. Para ello debemos: a) Crear dos comportamientos C1 y C2. } // Finalización del agente protected void takeDown(){ System.semana finaliza: import jade. } // Definición de un comportamiento private class MiComportamiento extends Behaviour{ private int dia = 0. .Agent. public boolean done(){ . } } } Ejercicio Grupo Sil: En este ejercicio veremos un poco como es el flujo de control de un agente. ..core. . public class ejemploComportamiento extends Agent{ private Behaviour comp.behaviours. // Inicializacion del agente protected void setup(){ .core. .. // Función que realiza MiComportamiento public void action(){ .println("La semana ya acabo").

} . el comportamiento no sigue..core.b) Hacer que ambos comportamientos ejecuten un println y se bloqueen durante un tiempo.{ int repeticiones = 0.out. al eliminarse el agente.Agent.. } private class MiComportamiento1 extends ...println("Agente Finalizado").println("Comportamiento 1 Iniciado")... c) Poner que ambos comportamientos ejecuten el mismo número de veces el println. public class . .. } protected void takeDown(){ System. .. finalice la ejecución del agente.comp2. Normas de envío: Enviar el ejercicio a la dirección de correo: Adjuntar los siguientes datos: Nombre y Apellidos Grupo Código de ayuda: package . d) Poner el tiempo de bloqueo de C1 mayor que el de C2 (el doble por ejemplo).out.. import jade.out.{ private Behaviour comp1.{ System. protected void setup(){ System. extends . import . . Con esto veremos que aunque C1 debería seguir imprimiendo por pantalla el mensaje...... public void . e) Hacer que cuando C2 acabe.println("Agente inicializado").

repeticiones++..{ System. return 0..... . } public void . } } private class MiComportamiento2 extends . } public boolean done(){ .out.. return 0.out..out. { System..out. } } } .. } public int .println("C2: Me voy a bloquear").println("Comportamiento 2 Finalizado").{ . repeticiones++....println("C1: Me voy a bloquear")..out. public void .{ System.{ private int repeticiones=0.. } public boolean .. ....println("Comportamiento 2 Iniciado")....public void action(){ System. { System. .println("Comportamiento 1 Finalizado"). } public int ..

com:   nombre y apellidos.) Código fuente del ejercicio resuelto. G se ejecutarán 1 vez .java.practicaTres. situarse en $JADE_HOME$\src y ejecutar: javac examples\practicaTres\*.PE se ejecutarán 3 veces F.Boot -gui Ejecutar agente: Situarse en $JADE_HOME$\src y ejecutar: java jade. DNI y grupo (Limia. Tendremos en cuenta que:     A y B se ejecutarán 2 veces PA..NombreDeClase Ejercicio propuesto En este ejercicio vamos a desarrollar los comportamientos paralelos y secuenciales. Sil. para cada ejercicio y añadirlo a $JADE_HOME$\src\examples\practicaTres Para compilar.java Ejecutar plataforma JADE: Situarse en $JADE_HOME$ y ejecutar: java jade. Para ello simularemos la siguiente figura. PD .. Instrucciones para compilar y ejecutar el ejemplo     Crear NombreDeClase. PB se ejecutarán 1 vez PC.Ejercicio 2: GRUPO BUBAL Instrucciones de entrega Enviar un correo a grupobubal1011@gmail.Boot container nombreAgente:examples. .

. p.{ public void . .. import .{ // crear comportamiento paralelo que finalice cuando se ejecuten todos los subcomportamientos . . .........practicaTres.. public class .Examina el código del siguiente agente y complétalo : package examples... s = new. p = new .. p. ...... p. import . extends . p...... ... // crear comportamiento secuencial ...... . p.......

. . } private class Contador extends . s. s.out....s.c = 0..//llamar al comportamiento paralelo s. } protected void . s. System.. //añadir comportamiento .. ...println("contador " + nombre + ": " + c)...... String nombre... } public boolean done () { . } public void action () { c++.. public Contador(Agent a..out. this..com/Comportamientos . String nombre.println("ejecucion finalizada")..{ System.. . int lim) { super(a). this.. this..nombre = nombre. int lim. ..lim = lim. } } Bibliografia: http://programacionjade. .wikispaces. { int c.

Sign up to vote on this title
UsefulNot useful