「テーマパークのシミュレーション:Rを使って待ち時間を理解する」

Theme Park Simulation Understanding Wait Times Using R

Rでキューの待ち時間を理解し、ビジネスプロセスを最適化するためにテーマパークのシミュレーション

Photo by Thomas Kelley on Unsplash

長い行列はいつも嫌ですよね、特に宇宙を飛び越えたり、グレート・バリアリーフを航海するのを待っている時は。夏休みが続く中、ほとんどの人が何かのために並んでいることでしょうし、あなたはラッキーな人でしょう、まっすぐマジックキングダムに向かっていることを願っています。もしかしたら、このブログを読みながらあなたもその列の中にいるかもしれませんね!

いくつかのコードが例をサポートするために含まれていますが、全体のコードは記事の最後にリンクされている私のGitHub上で見つけることができます。このプロジェクトでは、RとDiscrete Event Simulationのパッケージであるsimmerを使用しています。お楽しみください!

コンセプトのレビュー — Discrete Event Simulation

では、私のノートパソコンでテーマパークをシミュレートするためには何が必要なのでしょうか?それはWreck-it-RalphのGame Central Stationのように見えるのでしょうか?

残念ながら… Rで書かれたコードはDiscrete Event SimulationまたはDESを使用します。これは実際にはプロセスが時間の経過とともにどのように進行するかを示すだけです。DESの主な使用例はプロセスの最適化です。そのため、オペレーションリサーチでよく使用されます。シミュレーションにより、意思決定者は多くの繰り返しの後に典型的なプロセスを表示し、どのように改善できるかを確認することができます。例えば、工場の生産ラインに追加の機械を追加することで製品のボトルネックを減らすことができるでしょうか?

この記事では、DESを架空のディズニーワールドに適用します。このバージョンのパークは少し単純化されており、モデリングを容易にするためのいくつかの追加の仮定があります。

このブログはアプリケーションに焦点を当てているため、理論よりも多くのコード例がありますが、関連するコンポーネントのこのコンセプトレビューは私たちを迅速に理解するのに役立ちます。

コンポーネント

DESが機能するために必要ないくつかの基本的なコンポーネントがあります。それぞれはsimmerを使用して作成しますが、コーディングを始める前にここでそれらを確認しましょう:

  • 軌跡:軌跡はゲストがシミュレーション内でたどるパスです。例えば、ゲストが到着したら、ライドの列に並び、ライドに乗り、そして退場するというような軌跡です。
  • リソース:リソースは軌跡の中で使用されるものです。上記の例では、ライドがリソースです。
  • ジェネレータ:ジェネレータはゲストを生成するために使用するアイテムで、ジェネレータは通常、シミュレーションの間に多くのゲストを生成します。ジェネレータは生成されたゲストがどこに行くべきかを知るために軌跡も必要です。
  • 環境:環境はこのシミュレーション全体が実行される場所であり、私たちの場合はテーマパーク自体です。環境はすべてのリソース、ジェネレータ、および軌跡をカプセル化します。simmerを使用すると、環境はリソースの使用状況も追跡し、報告するため、シミュレーションの分析が簡単になります。

このレビューが完了したら、実際の作業に取り掛かりましょう!以下のシミュレーションはお互いに組み合わされ、どんどん複雑になります。説明のために、コードは最後のシミュレーションまでリファクタリングされず、いくつかの追加のR関数と機能を利用してシミュレーションをクリーンアップしています。

シミュレーション1: リロとスティッチに出会う

最初のシミュレーションは紹介の役割を果たします。このシミュレーションでは、ゲストが到着し、リロとスティッチに会うための列に並び始めます。コーディングの前に、次のコンポーネントについて確認すると役立ちます:

  • 軌跡:パークに到着し、列に並び、キャラクターリソース(リロまたはスティッチ)を使用し、キャラクターリソースを解放し、パークを出る。
  • リソース:ゲストが会えるキャラクター。リロまたはスティッチのどちらかです。したがって、このリソースの容量は2に設定されており、つまり同時に2人のゲストがリソースを占有できます。
  • ジェネレータ:定期的にパークに到着するゲストを生成します。
  • 環境:パーク自体です。

では、各要素のコードを考えてみましょう。Rを使用すると、dplyrなどの他のパッケージを利用して書いたコードを整理することができます。これにより、軌跡の構築が簡単になります:

