Simulare un Parco Divertimenti Comprendere i tempi di attesa con R

Simulazione Parco Divertimenti Tempi attesa con R

Simulare un parco a tema per capire i tempi di attesa e imparare come ottimizzare i processi aziendali in R.

Foto di Thomas Kelley su Unsplash

Le lunghe code sono sempre sgradevoli, specialmente quando si sta aspettando di volare nello spazio o di navigare lungo la Grande Barriera Corallina. Mentre le vacanze estive continuano, sono sicuro che quasi tutti faranno la fila per qualcosa, e sperabilmente, avrete la fortuna di essere diretti dritti verso il Magic Kingdom. Forse siete in una di quelle code mentre leggete questo blog!

Del codice è incluso per supportare gli esempi, ma il codice completo può essere trovato sul mio GitHub, che è collegato alla fine dell’articolo. Il progetto utilizza R e il pacchetto simmer per la simulazione di eventi discreti. Buona lettura!

Revisione del concetto – Simulazione di eventi discreti

Cos’è necessario per simulare un parco a tema sul mio computer portatile? E assomiglierà in qualche modo a Game Central Station di Wreck-it-Ralph?

Temo di no… il codice scritto in R utilizzerà la Simulazione di Eventi Discreti o DES, che mostra semplicemente ciò che potrebbe accadere in un processo nel tempo. Il principale caso d’uso di DES è ottimizzare i processi, motivo per cui viene comunemente utilizzato nella ricerca operativa. Le simulazioni consentono ai decisori di visualizzare un processo tipico dopo molte iterazioni e vedere come potrebbe essere migliorato. Ad esempio, l’aggiunta di macchine extra a una linea di produzione potrebbe ridurre i collo di bottiglia nella produzione di un prodotto?

Questo articolo applicherà DES a un ipotetico Disney World. Questa versione del parco sarà un po’ più semplice e avrà alcune supposizioni extra per rendere più semplice la modellizzazione.

Dato che questo blog si concentra più sull’applicazione, ci saranno molti esempi di codice rispetto alla teoria, ma questa revisione concettuale dei componenti coinvolti dovrebbe aiutarci a metterci al passo.

Componenti

Ci sono alcuni componenti di base necessari per il funzionamento di DES. Ognuno di essi sarà creato utilizzando simmer, ma facciamone una revisione qui prima di iniziare la codifica:

  • Traiettoria: Una traiettoria è un percorso che un ospite seguirà nella simulazione. Ad esempio, quando un ospite arriva, potrebbe mettersi in coda per una corsa, fare una corsa e poi lasciare. Questa sarebbe la sua traiettoria.
  • Risorsa: Una risorsa è una cosa utilizzata durante la traiettoria. Nell’esempio sopra, la corsa sarebbe una risorsa.
  • Generatore: Un generatore è un elemento che utilizziamo per generare gli ospiti, e i generatori genereranno tipicamente molti ospiti nel corso di una simulazione. Il generatore ha anche bisogno di una traiettoria per sapere dove devono andare gli ospiti generati.
  • Ambiente: L’ambiente è dove questa simulazione intera viene eseguita, nel nostro caso questo è il parco a tema stesso. Racchiude tutte le nostre risorse, generatori e traiettorie. Con simmer c’è un vantaggio aggiuntivo che l’ambiente traccerà e riporterà anche l’uso delle nostre risorse, il che rende l’analisi della simulazione molto più semplice.

Con questa revisione completata, mettiamoci all’opera! Le simulazioni di seguito si basano l’una sull’altra e aumentano di complessità man mano che procedono. A scopo illustrativo, il codice non è refattorizzato fino all’ultima simulazione, che sfrutta alcune funzioni e caratteristiche aggiuntive di R per pulire la simulazione.

Simulazione Uno: Incontro con Lilo e Stitch

