Tipos de comportamiento
› Comportamiento genérico
› Comportamientos simples OneShotBehaviour
CyclicBehaviour
› Comportamientos compuestos FSMBehaviour
SequentialBehaviour
ParallelBehaviour
› Comportamientos temporales TickerBehaviour
WakerBehaviour
Los agentes pueden realizar funcionalidades
complejas que pueden llegar a implicar tareas
simultáneas forzando a implementar agentes
multihilo causando problemas.
JADE proporciona un sistema de comportamientos
(behaviours) que ayudan al usuario a construir
sistemas multiagente y reutilizar código.
El paquete jade.core.behaviours contiene las clases que
se usan para implementar comportamientos básicos de
agentes.
Los agentes JADE programan sus comportamientos con un
solo hilo.
Se eliminan los problemas de sincronización entre
comportamientos concurrentes que acceden al mismo
recurso, haciendo que cada agente sea equivalente a un único
hilo.
Comportamientos Genéricos:
› Se corresponde con la clase abstracta Behaviour. Mantienen un estado
del agente y en base a él se ejecutan diferentes operaciones. Finalizan
cuando cierta condición se cumple.
Comportamientos Simples:
› Se corresponden con la clase SimpleBehaviour que representa a
comportamientos atómicos, que suelen realizar tareas simples.
reset ():Devuelve el comportamiento a su estado inicial.
› OneShotBehaviour: el método done() siempre devuelve "true“.
package examples.practicaTres;import jade.core.Agent; import jade.core.behaviours.*; public class OneShot extends Agent{
public void setup() { MyOneShotBehaviour c = new MyOneShotBehaviour(); addBehaviour(c);
} protected void takeDown(){
System.out.println("Ejecucion finalizada");} private class MyOneShotBehaviour extends OneShotBehaviour {
public void action() { System.out.println("Ejecutamos la accion una sola vez"); myAgent.doDelete();
} } }
CyclicBehaviour: representa un comportamiento que debe ejecutarse
una serie de veces.
› El método done() devuelve false.
› Se mantiene activo tanto tiempo como esté activo el agente.
› Hay riesgo de que se pueda quedar con toda la CPU.
package examples.practicaTres;import jade.core.Agent;import jade.core.behaviours.*;public class Cyclic extends Agent{
public void setup() { MyCyclicBehaviour c = new MyCyclicBehaviour(); addBehaviour(c);
} protected void takeDown(){
System.out.println("Ejecucion finalizada"); } private class MyCyclicBehaviour extends CyclicBehaviour {
public void action() { System.out.println("Ejecutamos la accion ciclicamente");}
} }
Esta clase abstracta modela comportamientos a partir de la composición
de otros comportamientos (hijos).
Está compuesta por diferentes subcomportamientos que se pueden
ejecutar siguiendo diferentes políticas de planificación.
Las diferentes políticas vienen determinadas por la subclase elegida, que
puede ser del tipo:
› SequentialBehaviour
› ParallelBehaviour
› FSMBehavior
Se utilizarán los siguientes metodos:
checkTermination(): Se ejecuta
después de la ejecución de cada
hijo para saber cuando se debe
terminar el comportamiento.
getCurrent(): Devuelve el
comportamiento hijo que
actualmente está programado
para ejecutarse.
scheduleFirst(): Programa al
primer hijo para ser ejecutado.
scheduleNext(): Programa al
siguiente hijo para ser ejecutado.
FSMBehavior:
› Permite definir una Máquina de Estados finita mediante
subcomportamientos.
› Cada subcomportamiento representa un estado de la máquina y las
transiciones se van produciendo según la salida de dichos estados.
Se utilizarán los siguientes metodos:
› registerFirstState(behaviour b, String n ): Establece cúal es el estado
inicial.
› registerState(behaviour b, String n ): Registra los estados
intermedios.
› registerLastState(behaviour b, String n ): Registra el estado final.
› registerTransition(String s1, String s2, int evento ): Registra las
transiciones entre estados.
› registerDeafultTransition(String s1, String s2): Define una transición
por defecto entre dos estados.
De manera secuencial, y definiendo transiciones entre estados, se
implementa la acción que debe realizar el comportamiento.
Hay que tener en cuenta una serie de cuestiones como:
› FSMBehaviour carece de método action().
› Hay que identificar los estados definiendo unas constantes cómo etiquetas.
› Hay que registrar los distintos comportamientos que componen FSMBehaviour a
modo de estados.
› 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.
package examples.practicaTres;import jade.core.Agent;import jade.core.behaviours.*;import java.lang.*; public class FSM extends Agent { private static final String ONE_STATE = "UNO"; private static final String TWO_STATE = "DOS"; private static final String THREE_STATE = "TRES"; private static final String ERROR_STATE= "CERO"; private final int UNO = 1; private final int DOS = 2; private final int TRES = 3; private final int CERO = 0; private String entrada=""; public void setup() { entrada="231231231"; MiFSMBehaviour b = new MiFSMBehaviour(this,entrada); addBehaviour(b); }
private class MiFSMBehaviour extends FSMBehaviour{ private int transicion=0; private String entrada=""; public MiFSMBehaviour(Agent _agente,String ent){ super(_agente); entrada=ent; } public void onStart(){ registerFirstState(new OneBehaviour(),ONE_STATE); registerState(new TwoBehaviour(), TWO_STATE); registerState(new ThreeBehaviour(), THREE_STATE); registerLastState(new ErrorBehaviour(),ERROR_STATE); registerTransition(ONE_STATE, TWO_STATE, DOS); registerTransition(TWO_STATE, THREE_STATE,TRES); registerTransition(THREE_STATE,ONE_STATE,UNO); registerDefaultTransition(ONE_STATE, ERROR_STATE); registerDefaultTransition(TWO_STATE, ERROR_STATE); registerDefaultTransition(THREE_STATE, ERROR_STATE); } protected boolean checkTermination(boolean currentDone,int currentResult){ System.out.println(" ** Terminado estado numero: "+currentName); return super.checkTermination(currentDone,currentResult); }
public int getEntrada(){ int tipoEvento = CERO; if (entrada.length()<1) return tipoEvento; else tipoEvento=Integer.parseInt(entrada.substring(0,1)); entrada=entrada.substring(1,entrada.length()); return tipoEvento; } private class OneBehaviour extends OneShotBehaviour { public void action(){System.out.println("() Primer estado");} public int onEnd() { return getEntrada();} } private class TwoBehaviour extends OneShotBehaviour { public void action(){System.out.println("() Estado del segundo
comportamiento"); } public int onEnd() { return getEntrada();} } private class ThreeBehaviour extends OneShotBehaviour { public void action(){System.out.println("() Estado del tercer comportamiento"); } public int onEnd() { return getEntrada();} } private class ErrorBehaviour extends OneShotBehaviour { public void action(){System.out.println("() Error de estado");} } } //class MiFSMBehaviour}//class MiAgente
SequentialBehavior:
› Ejecuta los subcomportamientos de manera secuencial y termina
cuando todos ellos han terminado.
› Se utiliza cuando una tarea compleja se puede descomponer en una
secuencia de pasos atómicos.
› Para añadir los subcomportamientos se utiliza el método
addSubBehaviour() y se ejecutarán en el orden en que sean
agregados.
package examples.practicaTres; import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente2632 extends Agent{
public void setup() { SequentialBehaviour s = new SequentialBehaviour(this); s.addSubBehaviour(new Contador(this, "A", 3)); s.addSubBehaviour(new Contador(this, "B", 2)); s.addSubBehaviour(new Contador(this, "C", 4)); s.addSubBehaviour(new Contador(this, "D", 3)); s.addSubBehaviour(new Contador(this, "E", 5)); addBehaviour(s); }
protected void takeDown(){ System.out.println("ejecucion finalizada"); }
private class Contador extends SimpleBehaviour {int c;int lim; String nombre; public Contador(Agent a, String nombre, int lim) {
super(a);this.nombre = nombre; this.c = 0; this.lim = lim; }
public void action () { c++; System.out.println("contador " + nombre + ": " + c); }
public boolean done () { return c == lim; } }
}
ParalellBehavior:
› Ejecuta los subcomportamientos de manera concurrente.
› Define las constantes que han de ser notificadas al constructor
para que el comportamiento termine cuando:
todos los subcomportamientos lo han hecho (ParalellBehaviour.WHEN_ALL)
un subcomportamiento cualquiera termine (ParalellBehaviour.WHEN_ANY)
cuando un número (entero) especificado de subcomportamientos terminen
› Para añadir los subcomportamientos se
utiliza el método addSubBehaviour() como
en el comportamiento secuencial.
package examples.practicaTres; import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente2633 extends Agent{
public void setup() { ParallelBehaviour s = new ParallelBehaviour(this, ParallelBehaviour.WHEN_ALL); s.addSubBehaviour(new Contador(this, "A", 3));s.addSubBehaviour(new Contador(this, "B", 2)); s.addSubBehaviour(new Contador(this, "C", 4)); s.addSubBehaviour(new Contador(this, "D", 3)); s.addSubBehaviour(new Contador(this, "E", 5)); addBehaviour(s);
} protected void takeDown(){
System.out.println("ejecucion finalizada"); } private class Contador extends SimpleBehaviour {
int c; int lim; String nombre; public Contador(Agent a, String nombre, int lim) {
super(a); this.nombre = nombre;this.c = 0; this.lim = lim;
} public void action () {
c++; System.out.println("contador " + nombre + ": " + c); } public boolean done () {
return c == lim; }
} }
JADE proporciona además dos comportamientos adicionales sencillos para
ejecutar operaciones en determinados instantes de tiempo:
› TickerBehaviour
› WakerBehaviour
Cosas que es importante recordar:› El método block() inicia un contador que evitará que se vuelva a ejecutar el
mismo comportamiento hasta haber superado un tiempo establecido u ocurra
un determinado acontecimiento.
› Llamar más de una vez al método block() durante la ejecución del mismo
comportamiento no tiene efecto.
› El método sleep() es heredado de la clase Thread y cada agente se ejecuta en
un único hilo.
› El método stop() detiene el comportamiento desde el que se llama a dicho
método sin esperar.
TickerBehaviour:
› Define un comportamiento cíclico que ejecutará periódicamente una
tarea que será implementada sobrecargando el método abstracto
onTick().
› Sus métodos action() y done() ya están implementados.
› El método getTickCount() devuelve el número de ticks desde el
último reseteo del comportamiento.
package examples.practicaTres; import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente2641 extends Agent{
long tini; protected void setup(){
tini = System.currentTimeMillis(); addBehaviour(new miTicker(this, 1000));
} private class miTicker extends TickerBehaviour {
int minticks; public miTicker(Agent a, long intervalo){
super(a, intervalo); minticks = 0; } public void reset () {
super.reset(); System.out.println("reseteo!"); }
protected void onTick() { long tfin = System.currentTimeMillis() - tini; int nticks = getTickCount(); reset minticks++; if (nticks == 5) {
System.out.println("[" + tfin + "ms.] tick = " + nticks + ", mitick = " + minticks + " y reseteo");
reset(); } else {
System.out.println("[" + tfin + "ms.] tick = " + nticks + ", mitick = " + minticks); }
}} }
WakerBehaviour:
› Este comportamiento implementa un comportamiento one-shot que se
ejecuta una vez haya transcurrido un tiempo especificado.
› Los métodos action() y done() ya están implementados y la
funcionalidad del comportamiento debe ser implementada
sobrecargando el método abstracto onWake().
package examples.practicaTres; import jade.core.Agent; import jade.core.behaviours.*; public class MiAgente2642 extends Agent {
private long tini; protected void setup() {
tini = System.currentTimeMillis(); addBehaviour(
new TickerBehaviour(this, 1000) { protected void onTick() { System.out.println("[ 1 ] Tiempo transcurrido: "+
(System.currentTimeMillis()-tini) + "ms."); }
} );
addBehaviour( new WakerBehaviour(this, 10000){ protected void onWake() { System.out.println("[*2*] Tiempo transcurrido: " + (System.currentTimeMillis()-
tini) + "ms."); try { Thread.sleep(5000);
} catch (InterruptedException e) { System.out.println("error"); } }
} ); } }
Top Related