Académique Documents
Professionnel Documents
Culture Documents
MIND
+
Environnement
BODY
Agent
Interaction Organisation
S’enregistrer ("A1")
S’enregistrer ("V1")
publier ("service")
S’enregistrer ("V2")
publier ("service")
REQUEST (livre)
Chercher liste des vendeurs
CFP !
CFP !
PROPOSE !
PROPOSE !
BEST PROP
AP !
ACCEPT or REFUSE !
INFORM !
Un Agent JADE
! Un agent JADE est une classe qui hérite de la classe Agent et
qui redéfinie des méthodes qui définissent le cycle de vie de
l’agent dans la plateforme.
! La méthode setup est la première méthode qui sera appelée
après instanciation de l’agent par le container.
! la méthode doDelete permet de demander au container de
détruire l’agent.
! Avant que l’agent soit détruit, la méthode takeDown est appelée.
! Un agent peut se déplacer d’un container à l’autre.
◦ Avant chaque opération de migration, la méthode beforeMove est
appelée
◦ Après chaque opération de migration, la méthode afterMove est
appelée
! D’autres méthodes seront présentés par la suite.
My First Agent
package agents;
import jade.core.Agent;
public class BookBuyerAgent extends Agent {
@Override
protected void setup() {
System.out.println("Salut je suis l'acheteur!");
System.out.println("My Name is "+this.getAID().getName());System.out.println("Je me prépare .....");
}
@Override
protected void beforeMove() {
System.out.println("Avant de migrer vers une nouvelle location .....");
}
@Override
protected void afterMove() {
System.out.println("Je viens d'arriver à une nouvelle location .....");
}
@Override
protected void takeDown() {
System.out.println("avant de mourir .....");
}
}
Agent identifier
! Chaque agent est identifié par un identifiant unique dans la plateforme.
! L’identifiant d’un objet de type jade.code.AID
! La méthode getAID() de la classe Agent permet de récupérer
l’agentIdentifier
! Un objet de type AID contient le nom de l’agent plus le nom de la
palteforme (nom de domaine ou adresse IP) ainsi que le numéro de
port de l’annuaire.
! Exemple de nom complet : acheteur1@192.168.30.12:1099/JADE
! Pour créer un objet de type AID sachant le nom local, o peut
écrire :
◦ AID vendeur=new AID("Vendeur1", AID.ISLOCALNAME);
! Le paramètre ISLOCALNAME indique que le premier
paramètre représente le nom local.
Déployer l’agent sur ligne de comande
! Pour déployer un agent dans un nouveau container sur ligne de commande on peut écrire la
commande suivante :
◦ Java jade.Boot -container –host localhost –agents acheteur1:agents.BookBuyerAgent
Déployer l’agent dans une application java :
import jade.core.ProfileImpl; import jade.core.Runtime;
import jade.wrapper.AgentContainer; import jade.wrapper.AgentController;
public class BookBuyerContainer {
public static void main(String[] args) {
try {
Runtime runtime=Runtime.instance();
ProfileImpl profileImpl=new ProfileImpl(false);
profileImpl.setParameter(ProfileImpl.MAIN_HOST,"localhost");
AgentContainer agentContainer=runtime.createAgentContainer(profileImpl);
AgentController agentController=agentContainer.createNewAgent("acheteur1",
"agents.BookBuyerAgent", new Object[]{});
agentController.start();
} catch (Exception e) {
e.printStackTrace();
} Infos: --------------------------------------
} Agent container Container-4@192.168.1.26 is ready.
} --------------------------------------------
Salut je suis l'acheteur!
My Name is acheteur1@WIN-7PA448PU1OR:1099/JADE
Je me prépare .....
Tester la mobilité de l’agent
! L’interface graphique de JADE permet de demander d’un agent de
migrer d’un container à l’autre.
! WakerBehaviour
◦ Le WakerBehaviour est implémenté de façon à exécuter la
méthode onWake() après une période passée comme argument au
constructeur.
◦ Cette période est exprimée en millisecondes. Le Behaviour prend fin
juste après avoir exécuté la méthode onWake().
! TickerBehaviour
◦ Le TickerBehaviour est implémenté pour qu'il exécute sa tâche
périodiquement par la méthode onTick().
◦ La durée de la période est passée comme argument au constructeur.
ParallelBehaviour
! Pour qu’un agent puisse exécuter plusieurs comportements à la fois, il faut utiliser
ParallelBehaviour
package fa; import …
public class FirstAgent extends Agent {
@Override
protected void setup() {
ParallelBehaviour parallelBehaviour=new ParallelBehaviour();
addBehaviour(parallelBehaviour);
parallelBehaviour.addSubBehaviour(new CyclicBehaviour() {
@Override
public void action() { // T1}
});
parallelBehaviour.addSubBehaviour(new TickerBehaviour(this,1000) {
@Override
protected void onTick() { // T2 }
});
parallelBehaviour.addSubBehaviour(new Behaviour() {
int compteur;
@Override
public boolean done() { return (compteur==4);}
@Override public void action() { ++compteur; // T3 }
}); }}
Exemple 1 :
public class BookBuyerAgent extends Agent {
private String livre; private int compteur;
@Override
protected void setup() {
System.out.println("Salut je suis l'acheteur!");
System.out.println("My Name is "+this.getAID().getName()); System.out.println("Je me prépare .....");
Object[] args=getArguments();
if(args.length==1){ livre=(String) args[0]; } else{
System.out.println("J'ai besoin du nom du livre à acheter ...");
doDelete();
}
addBehaviour(new OneShotBehaviour() {
@Override
public void action() {
System.out.println("Cette action est exécutée une seule fois");
} });
addBehaviour(new TickerBehaviour(this,1000) {
@Override
protected void onTick() {
++compteur;System.out.println("Tentative Num "+compteur+" pour acheter le livre "+livre);
}});
}
Redéployer l’agent
AgentController agentController=agentContainer.createNewAgent("acheteur1",
"agents.BookBuyerAgent", new Object[]{"XML"});
addBehaviour(new CyclicBehaviour() {
@Override
public void action() {
System.out.println("Cyclic behavior");
ACLMessage msg=receive();
if(msg!=null){
System.out.println("Réception du message :"+msg.getContent());
}
else{
block();
}} });
Exemple de messages
! Envoyer un message à tous les vendeurs
pour leur demander de proposer une offre
concernant un livre.
! Ici nous utilisons un message dont l’attribut
performative est CFP (Call For Proposal)
// Message carrying a request for offer
ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
for (int i = 0; i < sellerAgents.lenght; ++i) {
cfp.addReceiver(sellerAgents[i]);
}
cfp.setContent(targetBookTitle);
myAgent.send(cfp);
Filtrer les message :
MessageTempalte
! Plusieurs messages peuvent arriver dans
la file d’attente.
! Plusieurs agents tentent d’accéder aux
messages qui arrivent,
! il est important de disposer d’un moyen
qui permet à un agent de filtrer les
messages qui le concernent dans le un
contexte quelconque.
! Les Templates de messages permettent de
résoudre ce problème.
MessageTemplate
! La classe MessageTemplate dispose d’un ensemble de méthodes
statiques de fabrique de d’objet MessageTemplate selon
différents critères.
! Exemples :
◦ Ignorer tous les messages sauf ceux qui ont l’option
performative est CFP
addBehaviour(new CyclicBehaviour() {
@Override
public void action() {
MessageTemplate mt =
MessageTemplate.MatchPerformative(ACLMessage.CFP);
ACLMessage msg = myAgent.receive(mt);
if (msg != null) {
// CFP Message received. Process it
}
else {
block();
}
}
}
DF Agent
! Le service des pages jaunes permet aux agents de la plateforme de
publier leurs services.
! D’autres agents de la plateforme peuvent découvrir ces services à partir
de ce service de pages jaunes.
! Dans JADE, Le service des pages jaunes est assurée par un agent DF
(Directory Facilitator) en respectant les spécification de la FIPA.
Interactions avec DF agent
! Les agents peuvent communiquer avec
DFAgent en envoyant des message ACL
! Le contenu de ces messages doivent
respecter la norme (SL0 language) et une
ontologie propre à ce service ( FIPA-Agent-
Management Ontology)
! Pour simplifier ces interactions, JADE a défini
la classe jade.domain.DFService avec
laquelle, il est possible de publier et de
chercher des services simplifiant ainsi les
interactions avec DFAgent.
Publication des services
! Un agent qui souhaite publier un service, doit fournir une
description qui incluse :
◦ Son identifiant AID
◦ Liste des langages et des ontologies que les autres agent doivent
utiliser pour communiquer avec lui
◦ Liste des services publiés
◦ Pour chaque service publié, on doit indiquer :
" Le type du service
" Le nom du service
" Les langages et les ontologies à utiliser pour exploiter ce service
" Et d’autres propriétés spécifiques.
! Les classe
◦ DFAgentDescription,
◦ ServiceDescription
◦ et Property
! du package jade.domain.FIPAAgentManagement représentent les
trois abstraction mentionnées.
Publication des services
@Override
protected void setup() {
// Register the book-selling service in the yellow pages
DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(getAID());
ServiceDescription sd = new ServiceDescription();
sd.setType("book-selling");
sd.setName("JADE-book-trading");
dfd.addServices(sd);
try {
DFService.register(this, dfd);
}
catch (FIPAException fe) {
fe.printStackTrace();
}
}
Suppression d’un service publié
# Quand un agent termine son travail, il est important de
supprimer ses services des pages jaunes.
# Généralement cette opération est effectuée dans la
méthode takeDown()
@Override
protected void takeDown() {
// Deregister from the yellow pages
try {
DFService.deregister(this);
}
catch (FIPAException fe) {
fe.printStackTrace();
}
}
Chercher des services
! Un agent qui souhaite chercher des services doit fournir au DF,
une template de description qui décrit les services souhaités.
! Le résultat de la recherche est une liste de descriptions de
services.
! La méthode statique search() de la classe DFService peut être
utilisée pour ce fait.
REQUEST !
CFP !
PROPOSE !
ACCEPT_PROPOSAL!
CONFIRM !
RESPONSE !
BookBuyerAgent
package agents; import jade.core.AID; import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour; import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
public class BookBuyerAgent extends Agent {
private int compteur;
@Override
protected void setup() {
System.out.println("Salut je suis l'agent Acheteur mon nom
est:"+this.getAID().getName());
addBehaviour(new CyclicBehaviour() {
private AID requester; private String livre; private double prix;
@Override
public void action() {
try {
MessageTemplate template=
MessageTemplate.or(
MessageTemplate.MatchPerformative(ACLMessage.PROPOSE),
MessageTemplate.or(
MessageTemplate.MatchPerformative(ACLMessage.CONFIRM),
MessageTemplate.MatchPerformative(ACLMessage.REQUEST))
);
BookBuyerAgent
ACLMessage aclMessage=receive(template);
if(aclMessage!=null){
switch(aclMessage.getPerformative()){
case ACLMessage.REQUEST :
++compteur;
System.out.println("#########################################");
System.out.println("Requête d'achat de livre:");
System.out.println("From :"+aclMessage.getSender().getName());
livre=aclMessage.getContent();
requester=aclMessage.getSender();
System.out.println("Livre : "+livre);
System.out.println("............................");
System.out.println("Envoi de la requête....");
ACLMessage msg=new ACLMessage(ACLMessage.CFP);
msg.setContent(livre);
msg.setConversationId(livre+"-"+compteur);
msg.addUserDefinedParameter("compteur", String.valueOf(compteur));
msg.addReceiver(new AID("Vendeur1",AID.ISLOCALNAME));
System.out.println("....... En cours");
Thread.sleep(5000); send(msg);
break;
BookBuyerAgent
case ACLMessage.PROPOSE :
prix=Double.parseDouble(aclMessage.getContent());
System.out.println("***********************************");
System.out.println("Conversation ID:"+aclMessage.getConversationId());
System.out.println("Réception de l'offre :");
System.out.println("From :"+aclMessage.getSender().getName());
System.out.println("Prix="+prix);
System.out.println("-----------------------------------");
System.out.println("Conclusion de la transaction.......");
ACLMessage aclMessage2=aclMessage.createReply();
aclMessage2.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
System.out.println("...... En cours");
Thread.sleep(5000);
send(aclMessage2);
break;
BookBuyerAgent
case ACLMessage.CONFIRM:
System.out.println(".........................");
System.out.println("Reçu de la confirmation ...");
System.out.println("Conversation ID:"+aclMessage.getConversationId());
ACLMessage msg3=new ACLMessage(ACLMessage.INFORM);
msg3.addReceiver(requester);
msg3.setConversationId(aclMessage.getConversationId());
msg3.setContent("<transaction>"
+ "<livre>"+livre+"</livre>"
+ "<prix>"+livre+"</prix>"
+ "<fournisseur>"+aclMessage.getSender().getName()+"</fournisseur>"
+ "</transaction");
send(msg3);
break;
}}
else{
block();
}
} catch (Exception e) {
e.printStackTrace();
}
BookSellerAgent
package agents;
import java.util.HashMap; import java.util.Map; import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour; import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
public class BookSellerAgent extends Agent {
private Map<String, Double> data=new HashMap<>();
@Override
protected void setup() {
data.put("XML", new Double(230)); data.put("JAVA", new Double(460));
data.put("IOT", new Double(540));
System.out.println("....... Vendeur "+this.getAID().getName());
addBehaviour(new CyclicBehaviour() {
@Override
public void action() {
try {
}
RequestBehaviour
package agents; import jade.core.AID; import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour; import jade.domain.DFService;
import jade.domain.FIPAException; import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate; import java.util.ArrayList; import java.util.List;