La prima simulazione servirà come introduzione. In questa simulazione, gli ospiti arrivano e iniziano a mettersi in fila per vedere Lilo e Stitch. Prima di iniziare a codificare, è utile rivedere quali saranno i componenti:

  • Traiettoria: Arrivare al parco, mettersi in coda, utilizzare la risorsa personaggio (Lilo o Stitch), rilasciare la risorsa personaggio e lasciare il parco.
  • Risorsa: Personaggio che gli ospiti possono incontrare. Sia Lilo che Stitch, quindi la capacità per questa risorsa è impostata su due, il che significa che può essere occupata contemporaneamente da due ospiti.
  • Generatore: Genererà periodicamente gli ospiti che arrivano al parco.
  • Ambiente: Il parco stesso.

Ora pensiamo al codice per ciascun elemento. R ci consente di sfruttare altri pacchetti come dplyr per organizzare il codice che scriviamo. Questo semplifica molto la costruzione delle traiettorie:

Prima di tutto, l’ospite acquisisce un personaggio che lo blocca impedendone l’uso da parte di altri ospiti. Poi passa il tempo con quella risorsa. Passare il tempo significa semplicemente che non possono fare altro. La durata del timeout nella maggior parte delle simulazioni sarà basata su un processo reale. Tuttavia, in questo scenario inventato, la durata del timeout viene estratta da una distribuzione normale. Infine, l’ospite rilascia la risorsa e può essere nuovamente utilizzata da un altro ospite in coda.

La traiettoria è il concetto più complicato. L’ambiente, le risorse e il generatore sono tutti definiti insieme in un unico blocco di codice:

Questo insieme di componenti è ancora molto basilare. Le note importanti sono che la risorsa ha una capacità di due, come specificato. Gli ospiti arrivano secondo una funzione esponenziale e vengono forniti con la traiettoria definita in precedenza. L’arrivo degli ospiti sarebbe anche tipicamente modellato dopo un evento reale, ma per l’esempio, l’esponenziale funzionerà benissimo!

Il ultimo passo è eseguire la simulazione e fare alcune analisi. Eseguire la simulazione è semplice come digitare “run” e fornire un numero di passaggi temporali da eseguire. In questo caso, il parco sarà aperto per 15 ore. Per l’analisi, useremo simmer.plot, un’estensione della libreria simmer che costruisce alcune visualizzazioni semplici per noi:

Il primo grafico qui sotto mostra l’utilizzo delle risorse. Per questa simulazione, la nostra utilizzo si ferma al 20%. Questa percentuale rappresenta la proporzione di tempo di simulazione in cui la risorsa è stata utilizzata.

Immagine dell'autore

Il valore di utilizzo del 20% è abbastanza basso e idealmente avremmo un utilizzo più alto, poiché significa più ospiti soddisfatti! La successiva visualizzazione rappresenta i tempi di attesa, senza ospiti in attesa per più di 5 passaggi temporali. Questo ha senso poiché il timeout della risorsa si basa su un campione da una distribuzione normale attorno a 5 passaggi. Il tempo medio di attesa, però, è molto più basso, rappresentato dalla linea blu.

Immagine dell'autore

Simulazione Due: Incontro con Lilo e Stitch con pass rapidi

Ora aggiungiamo un po’ di complessità, iniziando lentamente. La simulazione rimarrà la stessa di quella precedente. Tuttavia, aggiungeremo clienti prioritari. Questi simuleranno il sistema “FastPass” nei parchi Disney. In pratica, tutto ciò che facciamo è generare un nuovo cliente che ha la priorità:

Si noti che questo cliente ha una priorità di uno, a differenza del cliente predefinito che di default è zero. Un valore di priorità più alto significa che questo cliente salterà la coda e salirà sulle giostre prima di tutti i clienti di priorità inferiore. L’altra aggiunta è che questi clienti arrivano ogni 50 passaggi temporali. In realtà, avrebbero prenotato un pass per un certo intervallo di tempo uniformemente distribuito.

Immagine dell'autore

