La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

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.

Presentazioni simili


Presentazione sul tema: "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."— Transcript della presentazione:

1

2 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.

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

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

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.

6 Modellazione Petri Net

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.

8 Gestione dellattesa Il viaggio dura un certo tempo questo non e stato riportato nella Petri net iniziale e lo si riposta qui.

9 Modellazione Attori Dalla descrizione del sistema si evince la presenza di tre attori. Stazione Taxi Utente

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.

11 Diagramma Attori

12 Diagramma degli stati Utente

13 Diagramma degli stati Stazione

14 Diagramma degli stati Taxi

15 Diagramma degli stati Complessivo

16 Tipologie Messaggi

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; }

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; }

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))); }

20 Utente if (m instanceof AssegnazioneTaxi){ System.out.println(getActorTypeAndID() + " elaboro AssegnazioneTaxi"); //il taxi è stato assegnato all'utente. L'utente comunica la stazione al taxi che lo porterà //in quella stazione. comunicazioniTaxiNonDisponibiliConsecutive = 0; //reset //sceglie una stazione Stazione prossimaStazione; int pos; do { //evitiamo di scegliere la stazione corrente pos = ScenarioData.RANDOM.nextInt(ScenarioData.stazioniDisponibili.length); prossimaStazione = ScenarioData.stazioniDisponibili[pos]; } while (prossimaStazione.equals(stazioneCorrente)); //scelta la stazione si manda la comunicazione AssegnazioneTaxi msg = (AssegnazioneTaxi)m; System.out.println(getActorTypeAndID() + " lascia la stazione:" + stazioneCorrente.getActorTypeAndID()); send(new IndicazioniDiViaggio(this, msg.getTaxiScelto(), now(), prossimaStazione)); System.out.println(getActorTypeAndID() + " invio:IndicazioniDiViaggio ricevente:" + msg.getTaxiScelto().getActorTypeAndID() + " argomento:" + prossimaStazione.getActorTypeAndID()); //mi serve per il printline Stazione oldstation=stazioneCorrente; stazioneCorrente = prossimaStazione; //si aggiorna lo stato become(INVIAGGIO); //update grafica gui.aggiungiUtenteTransito(getActorTypeAndID(), " lascia la stazione:" + oldstation.getActorTypeAndID()+" in viaggio per "+prossimaStazione.getActorTypeAndID() ); System.out.println(getActorTypeAndID() + " cambio stato: INVIAGGIO"); }

21 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

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

23 Taxi send(new FineViaggio(this, msg.getStazione(), tempoTrascorso, (Utente)msg.getSender())); System.out.println(getActorTypeAndID() + " invio:FineViaggio ricevente:" + msg.getStazione().getActorTypeAndID() + " argomento:" + msg.getSender().getActorTypeAndID()); //e pure all'utente nel taxi send(new FineViaggio(null, msg.getSender(), tempoTrascorso, null)); System.out.println(getActorTypeAndID() + " invio:FineViaggio ricevente:" + msg.getSender().getActorTypeAndID() + " argomento: nessuno" ); } @Override public String getActorTypeAndID() { return "TaxiID:" + id; } @Override public boolean equals(Object obj) { if (obj instanceof Taxi){ return this.id == ((Taxi)obj).getID(); } return false; } }//class

24 Stazione public class Stazione extends Actor{ private GuiAttori gui; private int id; private LinkedList taxiInAttesa = new LinkedList (); private LinkedList utentiInAttesa = new LinkedList (); public Stazione(GuiAttori gui, int id) { this.gui = gui; this.id = id; gui.aggiornaStazione(getActorTypeAndID(), 0, 0); } public Stazione(int id){ this.id = id; } public int getID(){ return this.id; } public int getUtentiAttesaSize(){ return utentiInAttesa.size(); } public int getTaxiInAttesaSize(){ return taxiInAttesa.size(); }

25 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()); }

26 Stazione if (m instanceof SceltaTaxiEffettuata){ System.out.println(getActorTypeAndID() + " elaboro SceltaTaxiEffettuata"); //l'utente ha scelto un taxi e si verifica se è disponibile //o è stato preso nel frattemo della scelta. SceltaTaxiEffettuata msg = (SceltaTaxiEffettuata)m; boolean taxiPresente = taxiInAttesa.remove(msg.getTaxiScelto()); if (!taxiPresente){ //se il taxi non c'è si avvisa l'utente send(new TaxiNonDisponibile(msg.getSender(), now()+1)); //sempre piccoli ritardi System.out.println(getActorTypeAndID() + " invio:TaxiNonDisponibile ricevente:" + m.getSender().getActorTypeAndID()); } else{ //il taxi è stato rimosso quindi c'è //l'utente si sposta. utentiInAttesa.remove((Utente)msg.getSender()); send(new AssegnazioneTaxi(msg.getSender(), now() /*immediato*/, msg.getTaxiScelto())); System.out.println(getActorTypeAndID() + " invio:AssegnazioneTaxi ricevente:" + m.getSender().getActorTypeAndID() + " argomento:" +msg.getTaxiScelto().getActorTypeAndID()); }

27 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

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); }

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<ScenarioData.NUMERO_STAZIONI; i++){ numeroTaxi += ScenarioData.stazioniDisponibili[i].getTaxiInAttesaSize(); numeroUtenti += ScenarioData.stazioniDisponibili[i].getUtentiAttesaSize(); } System.out.println("Utenti in stazione:" + numeroUtenti); System.out.println("Taxi in stazione:" + numeroTaxi); //si esegue il messaggio m.getReceiver().handler(m); }

