forked from adricarda/SMART-M3Project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Instructions.txt
73 lines (49 loc) · 9.74 KB
/
Instructions.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Il file Bus.java all'interno del package main contiene la logica del bus e viene istanziato dalla classe SimConfigurationFrame.java in base alle scelte effettuate dall'utente in fase di inizializzazione. Come prima cosa il bus ottiene una lista di coordinate; questa contiene l'insieme di punti ordinati che l'autobus deve attraversare e costituisce il percorso dell'autobus.
Inoltre l'autobus deve essere in grado di riconoscere se delle coordinate corrispondono alle coordinate di una fermata di sua competenza. Di conseguenza in fase di inizializzazione viene creata una hashMap contenente proprio i punti relativi alle sole fermate che l'autobus deve effettuare.
Cosi` facendo ogniqualvolta l'autobus avanza di un punto, deve interrogarsi per verificare se e` arrivato o no ad una fermata, e a seconda dei casi eseguire le opportune operazioni. Notare che entrambe le liste (lista delle coordinate da attraversare e lista delle coordinate delle fermate) sono ottenute facendo parsing dei relativi file .gpx presenti nella cartella gpx. Una volta inizializzate le strutture dati necessarie l'autobus e` pronto per partire. In particolare vengono inserite tutte le informazioni non mutevoli all'interno della SIB (per maggiori dettagli consultare il grafo dell'ontologia):
-locationData corrispondente all'autobus
-personData corrispondente all'autobus
-busId
-Linea e massimo numero di posti disponibili
Queste informazioni sono statiche, e dunque non variano mai all'interno della stessa simulazione. Tuttavia assumeranno valori diversi gli attributi degli oggetti elencati precedentemente, ad esempio ogniqualvolta l'autobus avanza di una posizione, aggiornerà i literal 'latitude' e 'longitude' dell'oggetto locationData.
In modo analogo vengono aggiornati gli attributi di personData ad ogni fermata.
Le operazioni fondamentali dell'autobus si sviluppano attraverso tre cicli for: il ciclo piu` esterno corrisponde al numero di giorni da simulare, quello intermedio al numero di corse da simulare, mentre quello piu` interno corrisponde alla lista di punti sulla mappa che l'autobus deve attraversare. Ad esempio uno scenario classico d'escuzione dell'autobus e` il seguente:
-si ottengono le coordinate del prossimo punto da attraversare
-si controlla se le coordinate relative al punto corrispondono a quelle di una fermata.
In caso negativo si aggiorna semplicemente l'oggetto locationData (in tal modo il visualizzatore che ha effettuato la subscribe su questa infromazione e` in grado di spostare il merker dell'autobus in tempo reale), in caso affermativo e` necessario inserire nella SIB tutte le informazioni necessarie in accordo con l'ontologia, ad esempio si aggiornano gli attributi dell'oggetto personData, oppure viene indicato l'eventuale presenza del controllore.
Infine le ultime due operazioni fondamentali dell'autobus sono necessarie per avere una corretta simulazione.
A questo scopo infatti, ciascun autobus al termine della simulazione di una giornata, invoca il meotdo SimulationConfig.getInstance().waitForBarrier().
Questa barriera serve a far sì che un autobus non inizi la simulazione del giorni i+1 prima che gli altri autobus abbiano terminato la simulazione del giorno i.
In modo del tutto analogo e` presente una barriera al termine dell'intera simulazione; in questo modo solo quando tutti gli autobus hanno percorso l'ultima corsa dell'ultimo giorno di simulazione, viene sbloccato il main, che successivamente invoca il metodo opportuno sulla classe StatisticsFrame per calcolare e visualizzare a schermo le statistiche della simulazione.
La generazione delle persone che salgono e scendono ad ogni fermata avviene internamente alla classe "Bus", così come l'emissione delle multe da parte del controllore quando quest'ultimo sale a bordo del pullman.
La logica di generazione delle persone fa uso di sei variabili ("descendedRealPerson", "ascendedRealPerson", "descendedPayingPerson", "ascendedRealPerson", "realPerson" e "payingPerson") che tengono il conto delle persone, paganti e non, salite e scese ad ogni fermata, e di quelle paganti e non presenti in un determinato istante nel bus.
Ad ogni fermata (eccetto l'ultima) vengono generate randomicamente le persone reali che salgono (dal metodo "generateAscendingRealPerson") tenendo in considerazione le persone reali attualmente a bordo e la massima capienza dell'autobus (configurabile nella classe "SimulationConfig" che contiene i parametri principali dell'applicazione).
Successivamente si determina il numero di persone paganti fra quelle reali salite (metodo "generateAscendingPayingPerson") utilizzando la probabilità di evasione del biglietto (reperibile nella classe "SimulationConfig" e configurabile dal frame iniziale "SimConfigurationFrame").
Quindi si generano casualmente le persone reali che scendono (metodo "generateDescendingRealPerson") fra le persone reali presenti al momento sul pullman.
Infine viene determinato il numero di persone paganti scese (metodo "generateDescendingPayingPerson") fra le reali che scendono, tenendo in considerazione sia la probabilità di evasione del biglietto che il numero di persone reali e paganti presenti a bordo.
Dopo aver generato i flussi di persone in salita/discesa si aggiornano le variabili "realPerson" e "payingPerson".
All'ultima fermata invece si fanno semplicemente scendere tutte le persone a bordo.
I valori delle variabili "realPerson", "payingPerson", "ascendedRealPerson" e "ascendedPayingPerson" vengono scritti dall'autobus nella SIB ad ogni fermata inserendo nuove istanze per le entità "Affluence" (relativa a "realPerson" e "payingPerson") e "GetOn" (per "ascendedRealPerson" e "ascendedPayingPerson").
L'emissione delle multe avviene alla salita del controllore sul bus, cioè quando la variabile "inspectorPresent" assume il valore "true".
Il controllore multerà tutte le persone sprovviste di biglietto presenti sul bus nella tratta fra la fermata in cui sale e la fermata successiva (ricordiamo che è stato supposto che il controllore scenda alla fermata successiva a quella in cui è salito).
Il numero di multe effettuate è ottenuto quindi semplicemente dalla sottrazione fra le persone reali a bordo e quelle paganti, ed è salvato nella variabile "fines".
Per questa operazione non è necessaria una query del controllore alla SIB in quanto salendo sul pullman è in grado di vedere "con i suoi occhi" chi ha pagato e chi no.
Dopo aver determinato il numero di multe effettuate, tale valore viene salvato nella SIB come nuova istanza dell'entità "Report".
Tutti i dati di simulazione forniti all'avvio sono disponibili all'interno del programma tramite il singleton SimulationConfig.
Durante la fase di inizializzazione del sistema vengono inseriti nella SIB anche tutti i dati relativi alle fermate. Anche in questo caso i dati sono resi disponibili al programma tramite file gpx. Per la generazione dei controllori alle fermate si utilizzano due dati: il numero massimo di controllori presenti e la probabilità di comparsa ad una determinata fermata. La lista di tutte le fermate presenti nel sistema viene "mescolata" e scansionata. Per ogni fermata viene quindi applicata la probabilità di comparsa del controllore. Tutto ciò avviene fino al raggiungimento del numero di controllori massimi nel sistema. La generazione dei controllori avverrà quindi solamente all'avvio del sistema.
Dal punto di vista delle utilità prodotte è presente un file con la configurazione del server dove è presente la SIB, una classe che contiene tutte le informazioni dell'ontologia e la classe Triple. Quest'ultima permette di aggiungere un livello di astrazione maggiore per l'inserimento delle triple all'interno della SIB. Fornisce quindi all'utente una vista sotto forma di soggetto, predicato e oggetto interfacciandosi con le API pre-esistenti che utilizzano solamente dei Vector<String>.
I parser SAX permettono di analizzare dei file xml per ricavare l'elenco dei punti di cui è composto il percorso di una linea e l'elenco delle fermate per ogni linea. Nel caso dei punti appartenenti al percorso il parser si limiterà ad estrapolare le coordinate di ogni punto, mentre per le fermate verrà considerato anche il tag contenente il nome della fermata.
"SimConfigurationFrame" provvede invece a gestire il frame iniziale, recuperando i valori parametrizzabili inseriti dall'utente e settandoli nel "SimulationConfig".
STATISTICHE FINALI:
Le statistiche finali, stampate in un frame apposito, sono gestite da due classi:
1) StatisticsFrame -> Parte grafica
2) StatisticsManager -> logica di business (la parte operativa)
StatisticsFrame.java:
Questa classe rappresenta il frame grafico dove vengono visualizzate le statistiche elaborate alla fine della simulazione; è invocata dal main (Main.java class).
Essenzialmente questa classe ha un solo compito: la composizione del frame grafico dove vengono stampate le statistiche (in una JTextArea).
Il calcolo delle statistiche non è demandato a questa classe, ma al Singleton StatisticsManager.java, opportunamente sfruttato attraverso il proprio metodo di output economicSummary().
StatisticsManager.java:
In questa classe vengono effettuati tutti i calcoli necessari alla composizione delle statistiche relative alla simulazione appena terminata.
Ogni statistica realizzata ha un metodo dedicato che effettua tutta l'elaborazione necessaria alla composizione di quella determinata statistica.
L'unico metodo visibile dall'esterno, oltre alla getInstance() (Ricordiamo che StatisticsManager è un Singleton), è economicSummary(), dove vengono invocati sequenzialmente i metodi privati relativi ad ogni statistica.
Quasi tutti i metodi effettuano delle query alla SIB sfruttando l'espressività del linguaggio SPARQL, mentre la join è effettuata dentro al costruttore (invocato opportunamente dalla getInstance()).