Si noti che l’utilizzo delle risorse è aumentato drasticamente! Questo perché ora c’è un cliente garantito che arriva e prenderà il posto di tutti gli altri clienti all’intervallo fisso. Al contrario, i tempi di attesa sono aumentati, il che segue logicamente poiché ci sono non solo più ospiti, ma anche più ospiti con FastPass, il che aumenta il tempo di attesa per il gruppo originale.

Simulazione Tre: Incontro con Lilo e Stitch con abbandono

Aspettare in coda può essere frustrante e le persone spesso si arrendono. Questo può essere considerato matematicamente attraverso l’idea di abbandono. Se un cliente attende in coda per molto tempo, possiamo modellare la possibilità che si arrenda. Questo viene fatto aggiungendo alla traiettoria:

Il tempo necessario perché un cliente si arrenda viene nuovamente campionato da una distribuzione normale, questa volta intorno al valore di 2 (tipicamente, questo sarebbe stimato e sarebbe maggiore, ma per questo esempio abbiamo clienti molto impazienti per comprendere l’abbandono). È importante interrompere l’abbandono una volta che l’ospite ha ottenuto una risorsa. Gli ospiti non lascerebbero subito alla fine del periodo di attesa!

Immagine dell'autore

Questo recesso ha ridotto ultimamente l’utilizzo delle risorse poiché sempre più ospiti se ne vanno senza utilizzare la risorsa. Tuttavia, ha anche ridotto i tempi di attesa poiché molti ospiti si arrendono semplicemente, quindi il loro tempo di attesa non è incluso. Un effetto aggiuntivo degli ospiti che se ne vanno è che gli altri ospiti vivono una coda più breve che riduce anche i tempi di attesa. Per il resto delle simulazioni, aumenteremo il tempo necessario affinché gli ospiti si ritirino.

Simulazione Quattro: Giro sulla Space Mountain con un carrello usando il batching

Ora passiamo alla parte divertente: le attrazioni. Le attrazioni nel parco a tema sfrutteranno la funzione di batching in simmer. Il batching ci consente di raggruppare gli ospiti in un carrello della Space Mountain, ad esempio:

Il parametro n indica quanti ospiti possono essere raggruppati in questo gruppo, quindi in questo caso, ogni carrello può contenere 6 ospiti. Il parametro di timeout indica quanto tempo un batch deve attendere per essere riempito prima di passare alla fase successiva della traiettoria. Quindi il batch può raggiungere la sua capacità di 6 ospiti o possono passare 10 intervalli di tempo prima che il batch prenda una risorsa del carrello.

Immagine dell'autore

Con la complessità aggiunta di questo esempio e la necessità che gli ospiti vengano raggruppati o almeno aspettino un tempo appropriato prima di andarsene senza un batch completo, l’utilizzo diminuisce. Queste condizioni causano anche un problema per i tempi di attesa che variano drasticamente rispetto ai tempi di attesa dei personaggi. Un ospite potrebbe arrivare e andarsene immediatamente o dover aspettare 10 intervalli di tempo completi affinché un nuovo batch parta. Per affrontare questo problema nella realtà, la dimensione o il numero di carrelli sarebbe aumentato.

Simulazione Cinque: Space Mountain o Splash Mountain con branchiamento

Rendiamo le cose ancora più realistiche; un parco a tema non sarebbe buono con una sola attrazione. Aggiungendo una nuova attrazione come Splash Mountain, possiamo modellare le preferenze degli ospiti e utilizzare le traiettorie di branchiamento per vedere su quale attrazione andranno. Questo è un po’ più complicato, e nello script completo, si può vedere che gli elementi dell’attrazione della traiettoria sono stati aggiunti alle loro proprie funzioni. Per semplicità, qui viene mostrata una versione più concisa solo per dimostrare la logica di branchiamento:

Nel caso sopra, gli ospiti scelgono in base a un lancio di moneta, quindi è altrettanto probabile che un ospite scelga Space o Splash Mountain. Questo potrebbe essere modellato da una preferenza effettiva in un’applicazione più reale. Anche la costruzione della simulazione cambia un po’ qui:

