Python PR

【Python】Simpyではじめる離散イベントシミュレーション -作業工程を見直して生産性向上のヒントを得る-

Simpyではじめる離散イベントシミュレーション
記事内に商品プロモーションを含む場合があります

こんにちは。現役エンジニアの”はやぶさ”@Cpp_Learningです。社内のDX推進を頑張ってます!

本記事では離散イベントシミュレーションフレームワークのSimpyを活用した、作業工程の見直しについて説明します。

離散イベントシミュレーションを行うモチベーション

複数の工程が必要な作業や実験をする際、制限時間内で何サイクル回せるかを事前確認したいときがよくあります。

実験サイクル例
  1. 準備:5[sec]
  2. 工程A:10[sec]
  3. 工程B:8[sec]
  4. 工程C:12[sec]
  5. 片付け:10[sec]
Simpyではじめる離散イベントシミュレーション

上の例では、1サイクル回すのに45[sec]かかるので、100[sec]では2サイクル+工程Aの途中で終了します。これくらいの時間の見積もりなら、それほど難しくありませんが、各工程でばらつきがある場合はどうでしょうか?

実験サイクル例 -ばらつき有-
  1. 準備:5[sec]
  2. 工程A:10[sec]
  3. 工程B:8 + σ [sec]、σ = 0~10[sec]
  4. 工程C:12 + σ [sec]、σ = 0~10[sec]
  5. 片付け:10[sec]
Simpyではじめる離散イベントシミュレーション

例えば、工程Bと工程Cでσ=0~10[sec] のばらつきが発生すると仮定したとき、100[sec]以内に何サイクル回せるかをシミュレーションで確認したくなります。

Simpyではじめる離散イベントシミュレーション

さらに作業員が2人に増えたときや工程Aで待ちが発生するなどの複数の制約も考慮したシミュレーションをしたいことがあります。

ここまで説明したシミュレーションについては Simpy を使えば、比較的簡単に実現できます。

実践!Simpyではじめる離散イベントシミュレーション

簡単なシミュレーションから始め、少しづつ複雑なシミュレーションを実践していきます。

インストール

最初に以下のコマンドで Simpy をインストールします。

pip install simpy

以降からソースコード書いていきます。

本記事のソースコードはGoogle Colabで動作確認しました

Simpyの基本的な使い方

Simpyではじめる離散イベントシミュレーション

上図の実験サイクルは、以下のコードでシミュレーションできます。

==== Start experiment No.1 at 0 [sec] ====
Process A at 5 [sec]
Process B at 15 [sec]
Process C at 27 [sec]
==== Finish experiment No.1 at 35 [sec] ====
==== Start experiment No.2 at 45 [sec] ====
Process A at 50 [sec]
Process B at 60 [sec]
Process C at 72 [sec]
==== Finish experiment No.2 at 80 [sec] ====
==== Start experiment No.3 at 90 [sec] ====
Process A at 95 [sec]

上記がターミナルに表示され、100[sec]では3サイクル目の工程Aの途中で終了することを確認できます。

このコードを雛形に少しづつ条件や制約を増やしたシミュレーションをしていきます。

Simpyでばらつきを考慮したシミュレーション

工程Bと工程Cでσ=0~10[sec]のばらつき発生を仮定したシミュレーションは random 追加で実現できます。

==== Start experiment No.1 at 0 [sec] ====
Process A at 5 [sec]
Process B at 15 [sec]
Process C at 30.4 [sec]
==== Finish experiment No.1 at 41.53 [sec] ====
==== Start experiment No.2 at 51.53 [sec] ====
Process A at 56.53 [sec]
Process B at 66.53 [sec]
Process C at 81.44 [sec]
==== Finish experiment No.2 at 99.1 [sec] ====

シード固定しなければ、毎回ランダムなばらつきが発生します。上記では 99.1[sec]で2サイクル目が終了していますが、2サイクル目の工程Cの途中で終了するケースもありました。

つまり100[sec]以内で2サイクルがギリギリ終わるときと、終わらないときがあるというシミュレーション結果が得られました。

作業員を増やしてシミュレーション

Simpyではじめる離散イベントシミュレーション Simpyではじめる離散イベントシミュレーション

作業員を2人に増やしてみます。以下のように、operator関連のコードを追加すればOKです。

