Login

Tweet recenti ...

By A Web Design Company

Agenti

Teoria e pratica dei sistemi basati su agenti.

dadi200x150Iniziamo, con questo articolo, una nuova serie di pubblicazioni relative agli agenti.

Gli agenti sono dei componenti software che possiedono determinate proprietà quali, l'autonomia, la capacità di cooperazione ed altre ancora. In questo documento ci concentreremo solo sugli aspetti di comunicazione, utilizzando una delle numerose piattaforme disponibili per sviluppare sistemi basati su agenti: JADE.

Nell'esempio che andremo ad esaminare avremo due agenti che, comunicando tra di loro, giocheranno al noto gioco "indovina il numero".

Le regole del gioco sono molto semplici: il primo giocatore pensa un numero intero tra uno e un valore massimo prefissato (nell'esempio tale valore è 10.000), il secondo tenta di indovinare qual è il numero e riceve in risposta dal primo se il suo tentativo è superiore al numero "misterioso", oppure se è uguale o se ha indovinato.

L'algoritmo per risolvere questo problema è molto semplice ed è la classica ricerca dicotomica: si va a metà dell'intervallo di incertezza e, in base alla risposta (maggiore o minore) si restringe ulteriormente l'intervallo, andando di nuovo alla sua metà e via dicendo. Si dimostra facilmente che il numero massimo di tentativi cresce con l'intero superiore del logaritmo in base 2 del valore più alto possibile (nel nostro caso è quindi pari a 14).

L'implementazione effettuata sulla piattaforma JADE è molto semplice e consiste in due agenti (che sono dei semplici contenitori) a ciascuno dei quali è assegnato un behaviour che al suo interno contiene un automa stati finiti che gli consente di gestire le varie situazioni di gioco.

Il diagramma degli stati è uguale per entrambi i giocatori: si parte da uno stato iniziale che corrisponde al primo tentativo, si passa ad uno stato in cui si permane per tutti tentativi sbagliati successivi al primo e poi si passa in uno stadio finale in cui due giocatori esultano e terminano il gioco.

Lo stato "primo tentativo"

In questo stato il primo giocatore genera casualmente il numero da indovinare e comunica al secondo giocatore qual è il valore massimo ammissibile per tale numero (valore che nell'esempio è prefissato a 10.000).

Il codice che genera il numero casuale, comunica il massimo possibile e passa allo stato successivo, per il giocatore numero uno, ossia quello che estrae il numero da indovinare, è il seguente (classe QuizB.java):

 

public QuizB(Agent a, long max) {

super(a);

this.max = max;

this.mystery = (long) (Math.floor(Math.random() * max)) + 1;

this.state = PRIMO_TENTATIVO;

}

public void action() {

switch (state) {

case PRIMO_TENTATIVO:

ACLMessage msg = new ACLMessage(ACLMessage.INFORM);

msg.setContent(Long.toString(max));

msg.addReceiver(new AID("con", AID.ISLOCALNAME));

myAgent.send(msg);

state = ATTESA_RISPOSTA;

System.out.println(" - " + myAgent.getLocalName() + " sent: "

+ msg.getContent());

block();

break;

[...]

Come è semplice notare, nel costruttore viene generato il numero casuale mentre nel metodo action(), grazie ad un'istruzione switch che viene utilizzata per far funzionare la macchina a stati finiti che permette all'agente di evolvere, viene impacchettato il messaggio e spedito al destinatario (a cui, per semplicità, è stato assegnato il nome di "con" abbreviazione di concorrente).

Dopo aver spedito il messaggio il sistema cambia di stato, passa lo stato in cui si attende un tentativo dall'altro giocatore e quindi blocca l'agente in attesa di un evento.

Per semplicità sono state omesse le righe di codice successive relative agli altri stati.

Il codice relativo al secondo giocatore è invece reperibile nella classe AnswB.java ed è molto simile al precedente:

public AnswB(Agent a) {

super(a);

this.low = 1;

this.state = PRIMO_TENTATIVO;

}

 

public void action() {

switch (state) {

case PRIMO_TENTATIVO:

ACLMessage msg = myAgent.receive();

if (msg != null) {

System.out.println(" - " + myAgent.getLocalName()

+ " received: " + msg.getContent());

String res = msg.getContent();

long max = Long.parseLong(res);

this.max = max;

this.high = max;

lastGuess = (long) Math.floor(((high - low) / 2) + low);

msg = new ACLMessage(ACLMessage.INFORM);

msg.setContent(Long.toString(lastGuess));

msg.addReceiver(new AID("quiz", AID.ISLOCALNAME));

myAgent.send(msg);

state = TENTATIVI_SUCCESSIVI;

System.out.println(" - " + myAgent.getLocalName() + " sent: "

+ msg.getContent());

block();

}

break;

[...]

Anche in questo caso nel costruttore vengono eseguite delle operazioni di inizializzazione e poi si passa al metodo action() che si occupa di ricevere un messaggio, leggerne il valore e memorizzarlo come il numero massimo (variabili che, in quest'esempio, non sarà più utilizzata). Viene quindi eseguito il primo tentativo prendendo il valore centrale dell'intervallo tra uno e il massimo appena letto. Questo valore viene comunicato al primo giocatore che, per comodità, viene identificato come "quiz".

Dopo l'invio del messaggio il secondo giocatore (il secondo agente) passa nello stato relativo ai tentativi successivi.

Leggi tutto...