In questo esempio, ci sono due risorse distinte. Questo è diverso dagli esempi di Lilo e Stitch sopra poiché Lilo e Stitch sono stati entrambi modellati come una risorsa “personaggio” con capacità due. Qui invece, Splash Mountain è una risorsa separata rispetto a Space Mountain.

Immagine dell'autore

L’utilizzo di queste due attrazioni è molto diverso, principalmente a causa della differenza nei tempi di attrazione tra le due traiettorie. Il fatto che il giro sulla Space Mountain duri più a lungo e che gli ospiti siano più propensi a ritirarsi ha anche creato un tempo di attesa più vario, tuttavia dal punto di vista dell’ottimizzazione, siamo riusciti a migliorare con successo l’esperienza degli ospiti riducendo il tempo medio di attesa nell’apertura di un’attrazione più veloce.

Simulazione Sei: Apertura del parco utilizzando programmi e preferenze di coda

La simulazione finale unisce tutto ciò che abbiamo creato e aggiunge un programma al parco. Fino ad ora abbiamo definito la capacità delle risorse utilizzando valori fissi. C’è un’alternativa: utilizzare programmi. I programmi ci permettono di controllare la capacità di una risorsa in base agli intervalli di tempo.

Il programma del parco sarà controllato da un cancello che si apre dopo 50 passaggi di tempo e si chiude 50 passaggi di tempo prima della fine della simulazione. Il codice seguente utilizza molte delle funzioni ristrutturate, che sono ancora una volta collegate nel repository GitHub sottostante. Il programma del cancello è la cosa più importante da esaminare qui:

Questa volta la nostra traiettoria combina le attrazioni e i personaggi. Sono stati aggiunti altri pezzi di codice per far sì che gli ospiti selezionino i personaggi che visitano secondo una politica round-robin. Vengono generati anche più ospiti ora che c’è di più da fare.

Immagine dell'autore

In questa simulazione si osserva una distribuzione dell’utilizzo più realistica su tutte le risorse. Ci sono più cose che i clienti possono fare, quindi ogni risorsa trascorre meno tempo in uso. È anche previsto che i clienti debbano aspettare per entrare nel parco. Si noti che il cancello causa gran parte di questa riduzione nell’utilizzo ma in realtà vede poco utilizzo stesso perché i clienti lo prendono e lo rilasciano immediatamente. I tempi di attesa raggiungono anche il loro picco qui, con gli ospiti in attesa che il parco apra e poi per le attrazioni nel parco, ma questa è una simulazione molto più realistica. Il primo gruppo di ospiti viene liberato nel parco per scegliere cosa vogliono fare e chi vogliono incontrare, non appena si aprono i cancelli.

Conclusioni e considerazioni finali

La simulazione di eventi discreti offre agli analisti e ai decisori la possibilità di esplorare i processi aziendali. Negli esempi sopra, la complessità è stata in grado di estendersi dall’arrivo di un ospite, alla realizzazione di un’attività e alla partenza, fino a tener conto delle preferenze e del comportamento umano come il rinunciare.

Alcune delle decisioni prese durante il processo, come l’aggiunta di più attrazioni, hanno dimostrato come DES possa essere utilizzato per ottimizzare i processi. D’altra parte, l’aggiunta di comportamenti più complessi come il rinunciare ha mostrato come le risorse possano essere sottoutilizzate se non sono impostate correttamente.

Spero che abbiate apprezzato questo articolo! Se è così, vi invito a seguire la mia pagina per altri contenuti di data science.

Risorse

Codice:

GitHub – josephlewisjgl/DESR: Repository che contiene il codice dall’articolo del blog Simulating a Theme Park…

Repository che contiene il codice dall’articolo del blog Simulating a Theme Park: Understanding queue times with R. – GitHub …

github.com

Documentazione di Simmer:

6.1 The donut shop | Simulazione e modellazione per comprendere il cambiamento

Queste sono le note di lezione per il modulo Simulazione e modellazione per comprendere il cambiamento tenuto nella Scuola di Scienze Umane…

bookdown.org