Descrizione Il sistema studiato e proposto simula la gestione
di una stazione in cui pervengono richieste da parte di taxi e
Utenti Gli utenti chiedono alla stazione la diponibilit di un taxi
I taxi notificano alla stazione la loro diponibilit La stazione
gestisce lassegnazione taxi utente.
Slide 3
Utente Lutente arriva nella stazione E si trova nello stato
Arrivato in Stazione Lutente invia la richiesta di un taxi Lutente
si mette in attesa di una riposta alla sua richiesta Wait Lutente
riceve la risposta in cui gli viene assegnato un taxi Lutente
prende il taxi e inizia il viaggio Il viaggio termina in con
larrivo nella stazione di destinazi0ne
Slide 4
Taxi Il Taxi arriva nella stazione E si trova nello stato
Arrivato in Stazione Il taxi aspetta la notifica di una richiesta
dalla stazione Il taxi si mette in attesa di una riposta alla sua
richiesta Wait Il taxi riceve la risposta in cui gli viene
assegnato un utente Il taxi prende lutente e inizia il viaggio Il
viaggio termina in con larrivo nella stazione di destinazi0ne
Slide 5
Stazione Stazione attende e gestisce le richieste provenienti
dagli utenti e dai taxi utenti e taxi. La gestione consiste
nellassegnare ad un utente un taxi. La stazione funge da strumento
di sincronizzazione per le entit presenti nel sistema.
Slide 6
Modellazione Petri Net
Slide 7
La stazione presenta due transazioni che rappresentano levento
di arrivo in stazione Le transazioni sono collegate a due post
(taxi disponibili utenti disponibili) in cui le risorse
rappresentano gli utenti e i taxi del sistema I post taxi
disponibili utenti disponibili sono legati alla transazione
assegnamento permette la sincronizzazione. La transazione
assegnamento risulta collegata al post pronti a partire Che sblocca
la transazione su utenti e taxi Pronti a partire. Le transazioni
pronti a partire portano sia lutente che i taxi nel post viaggio.
Terminato il viaggio lutente e il taxi scelgono la stazione a cui
arrivare riportano utente e taxi nei loro stati iniziali dai quali
possono fare una nuova richiesta alla stazione.
Slide 8
Gestione dellattesa Il viaggio dura un certo tempo questo non e
stato riportato nella Petri net iniziale e lo si riposta qui.
Slide 9
Modellazione Attori Dalla descrizione del sistema si evince la
presenza di tre attori. Stazione Taxi Utente
Slide 10
Modellazione Attori Dal grafico qui mostrato si evince che per
ognuno degli attori del sistema vi una classe che estende la classe
Actor che ne specifica il comportamento. Gli attori al loro interno
sono modellati come degli automi a stati finiti e comunicano tra di
loro mediante lo scambio di messaggi. Lo scambio di messaggi
gestito da una macchina di controllo da noi implementata sulle
specifiche di una simulted control machine presentata al
corso.
Slide 11
Diagramma Attori
Slide 12
Diagramma degli stati Utente
Slide 13
Diagramma degli stati Stazione
Slide 14
Diagramma degli stati Taxi
Slide 15
Diagramma degli stati Complessivo
Slide 16
Tipologie Messaggi
Slide 17
Attore public abstract class Actor { private static
ControlMachine cm; private int status; public long now(){ return
cm.now(); } public void send( Message m ){ cm.schedule(m); } public
int currentStatus() { return status; } protected void become( int
status ){ this.status=status; } public abstract void handler(
Message m ); public abstract String getActorTypeAndID(); public
static void setControlMachine( ControlMachine cm ){ Actor.cm=cm;
}
Slide 18
Utente public class Utente extends Actor{ private static final
int INSTAZIONE = 0, INVIAGGIO = 1; private Stazione
stazioneCorrente; private int id; private int
comunicazioniTaxiNonDisponibiliConsecutive = 0; private GuiAttori
gui; public Utente(Stazione stazioneCorrente, int id, GuiAttori
gui) { this(stazioneCorrente, id); this.gui = gui; } public
Utente(Stazione stazioneIniziale, int id){ this.stazioneCorrente =
stazioneIniziale; this.id = id; become(INSTAZIONE); //primo
messaggio per "muoversi dalla stazione" //l'utente consuma tempo
nella stazione e poi si muover dopo un certo tempo. long
tempoAttesa = now() +
ScenarioData.TEMPO_CONSUMATO_IN_STAZIONE_MININO_DaUTENTE +
ScenarioData.RANDOM.nextInt(ScenarioData.VARIAZIONE_TEMPO_IN_STAZIONE_UTENTE);
send( new ScegliTaxiPerViaggio( this, stazioneCorrente,
tempoAttesa) ); System.out.println(getActorTypeAndID() + "
invio:ScegliTaxiPerViaggio ricevente:" +
stazioneCorrente.getActorTypeAndID() ); } public int getID(){
return this.id; } private void impostaStazione(Stazione stazione){
stazioneCorrente = stazione; } //quando un utente lascia la
stazione private void lasciaStazione(){ stazioneCorrente = null; }
public boolean eInStazione(){ return stazioneCorrente != null;
}
Slide 19
Utente @Override public void handler(Message m) { if
(currentStatus()==INSTAZIONE){ if (m instanceof
RispostaSceltaTaxi){ System.out.println(getActorTypeAndID() + "
elaboro rispostaSceltaTaxi"); RispostaSceltaTaxi msg=
(RispostaSceltaTaxi)m; //sceglie un taxi LinkedList listaTaxi =
msg.getTaxiInAttesaInStazione(); Taxi taxiScelto =
listaTaxi.get(ScenarioData.RANDOM.nextInt(listaTaxi.size()));
send(new SceltaTaxiEffettuata(this, stazioneCorrente, now() +1
/*piccolo ritardo*/, taxiScelto));
System.out.println(getActorTypeAndID() + "
invio:SceltaTaxiEffettuata ricevente:" +
stazioneCorrente.getActorTypeAndID() + " argomento:" +
taxiScelto.getActorTypeAndID()); } if (m instanceof
TaxiNonDisponibile){ System.out.println(getActorTypeAndID() + "
elaboro TaxiNonDisponibile"); //il taxi non disponibile, l'utente
riprova a fare un'altra scelta da capo
comunicazioniTaxiNonDisponibiliConsecutive++; if
(comunicazioniTaxiNonDisponibiliConsecutive > 6){ //se superiamo
2^6 limitiamo l'attesa tra due richieste a 2^6
comunicazioniTaxiNonDisponibiliConsecutive = 6; } send( new
ScegliTaxiPerViaggio( this, stazioneCorrente, now() +
(int)Math.pow(2, comunicazioniTaxiNonDisponibiliConsecutive) ));
//ritardi esponenzialmente crescenti.
System.out.println(getActorTypeAndID() + "
invio:ScegliTaxiPerViaggio ricevente:" +
stazioneCorrente.getActorTypeAndID() + " tempo di scelta:" + (now()
+ (int)Math.pow(2, comunicazioniTaxiNonDisponibiliConsecutive)));
}
Slide 20
Utente if (currentStatus() == INVIAGGIO){ if (m instanceof
FineViaggio){ System.out.println(getActorTypeAndID() + " elaboro
FineViaggio"); //l'utente arrivato in stazione //quindi consuma
tempo nella stazione e poi si prepara per ripartire long
tempoAttesa = now() +
ScenarioData.TEMPO_CONSUMATO_IN_STAZIONE_MININO_DaUTENTE +
ScenarioData.RANDOM.nextInt(ScenarioData.VARIAZIONE_TEMPO_IN_STAZIONE_UTENTE);
send( new ScegliTaxiPerViaggio( this, stazioneCorrente,
tempoAttesa) ); System.out.println(getActorTypeAndID() + "
invio:ScegliTaxiPerViaggio ricevente:" +
stazioneCorrente.getActorTypeAndID() );
gui.rimuoviUtenteTransito(getActorTypeAndID()); become(INSTAZIONE);
System.out.println(getActorTypeAndID() + " cambio stato:
INSTAZIONE"); } @Override public String getActorTypeAndID() {
return "UtenteID:" + id; } @Override public boolean equals(Object
obj) { if (obj instanceof Utente){ return ((Utente)obj).getID() ==
this.id; } return false; } }//class
Slide 22
Taxi public class Taxi extends Actor{ private int id; //taxi id
public Taxi(Stazione stazioneIniziale, int id){ this.id = id; //il
taxi si sposta in una stazione iniziale send(new FineViaggio(this,
stazioneIniziale, now(), null));
System.out.println(getActorTypeAndID() + " invio:FineViaggio
ricevente:" + stazioneIniziale.getActorTypeAndID() + " argomento:
vuoto"); } public int getID(){ return this.id; } @Override public
void handler(Message m) { if (m instanceof IndicazioniDiViaggio){
System.out.println(getActorTypeAndID() + " elaboro
IndicazioniDiViaggio"); //il taxi stato scelto ed ora si mette in
viaggio con un utente IndicazioniDiViaggio msg =
(IndicazioniDiViaggio)m; long tempoTrascorso = now() +
ScenarioData.TEMPO_MINIMO_CONSUMATO_IN_VIAGGIO +
ScenarioData.RANDOM.nextInt(ScenarioData.VARIAZIONE_TEMPO_IN_VIAGGIO);
//inviamo il messaggio di arrivo alla stazione
Slide 23
Stazione public void handler(Message m) { if (m instanceof
ScegliTaxiPerViaggio){ System.out.println(getActorTypeAndID() + "
elaboro ScegliTaxiPerViaggio"); Utente richiedente =
(Utente)m.getSender(); if (! utentiInAttesa.contains(richiedente)){
utentiInAttesa.addLast(richiedente); System.out.println("Aggiunto
a:" + getActorTypeAndID() + " l'entit " +
richiedente.getActorTypeAndID()); } if (taxiInAttesa.size() >
0){ //se c' qualche taxi in attesa send(new
RispostaSceltaTaxi(richiedente, now()+1 /*piccolo ritardo*/,
taxiInAttesa)); System.out.println(getActorTypeAndID() + "
invio:RispostaSceltaTaxi ricevente:" +
m.getSender().getActorTypeAndID() + "
argomento:ListaTaxiInAttesa"); } else { send(new
TaxiNonDisponibile(richiedente, now()+1)); //sempre piccoli ritardi
System.out.println(getActorTypeAndID() + " invio:TaxiNonDisponibile
ricevente:" + m.getSender().getActorTypeAndID()); }
Slide 26
Stazione if (m instanceof FineViaggio){
System.out.println(getActorTypeAndID() + " elaboro FineViaggio");
//un utente ed un taxi sono arrivati FineViaggio msg =
(FineViaggio)m; //aggiorna le liste Utente utenteArrivato =
msg.getUtente(); if (utenteArrivato != null){ //potrebbe essere che
solo un taxi arrivato (allo start) quindi //il carico null
utentiInAttesa.addLast(utenteArrivato);
System.out.println("Aggiunto a:" + getActorTypeAndID() + " l'entit
" + utenteArrivato.getActorTypeAndID()); }
taxiInAttesa.addLast((Taxi)msg.getSender());
System.out.println("Aggiunto a:" + getActorTypeAndID() + " l'entit
" + msg.getSender().getActorTypeAndID()); }
gui.aggiornaStazione(getActorTypeAndID(), utentiInAttesa.size(),
taxiInAttesa.size()); } @Override public String getActorTypeAndID()
{ return "StazioneID:" + id; } }//class
Slide 28
Control machine public class TimedSimulation extends
ControlMachine{ private LinkedList events = new LinkedList ();
private long time = 0; //tempo iniziale della simulazione private
long maxSimulatedTime; //tempo massimo della simulazione. public
TimedSimulation(long maxSimulatedTime){ this.maxSimulatedTime =
maxSimulatedTime; } @Override public void schedule(Message m) {
//inseriamo opportunamente il messaggio in lista
//System.out.println("nuovo messaggio in queue, siamo al tempo:" +
time); //se la coda vuota il for non sar mai eseguito! for
(ListIterator it = events.listIterator(); it.hasNext();) { //si
scorrono i messaggi Message message = it.next(); boolean addFirst =
false; if (m.getTime() < message.getTime()){ addFirst = true; }
else if (m.getTime() == message.getTime()){ //se il tempo uguale
risolviamo con la monetina if (ScenarioData.RANDOM.nextBoolean()){
//50% di probabilit addFirst = true; } if (addFirst){ //se un
evento che accadr prima //si torna prima di questo elemento
it.previous(); //e poi si aggiunge it.add(m); //si esce return; }
//se arriviamo qui o la coda e vuota o non abbiamo //inserito
l'elemento prima di altri elementi events.addLast(m); }
Slide 29
Control machine @Override public void unSchedule(Message m) {
//si gestisce il messaggio da elaborare //si aggiorna il tempo
della simulazione time = m.getTime(); // if (time % 100 == 0){
System.out.println("time:" + time); // } //per verificare gli
invarianti int numeroTaxi=0; int numeroUtenti=0; for (int i=0;
i