最初に、ゲストは他のゲストによる使用を制限するキャラクターを獲得します。その後、そのリソースでタイムアウトします。タイムアウトとは、何もできなくなることを意味します。ほとんどのシミュレーションでは、タイムアウトの長さは実際のプロセスに基づいています。しかし、この架空のシナリオでは、タイムアウトの長さは正規分布からサンプリングされます。最後に、ゲストはリソースを解放し、キュー内の別のゲストが再び使用できるようになります。

軌跡は最も複雑な概念です。環境、リソース、ジェネレータはすべて、1つのコードブロックで定義されます。

このコンポーネントセットは再び非常に基本的です。重要なポイントは、リソースの容量が仕様に従って2であることです。ゲストは指数関数に従って到着し、上記で定義された軌跡が与えられます。ゲストの到着も通常は実際のイベントに基づいてモデル化されますが、この例では指数関数でも十分です。

最後のステップは、シミュレーションを実行して分析を行うことです。シミュレーションの実行は、実行と実行するタイムステップの数を入力するだけです。この場合、公園は15時間営業します。分析には、シンマーライブラリの拡張であるsimmer.plotを使用します。これにより、いくつかのシンプルな視覚化が作成されます。

下の最初のプロットは、リソースの利用率を示しています。このシミュレーションでは、利用率はわずか20%です。このパーセンテージは、リソースが使用されたシミュレーション時間の割合を表しています。

Image by author

20%の利用率はかなり低く、理想的には利用率が高いほうが良いです。これはより多くの満足なゲストを意味します!次の視覚化は待ち時間を表し、5つ以上のステップを待つゲストはいません。これは、リソースのタイムアウトが5ステップを中心に正規分布のサンプルに基づいているため、合理的です。ただし、平均待ち時間は非常に低く、青い線で表されています。

Image by author

シミュレーション2:LiloとStitchにファストパスで会う

さて、少し複雑さを加えてみましょう。シミュレーションは上記と同じままです。ただし、優先顧客を追加します。これは、ディズニーパークの「ファストパス」システムを模倣します。実際には、優先顧客が一定の間隔で予約済みのパスを持って到着するでしょう。

優先顧客の優先度は、デフォルトの顧客の0に対して1に設定されます。優先度の値が高いほど、この顧客はキューをスキップして他の優先度の低い顧客よりも先に乗車します。もう1つの追加は、これらの顧客が50ステップごとに到着することです。実際には、彼らは一定の間隔でパスを予約しているでしょう。

Image by author

リソースの利用率が急激に増加したことに注意してください!これは、固定の間隔で到着する確実な顧客がいるためです。逆に、待ち時間が増加しています。これは、元のグループの待ち時間が増加し、ファストパスのゲストも増えたためです。

シミュレーション3:LiloとStitchによる断念付きの会合

列での待ち時間はイライラすることがあり、人々は単に諦めます。これは、断念という考えを数学的に考慮することで説明できます。顧客が長時間列に待っている場合、彼らが単に諦める可能性をモデル化することができます。これは軌跡に追加することで行われます。

顧客の断念にかかる時間は、再び値2を中心に正規分布からサンプリングされます(通常はこれが推定され、より高い値になりますが、この例では我々は辛抱強い顧客を持っているため、断念を理解するのに役立ちます)。重要なのは、ゲストがリソースを手に入れた後に断念を中止する必要があるということです。ゲストは待機期間の終わりに到達した瞬間にすぐに去るわけではありません!

画像: 著者による

この降車は、ゲストが退席するため、リソースの利用が減少しました。ただし、多くのゲストがあきらめるため、待ち時間も短縮されました。退席するゲストの追加効果は、他のゲストが短い待ち行列を体験し、待ち時間も短縮することです。その他のシミュレーションでは、ゲストが降車するまでの時間を増やします。

シミュレーション4: バッチ処理を使用して1台のカートでスペースマウンテンに乗る

さあ、楽しい部分に行きましょう:ライドです。テーマパークのライドでは、simmerのバッチ処理の特徴を活用します。バッチ処理では、例えば、ゲストをスペースマウンテンのカートにグループ化することができます:

パラメータnは、このグループにバッチ処理できるゲストの数を示します。したがって、この場合、各カートには6人のゲストが乗ることができます。timeoutパラメータは、バッチが次の軌跡の一部に移動する前に、いつまでバッチが満たされるのを待つかを示します。つまり、バッチが6人のキャパシティに到達するか、10回のステップが経過するまで、バッチはカートリソースを確保しません。

画像: 著者による

