Documente Academic
Documente Profesional
Documente Cultură
Sisteme Multiagent. Inregistrare Si Cautare de Servicii
Sisteme Multiagent. Inregistrare Si Cautare de Servicii
Agentul Provider va implementa urmtoarele comportamente: Refresh la controlul de tip text box periodic la 100 ms; Ateapt primirea de mesaje i rspunde la ele.
Pentru nceput vom crea o clasa ce ne va ajuta s nregistrm/cutm ageni. Aceasta conine urmtoarele metode: nregistrarea / deznregistrarea unui anumit serviciu; cutarea unui anumit serviciu.
Implementarea se realizeaz n clasa YellowPages. Mai jos se arat modul n care se caut un serviciu. Numele serviciului serviceName este dat ca parametru al metodei de cutare. Se caut un agent care ofer serviciu l serviceName, iar in caz de eec, procesul de cutare nceteaz dup un interval prestabilit (timeOut). Dac numele agentului specificat ca parametru nu se gaseste, se alege din lista rezultatelor primul agent; orice agent care ofer serviciul solicitat constituie un rezultat valid. [C#]
public static AID FindService(string serviceName, string agentName, Agent myAgent, int timeOut) { AID agent = null; bool found = false; double t1 = PerformanceCounter.GetValue(); while (!found) { if (PerformanceCounter.GetValue() - t1 > timeOut) break; Application.DoEvents(); // search for an agent DFAgentDescription template = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType(serviceName); template.addServices(sd); DFAgentDescription[] result = DFService.search(myAgent, template); if (result != null && result.Length > 0) { if (agentName == string.Empty) // any solver { agent = result[0].getName(); // one agent is enough - the first found = true; } else { for (int i = 0; i < result.Length; i++) { // it is possible to look for a long name, not only local name if (result[i].getName().getLocalName() == agentName) { agent = result[i].getName(); found = true; break; } } } } } return agent; }
[JAVA]
public static AID FindService(String serviceName, String agentName, Agent myAgent, int timeOut) { AID agent = null; boolean found = false; double t1 = System.currentTimeMillis(); while (!found) { if (System.currentTimeMillis() - t1 > timeOut) { break; } // search for an agent DFAgentDescription template = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType(serviceName); template.addServices(sd); DFAgentDescription[] result = null; try { result = DFService.search(myAgent, template); }catch(FIPAException e){} if (result != null && result.length > 0) { if (agentName.isEmpty()) // any solver { agent = result[0].getName(); // one agent is enough - the first found = true; } } else { for (int i = 0; i < result.length; i++) { // it is possible to look for a long name, not only local name if (result[i].getName().getLocalName().equals(agentName)) { agent = result[i].getName(); found = true; break; } } } } return agent; }
Tot n clasa YellowPages se implementeaz metodele de nregistrare i deznregistrare a serviciilor. Astfel, un serviciu oferit de un agent, odat nregistrat, este disponibil i poate fi cutat de ali ageni care doresc sa-l utilizeze. Deznregistratea unui serviciu se poate face la apelul metdodei DeregisterService, dar i n momentul n care agentul furnizor este eliminat (DeregisterServiceOnTakeDown).
[C#]
/// <summary> /// Registers a service on behalf of an agent /// </summary> public static void RegisterService(string serviceName, Agent myAgent) { // Register the service in the yellow pages DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(myAgent.getAID()); ServiceDescription sd = new ServiceDescription(); sd.setType(serviceName); sd.setName(serviceName); dfd.addServices(sd); DFService.register(myAgent, dfd); } /// <summary> /// Deregisters a service on behalf of an agent /// </summary> public static void DeregisterService(Agent myAgent) { DFService.deregister(myAgent); } /// <summary> /// Handles the messages associated with the take down of an agent, and deregisters the service on its behalf /// </summary> public static void DeregisterServiceOnTakeDown(Agent myAgent) { DFService.deregister(myAgent); MessageBox.Show( "Agent " + myAgent.getLocalName() + " was taken down.\r\nAn unhandled exception probably occured."); }
[JAVA]
// Registers a service on behalf of an agent public static void RegisterService(String serviceName, Agent myAgent) throws FIPAException { // Register the service in the yellow pages DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(myAgent.getAID()); ServiceDescription sd = new ServiceDescription(); sd.setType(serviceName); sd.setName(serviceName); dfd.addServices(sd); DFService.register(myAgent, dfd); } // Deregisters a service on behalf of an agent public static void DeregisterService(Agent myAgent) { try { DFService.deregister(myAgent); }catch(FIPAException e){} }
// Handles the messages associated with the take down of an agent, and deregisters the service on its behalf public static void DeregisterServiceOnTakeDown(Agent myAgent) { try { DFService.deregister(myAgent); }catch(FIPAException e){} MessageBox("Agent " + myAgent.getLocalName() + " was taken down.\r\nAn unhandled exception probably occured."); } public static void MessageBox(String infoMessage) { JOptionPane.showMessageDialog(null, infoMessage, "InfoBox: ", JOptionPane.INFORMATION_MESSAGE); }
Fereastra care reprezint visual agentul este aceeai ca n laboratorul precedent: un Windows Form / jFrame cu un textbox unde se afieaz mesajele / rezultatele primite. Construim n cele ce urmeaz agentul care va implementa Requester-ul:
[C#]
public class Requester : Agent { private FormAgent windowsForm; private AID providerAgent; public override void setup() { object[] args = this.getArguments(); if (args != null) { windowsForm = (FormAgent)args[0]; windowsForm.Text = this.getName(); windowsForm.Show(); } FindSolverService("Provider"); addBehaviour(new WinFormRefreshBehaviour(this, 100)); addBehaviour(new ReceiveBehaviour(this)); addBehaviour(new RequestSendBehaviour(this)); } }
[JAVA]
public class Requester extends Agent { private AgentFrame frame; private AID providerAgent;
@Override public void setup() { Object[] args = this.getArguments(); if (args != null) { frame = (AgentFrame)args[0]; frame.setTitle(this.getName()); frame.setVisible(true); } FindSolverService("Provider"); addBehaviour(new FrameRefreshBehaviour(this, 100)); addBehaviour(new ReceiveBehaviour(this)); addBehaviour(new RequestSendBehaviour(this)); } }
Metoda care va gsi furnizorul de servicii dorite (providerAgent) este prezentat mai jos, aceasta va folosi clasa YellowPages creat mai sus. [C#]
/// <summary> /// Finds a Provider agent /// </summary> /// <param name="solverName">A specific local name or empty string for any solver</param> private void FindSolverService(string solverName) { windowsForm.AddTextLine("Waiting for provider..."); try { providerAgent = YellowPages.FindService("Services.Addition", solverName, this, 10); // if it is null it raises an exception in getName() windowsForm.AddTextLine("Agent found: " + providerAgent.getName() + "\r\n"); } catch { windowsForm.AddTextLine("Exception finding provider"); } }
[JAVA]
//solverName: A specific local name or empty string for any solver private void FindSolverService(String solverName) { frame.AddTextLine("Waiting for provider..."); try { providerAgent = YellowPages.FindService("Services.Addition", solverName, this, 10); // if it is null it raises an exception in getName() frame.AddTextLine("Agent found: " + providerAgent.getName() + "\r\n"); } 6
Agentul Requester care va utiliza serviciul va avea trei comportamente. Primul comportament realizeaz actualizarea ferestrei agentului. Codul este asemntor cu cel din exemplele anterioare. Al doilea comportament, RequestSendBehaviour, trimite datele de intrare agentului providerAgent gsit cu FindSolverService, agent care ofer serviciul necesar prelucrrii lor:
[C#]
internal class RequestSendBehaviour : OneShotBehaviour { private new Requester myAgent; // "myAgent" implicit este de tip "Agent" public RequestSendBehaviour(Requester a) : base(a) { myAgent = a; } public override void action() { ACLMessage message = new ACLMessage(ACLMessage.REQUEST); AID receiverAid = new AID(myAgent.providerAgent.getLocalName(), AID.ISLOCALNAME); // in acelasi container message.addReceiver(receiverAid); message.setConversationId("ID1"); message.setContent("5:6"); myAgent.send(message); } }
[JAVA]
private class RequestSendBehaviour extends OneShotBehaviour { private Requester myAgent; // "myAgent" implicit este de tip "Agent" public RequestSendBehaviour(Requester a) { super(a); myAgent = a; } @Override public void action() { ACLMessage message = new ACLMessage(ACLMessage.REQUEST); AID receiverAid = new AID(myAgent.providerAgent.getLocalName(), AID.ISLOCALNAME); // in acelasi container message.addReceiver(receiverAid); message.setConversationId("ID1"); message.setContent("5:6"); myAgent.send(message); } }
Al treilea comportament, ReceiveBehavior, asteapt un mesaj n mod repetat, fiind de tip CyclicBehavior. El servete la a primi rezultatul prelucrrii realizate de providerAgent. [C#]
internal class ReceiveBehaviour : CyclicBehaviour { private new Requester myAgent; // "myAgent" implicit este de tip "Agent" public ReceiveBehaviour(Requester a) : base(a) { myAgent = a; } public override void action() { ACLMessage message = myAgent.receive(); if (message != null) { string s = message.getContent() + " from " + message.getSender().getLocalName(); myAgent.windowsForm.AddTextLine(s); } else block(); // foarte important } }
[JAVA]
private class ReceiveBehaviour extends CyclicBehaviour { private Requester myAgent; // "myAgent" implicit este de tip "Agent" public ReceiveBehaviour(Requester a) { super(a); myAgent = a; } @Override public void action() { ACLMessage message = myAgent.receive(); if (message != null) { String s = message.getContent() + " from " + message.getSender().getLocalName(); myAgent.frame.AddTextLine(s); } else { block(); // foarte important } } }
[JAVA]
public class Provider extends Agent { public AgentFrame frame; @Override public void setup() { Object[] args = this.getArguments(); if (args != null) { frame = (AgentFrame) args[0]; frame.setTitle(this.getName()); frame.setVisible(true); } RegisterService(); addBehaviour(new FrameRefreshBehaviour(this, 100)); addBehaviour(new ReceiveBehaviour(this)); } public void RegisterService() { try { YellowPages.RegisterService("Services.Addition", this); frame.AddTextLine("Services.Addition service registered"); } catch (Exception exc) { frame.AddTextLine("Exception registering service: " + exc.getMessage()); } } }
Metoda RegisterService realizeaz nregistrarea serviciului Addition oferit de agent. Astfel, serviciul respectiv va fi fcut disponibil potenialilor utilizatori: [C#]
public void RegisterService() { try { YellowPages.RegisterService("Services.Addition", this); windowsForm.AddTextLine("Services.Addition service registered"); } catch (Exception exc) { windowsForm.AddTextLine("Exception registering service: " + exc.Message); } }
[JAVA]
public void RegisterService() { try { YellowPages.RegisterService("Services.Addition", this); frame.AddTextLine("Services.Addition service registered"); } catch (Exception exc) { frame.AddTextLine("Exception registering service: " + exc.getMessage()); } }
Agentul Provider are asociat un comportament ReceiveBehavior. Se ateapt datele de intrare de la agentul solicitant (Requester), adic numerele care trebuie adunate. Rezultatul este trimis napoi Requester-ului. [C#]
internal class ReceiveBehaviour : CyclicBehaviour { private new Provider myAgent; public ReceiveBehaviour(Provider a) : base(a) { myAgent = a; } public override void action() { ACLMessage message = null; MessageTemplate pattern = MessageTemplate.MatchConversationId("ID1"); message = myAgent.receive(pattern); if (message != null) { string messageContent = message.getContent(); string s = messageContent + " from " + message.getSender().getLocalName(); myAgent.windowsForm.AddTextLine(s); //proceseaza mesajul si retuneaza raspuns suma celor 2 numere dintre ":" //Exemplu 45:6 va avea ca raspuns 51 10
ACLMessage reply = new ACLMessage(); reply.addReceiver(message.getSender()); reply.setContent(GetAnsweFor(messageContent)); myAgent.send(reply); } else block(); // foarte important } }
[JAVA]
private class ReceiveBehaviour extends CyclicBehaviour { private Provider myAgent; public ReceiveBehaviour(Provider a) { super(a); myAgent = a; } @Override public void action() { ACLMessage message = null; MessageTemplate pattern = MessageTemplate.MatchConversationId("ID1"); message = myAgent.receive(pattern); if (message != null) { String messageContent = message.getContent(); String s = messageContent + " from " + message.getSender().getLocalName(); myAgent.frame.AddTextLine(s); //proceseaza mesajul si retuneaza raspuns suma celor 2 numere dintre ":" //Exemplu 45:6 va avea ca raspuns 51 ACLMessage reply = new ACLMessage(); reply.addReceiver(message.getSender()); reply.setContent(GetAnswerFor(messageContent)); myAgent.send(reply); } else { block(); // foarte important } } }
n cardul comportamentului de mai sus, rezultatul se calculeaz folosind metoda GetAnswerFor, care primete numerele n formatul "N1:N2" i returneaz suma lor n format string.
11
[C#]
private static string GetAnsweFor(string s) { string[] suma = s.Split(new string[] {":"}, StringSplitOptions.RemoveEmptyEntries); try { if(suma.Length != 2) { return "Mesajul receptionat nu respecta formatul numar:numar"; } int rez = int.Parse(suma[0]) + int.Parse(suma[1]); return rez.ToString(); } catch (Exception e) { return "Mesajul receptionat nu respecta formatul numar:numar"; } }
[JAVA]
private String GetAnswerFor(String s) { String[] suma = s.split(":"); try { if (suma.length != 2) { return "Mesajul receptionat nu respecta formatul numar:numar"; } int rez = Integer.parseInt(suma[0]) + Integer.parseInt(suma[1]); return Integer.toString(rez); } catch (Exception e) { return "Mesajul receptionat nu respecta formatul numar:numar"; } }
n final, n clasa MASInit se genereaz cei doi agenti, Requester-ul si Provider-ul, n containerul principal. Se specific, de asemenea, diveri parametri necesari asigurrii comunicaiei dintre ageni. Codul este asemntor cu cel din exemplele precedente.
3. Aplicaie
S se creeze un sistem de pia virtual alctuit dintr-un numr de ageni cumpratori i un numr de ageni vnzatori, cu urmtoarele caracteristici: vnztorii, nregistrai n Pagini Aurii, au o list de produse cu anumite preuri; cumpratorii caut vnztorii n Pagini Aurii i cer informaii despre preul unui produs; cumpratorii au o list de produse din care vor alege aleatoriu un produs pe care doresc s-l achiziioneze i vor cuta preul minim pentru acest produs n piaa virtual. Pentru fiecare cumprtor, s se afieze oferta de preuri gsit i preul minim. Pentru fiecare vnztor, s se afieze oferta lui i interogrile la care rspunde.
12