==== Operator No.0 : Start experiment No.1 at 0 [sec] ====
==== Operator No.1 : Start experiment No.1 at 0 [sec] ====
Operator No.0 : Process A at 5 [sec]
Operator No.1 : Process A at 5 [sec]
Operator No.0 : Process B at 15 [sec]
Operator No.1 : Process B at 15 [sec]
Operator No.1 : Process C at 31.95 [sec]
Operator No.0 : Process C at 34.24 [sec]
==== Operator No.1 : Finish experiment No.1 at 40.53 [sec] ====
==== Operator No.0 : Finish experiment No.1 at 45.21 [sec] ====
==== Operator No.1 : Start experiment No.2 at 50.53 [sec] ====
==== Operator No.0 : Start experiment No.2 at 55.21 [sec] ====
Operator No.1 : Process A at 55.53 [sec]
Operator No.0 : Process A at 60.21 [sec]
Operator No.1 : Process B at 65.53 [sec]
Operator No.0 : Process B at 70.21 [sec]
Operator No.1 : Process C at 86.97 [sec]
Operator No.0 : Process C at 88.34 [sec]
==== Operator No.1 : Finish experiment No.2 at 98.76 [sec] ====

Operator No.0 と No.1 は同時に作業を開始しますが、工程BとCでばらつきが発生するため、以下のシミュレーション結果となりました。

  • Operator No.0:2サイクル目の工程Cの途中で100[sec]経過
  • Operator No.1:98.76[sec]で2サイクル目まで終了

待ちが発生するシミュレーション

Simpyではじめる離散イベントシミュレーション

リソースの都合で、並行処理できないケースもあります。例えば、上図の工程Aは専用機械を使うため、1回の実行で1つの処理しかできないと仮定します。つまり、Operator No.0 が工程Aを終了するまで、Operator No.1 は待機する必要があります。

このようなリソース制約は simpy.resource で定義できます。

==== Operator No.0 : Start experiment No.1 at 0 [sec] ====
==== Operator No.1 : Start experiment No.1 at 0 [sec] ====
Operator No.0 : Process A at 5 [sec]
Operator No.0 : Process B at 15 [sec]
Operator No.1 : Process A at 15 [sec]
Operator No.1 : Process B at 25 [sec]
Operator No.0 : Process C at 27.51 [sec]
==== Operator No.0 : Finish experiment No.1 at 41.45 [sec] ====
Operator No.1 : Process C at 44.53 [sec]
==== Operator No.0 : Start experiment No.2 at 51.45 [sec] ====
Operator No.0 : Process A at 56.45 [sec]
==== Operator No.1 : Finish experiment No.1 at 57.11 [sec] ====
Operator No.0 : Process B at 66.45 [sec]
==== Operator No.1 : Start experiment No.2 at 67.11 [sec] ====
Operator No.1 : Process A at 72.11 [sec]
Operator No.0 : Process C at 80.0 [sec]
Operator No.1 : Process B at 82.11 [sec]
==== Operator No.0 : Finish experiment No.2 at 92.51 [sec] ====

Operator No.0 と No.1 は同時に作業を開始しますが、工程Aで待ちが発生するため、1サイクル目の 「Operator No.0 が工程Bを開始する時間」と「Operator No.1 が工程Aを開始する時間」が同じ15[sec]になっています。

最終的には以下のシミュレーション結果となりました。

  • Operator No.0:92.51[sec]で2サイクル目まで終了
  • Operator No.1:2サイクル目の工程Bの途中で100[sec]経過
  • 100[sec]で待ちが発生したのは1回だけ(※)

(※)シミュレーション時間やばらつき次第で、複数の待ちが発生することを確認

このシミュレーション結果を考慮して「工程A用の機械を増やす」・「作業員を増やす」などの意思決定をするのが良いと思います。

スポンサーリンク

まとめ -Simpyではじめる離散イベントシミュレーション-

離散イベントシミュレーションフレームワーク Simpy の基本的な使い方から実践的なシミュレーションまでをソースコード付きで説明しました。

シミュレーション結果から生産性向上のヒントを得て、作業工程の見直しなどに繋げると良いと考えています。

はやぶさ
はやぶさ
データやシミュレーションを上手に活用して、生産性向上を目指しましょう。

PICK UP BOOKS

  • 数理モデル入門
    数理モデル
  • Jetoson Nano 超入門
    Jetoson Nano
  • 図解速習DEEP LEARNING
    DEEP LEARNING
  • Pythonによる因果分析
    Python