30 Control machine @Override public void controller() { System.out.println("Esecuzione avviata"); while (time < maxSimulatedTime){ //finchè il tempo della simulazione non è scaduto. Processa il messaggio in testa if (events.size() > 0){ unSchedule(events.removeFirst()); } else { System.out.println("wtf!?"); break; } @Override public long now() { return time; } @Override public void reset() { //si resetta tutto time = 0; events = new LinkedList (); } // }//class

31 Modellazione in Uppaal Il sistema di sopra descritto è stato modellato utilizzando il formalismo dei Timed Automa. Il sistema presenta anche in questo caso tre entità La stazione che funge da controllore. I taxi che offrono un servizio. Gli utenti che richiedono un servizio.

32 Stazione

33 Stazione Declaration La stazione presenta delle variabili interne che mappano il numero di taxi presenti nella stazione e il gli id dei taxi presente nella stazione questultima informazione viene mappata con un vettore booleano che ci informa se il taxi e presente o meno in stazione. Vi sono inoltre due metodo che ci permettono di inizializzare e mantenere aggiornato questo vettore.

34 Utenti

35 Lutente presenta un clock tempo utente che tiene conto dello scorrere del tempo al suo interno usato soprattutto per computare la durata in attesa prima che gli venga inviata la lista dei taxi e la durata del viaggio. Risulta chiaro che lutente interagisce con la stazione per la gestione dellassegnamento/scelta del taxi. Per fare ciò usa dei canali di sincronizzazione che sbloccano attivano alcune transazioni condivise. La scelta dell taxi viene fatta mediante luso di una struttura dati condivisa/globale (un vettore di interi) che traccia la posizione del Taxi.

36 Taxi

37 Dichiarazioni Globali Nel sistema considerato abbiamo visto che taxi e utenti interagiscono tra di loro e con la Stazione questo implica che una stazione può parale con tutti i taxi e con tutti gli utenti. Ricordado che la comunicazione è punto punto sono necessarie le seguenti matrici di canali. chan chStation[numUtenti_t][numStazioni_t]; chan chTaxiUtente[numUtenti_t][numTaxi_t]; chan chTaxi[numTaxi_t][numStazioni_t]; chan chNoTaxi[numUtenti_t][numStazioni_t];

38 Dichiarazioni Globali Inoltre ci serve definire gli identificatori dei taxi allintero di un range. typedef int[0,NUMERO_TAXI-1] numTaxi_t; typedef int[0,NUMERO_STAZIONI-1] numStazioni_t; typedef int[0,NUMERO_UTENTI-1] numUtenti_t; Inoltre come già anticipato in precedenza ci serve un vettore che mappa la posizione corrente del Taxi. int sceltaStazioneByTaxi[NUMERO_TAXI];

39 Considerazioni Il sistema cosi come è implementato presenta un problema di deadlock in quanto la scelta delle rotte assegnazione dei taxi e del tutto casuale. Questo potrebbe portare alla situazioni che vi è una stazione in cui troviamo utenti i taxi sono tutti in delle stazione e gli utenti nelle stazioni opposte. Inoltre si puo verificare starvation è possibile che i taxi non scelgano mai una stazione dove è presente un utente che aspetta. Tutto questo può essere aggravato se il numero dei taxi è del tutto inferiore al numero delle stazioni.

40 Soluzione al problema. Per garantire lassenza di starvation e dead-look si è deciso di modificare la logica del taxi come segue. Un taxi può restare inattivo in una stazione solo per un certo intervallo di tempo dopo di che sceglie una stazione da raggiungere. Sul come il taxi sceglie la stazione sta la strategia anti-deadlok e anti-stavation. La strategia usata consiste nel far girare i taxi in tutte le stazioni in modo ordinato. Per fare questo è stato necessario modificare il taxi e la stazione.

41 Taxi

42 Stazione

43 Stazione / Taxi Come si può osservare la stazione e il generico taxi presentano una piccola variante per la gestione del deadlock. Con questa modifica il sistema funziona anche in condizioni particolari in cui sono presenti molte stazioni molti utenti e pochi taxi. La scelta della prossima stazione da visitare quando si lascia una stazione per lunga attesa è numStazioni_t stazioneDaVisitare(){ stazioneVisitare=(stazioneVisitare+1)%NUMERO_STAZIO NI; return stazioneVisitare; }


Scaricare ppt "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."

Presentazioni simili


Annunci Google