この例の複雑さとゲストのバッチ化、または満員のバッチがないまま離れるための適切な時間を待つ必要性により、利用率が低下します。これらの条件は、待ち時間にも問題を引き起こし、キャラクターの待ち時間と比較して大幅に異なります。ゲストは到着してすぐに出発するか、新しいバッチが出発するまで10回のステップを待つ必要があります。この問題に対処するために、実際にはサイズまたはカートの数が増えるでしょう。

シミュレーション5: スペースマウンテンまたはスプラッシュマウンテンで分岐

さらに現実的にしてみましょう。1つのライドだけではテーマパークは十分ではありません。スプラッシュマウンテンのような新しいライドを追加することで、ゲストの好みをモデル化し、分岐軌跡を使用してどのライドを選ぶかを見ることができます。これは少し複雑ですが、完全なスクリプトでは、軌跡のライド要素が独自の関数として追加されていることが分かります。ここでは、分岐ロジックを示すために、より簡潔なバージョンが示されています:

上記の場合、ゲストはコイントスに基づいて選択しますので、スペースマウンテンかスプラッシュマウンテンを選ぶ可能性は同じです。これはより実際的なアプリケーションの実際の好みからモデル化できます。ここでは、シミュレーションの構築方法も変わります:

この例では、2つの異なるリソースがあります。これは、先述のリロとスティッチの例とは異なり、リロとスティッチは両方ともキャパシティ2の「キャラクター」リソースとしてモデル化されました。ここでは、スプラッシュマウンテンはスペースマウンテンとは別のリソースです。

画像: 著者による

これら2つのライドの利用率は非常に異なります。主に2つの軌跡間のライド時間の違いによるものです。スペースマウンテンに乗るには時間がかかり、ゲストは降車する可能性が高くなります。この複雑さにより、待ち時間もさまざまになりましたが、最適化の観点から言えば、新しいより速いライドを開くことで平均待ち時間を減らすことに成功しました。

シミュレーション6:スケジュールとキューの優先度を使用して公園を開く

最後のシミュレーションでは、これまでに作成したすべてを統合し、公園にスケジュールを追加します。これまでは、リソースの容量を固定値を使用して定義していましたが、別の方法があります:スケジュールの使用です。スケジュールを使用すると、時間間隔に基づいてリソースの容量を制御することができます。

公園のスケジュールは、50回の時間ステップ後に開門し、シミュレーション終了の50回の時間ステップ前に閉鎖されるように制御されます。以下のコードは、再構築された関数の多くを使用しています。ゲートのスケジュールがここで確認すべき最も重要な要素です:

今回の軌跡では、乗り物とキャラクターが組み合わさっています。ゲストがラウンドロビンポリシーで訪れるキャラクターを選択するために、いくつかのコードが追加されました。また、することが増えたことで、より多くのゲストが生成されています。

Image by author

このシミュレーションでは、リソース全体により現実的な利用が広がっています。お客様が行うことが増えたため、各リソースの使用時間が短くなります。また、お客様は公園に入るまで待たなければならないという条件も追加されています。ゲートが利用率の低下を引き起こしていることに注意してくださいが、実際にはほとんど利用されていないことがわかります。お客様がすぐにゲートを利用し、解放するためです。待ち時間もピークに達しており、公園の開園を待ってからライドを待っているゲストもいますが、これはより現実的なシミュレーションです。最初のグループのゲストは、ゲートが開いた瞬間に公園に解放され、乗りたいものや会いたいキャラクターを選ぶことができます。

結論と最終的な考察

ディスクリートイベントシミュレーションは、アナリストや意思決定者にビジネスプロセスを探求する機会を与えます。上記の例では、ゲストが到着し、活動を行い、去るという複雑さが、好みや離脱などの人間の行動を考慮するまで拡張されることができました。

ライドを追加するなどのプロセスを最適化するためにDESを使用することができることが、プロセスを最適化するためにDESがどのように使用されるかを示しています。一方で、離脱などのより困難な行動を追加することで、リソースが正しく設定されていない場合にリソースが使用されないことがわかりました。

この記事がお楽しみいただければ幸いです!もし気に入っていただけた場合は、私のページのフォローをご検討ください。

リソース

コード:

GitHub – josephlewisjgl/DESR:ブログ記事「Simulating a Theme Park」のコードを保持するリポジトリ…

GitHub – josephlewisjgl/DESR:ブログ記事「Simulating a Theme Park: Understanding queue times with R.」のコードを保持するリポジトリ…

github.com

Simmerドキュメント:

6.1 ドーナツショップ | シミュレーションと変化の理解のためのモデリング

これは、ヒューマンスクールで行われる「変化の理解のためのシミュレーションとモデリング」モジュールの講義ノートです…

bookdown.org

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more