mcpField
S
simpy

simpy

github.com/crazymsnデータ・データベース2336 回インストール22 週間前に更新
リポジトリ

simpy について

SimPyは、標準Pythonをベースにした離散イベントシミュレーションフレームワークを使うためのスキルです。共有リソースを取り合うシステムをモデル化し、待ち行列や資源利用、工程の分析を行えます。リアルタイムシミュレーションと監視機能も備えています。

主な機能

  1. 01ジェネレーター関数によるプロセスモデル化
  2. 02共有リソースと待ち行列の管理
  3. 03イベントスケジューリングとプロセス同期
  4. 04実時間に同期したシミュレーション
  5. 05リソース監視、統計、CSV出力

活用シーン

  1. 01製造ラインと機械スケジューリングの評価
  2. 02救急患者の流れと人員配置のシミュレーション
  3. 03ネットワークトラフィックと帯域割り当ての分析
  4. 04コールセンターなどのサービス容量計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/crazymsn/academic-skills --skill simpy

インストール後、Claude Code で/simpyを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
events.md
monitoring.md
process-interaction.md
real-time.md
resources.md
scripts/
basic_simulation_template.py
resource_monitor.py

詳細

SimPy - 離散イベントシミュレーション

概要

SimPy は、標準的な Python をベースとしたプロセスベースの離散イベントシミュレーションフレームワークです。エンティティ(顧客、車両、パケットなど)が互いに相互作用し、時間の経過とともに共有リソース(サーバー、機械、帯域幅など)を取り合うようなシステムのモデリングに SimPy を使用します。

主な機能:

  • Python のジェネレーター関数を使用したプロセスモデリング
  • 共有リソース管理(サーバー、コンテナ、ストア)
  • イベント駆動型のスケジューリングと同期
  • 壁時計時刻と同期するリアルタイムシミュレーション
  • 包括的なモニタリングとデータ収集

このスキルを使用するタイミング

次のような場合に SimPy スキルを使用します:

  1. 離散イベントシステムのモデリング - イベントが不規則な間隔で発生するシステム
  2. リソースの競合 - エンティティが限られたリソース(サーバー、機械、人員)を取り合う場合
  3. 待ち行列分析 - 待ち行列、サービス時間、スループットの検討
  4. プロセスの最適化 - 製造、物流、またはサービスプロセスの分析
  5. ネットワークシミュレーション - パケットルーティング、帯域幅割り当て、レイテンシ分析
  6. キャパシティプランニング - 望ましい性能を得るための最適なリソース量の決定
  7. システム検証 - 実装前のシステム挙動のテスト

適していない用途:

  • 固定の時間刻みを用いる連続シミュレーション(SciPy の ODE ソルバーを検討してください)
  • リソースを共有しない独立したプロセス
  • 純粋な数理最適化(SciPy の optimize を検討してください)

クイックスタート

基本的なシミュレーションの構造
import simpy

def process(env, name):
    """A simple process that waits and prints."""
    print(f'{name} starting at {env.now}')
    yield env.timeout(5)
    print(f'{name} finishing at {env.now}')

# Create environment
env = simpy.Environment()

# Start processes
env.process(process(env, 'Process 1'))
env.process(process(env, 'Process 2'))

# Run simulation
env.run(until=10)
リソースの使用パターン
import simpy

def customer(env, name, resource):
    """Customer requests resource, uses it, then releases."""
    with resource.request() as req:
        yield req  # Wait for resource
        print(f'{name} got resource at {env.now}')
        yield env.timeout(3)  # Use resource
        print(f'{name} released resource at {env.now}')

env = simpy.Environment()
server = simpy.Resource(env, capacity=1)

env.process(customer(env, 'Customer 1', server))
env.process(customer(env, 'Customer 2', server))
env.run()

中核となる概念

1. Environment

シミュレーション環境は、時間を管理し、イベントをスケジュールします。

import simpy

# Standard environment (runs as fast as possible)
env = simpy.Environment(initial_time=0)

# Real-time environment (synchronized with wall-clock)
import simpy.rt
env_rt = simpy.rt.RealtimeEnvironment(factor=1.0)

# Run simulation
env.run(until=100)  # Run until time 100
env.run()  # Run until no events remain
2. プロセス

プロセスは Python のジェネレーター関数(yield 文を含む関数)を使用して定義します。

def my_process(env, param1, param2):
    """Process that yields events to pause execution."""
    print(f'Starting at {env.now}')

    # Wait for time to pass
    yield env.timeout(5)

    print(f'Resumed at {env.now}')

    # Wait for another event
    yield env.timeout(3)

    print(f'Done at {env.now}')
    return 'result'

# Start the process
env.process(my_process(env, 'value1', 'value2'))
3. イベント

イベントは、プロセスの同期を行うための基本的な仕組みです。プロセスはイベントを yield し、そのイベントがトリガーされると再開します。

一般的なイベントの種類:

  • env.timeout(delay) - 時間の経過を待機
  • resource.request() - リソースを要求
  • env.event() - カスタムイベントを作成
  • env.process(func()) - イベントとしてのプロセス
  • event1 & event2 - すべてのイベントを待機(AllOf)
  • event1 | event2 - いずれかのイベントを待機(AnyOf)

リソース

SimPy は、さまざまなシナリオに対応する複数のリソース型を提供します。詳細は references/resources.md を参照してください。

リソース型の概要
リソース型用途
Resource容量が限られたもの(サーバー、機械)
PriorityResource優先度に基づくキューイング
PreemptiveResource高優先度のものが低優先度のものを割り込み可能
Containerバルク材料(燃料、水)
StorePython オブジェクトの保管(FIFO)
FilterStore条件を指定した選択的な取り出し
PriorityStore優先度順に並んだアイテム
クイックリファレンス
import simpy

env = simpy.Environment()

# Basic resource (e.g., servers)
resource = simpy.Resource(env, capacity=2)

# Priority resource
priority_resource = simpy.PriorityResource(env, capacity=1)

# Container (e.g., fuel tank)
fuel_tank = simpy.Container(env, capacity=100, init=50)

# Store (e.g., warehouse)
warehouse = simpy.Store(env, capacity=10)

一般的なシミュレーションパターン

パターン 1: 顧客とサーバーの待ち行列
import simpy
import random

def customer(env, name, server):
    arrival = env.now
    with server.request() as req:
        yield req
        wait = env.now - arrival
        print(f'{name} waited {wait:.2f}, served at {env.now}')
        yield env.timeout(random.uniform(2, 4))

def customer_generator(env, server):
    i = 0
    while True:
        yield env.timeout(random.uniform(1, 3))
        i += 1
        env.process(customer(env, f'Customer {i}', server))

env = simpy.Environment()
server = simpy.Resource(env, capacity=2)
env.process(customer_generator(env, server))
env.run(until=20)
パターン 2: プロデューサー・コンシューマー
import simpy

def producer(env, store):
    item_id = 0
    while True:
        yield env.timeout(2)
        item = f'Item {item_id}'
        yield store.put(item)
        print(f'Produced {item} at {env.now}')
        item_id += 1

def consumer(env, store):
    while True:
        item = yield store.get()
        print(f'Consumed {item} at {env.now}')
        yield env.timeout(3)

env = simpy.Environment()
store = simpy.Store(env, capacity=10)
env.process(producer(env, store))
env.process(consumer(env, store))
env.run(until=20)
パターン 3: 並列タスクの実行
import simpy

def task(env, name, duration):
    print(f'{name} starting at {env.now}')
    yield env.timeout(duration)
    print(f'{name} done at {env.now}')
    return f'{name} result'

def coordinator(env):
    # Start tasks in parallel
    task1 = env.process(task(env, 'Task 1', 5))
    task2 = env.process(task(env, 'Task 2', 3))
    task3 = env.process(task(env, 'Task 3', 4))

    # Wait for all to complete
    results = yield task1 & task2 & task3
    print(f'All done at {env.now}')

env = simpy.Environment()
env.process(coordinator(env))
env.run()

ワークフローガイド

ステップ 1: システムを定義する

次の項目を特定します:

  • エンティティ: システム内を移動するものは何か?(顧客、部品、パケット)
  • リソース: 制約となるものは何か?(サーバー、機械、帯域幅)
  • プロセス: どのような活動があるか?(到着、サービス、退去)
  • メトリクス: 何を測定するか?(待ち時間、稼働率、スループット)
ステップ 2: プロセス関数を実装する

プロセスの種類ごとにジェネレーター関数を作成します:

def entity_process(env, name, resources, parameters):
    # Arrival logic
    arrival_time = env.now

    # Request resources
    with resource.request() as req:
        yield req

        # Service logic
        service_time = calculate_service_time(parameters)
        yield env.timeout(service_time)

    # Departure logic
    collect_statistics(env.now - arrival_time)
ステップ 3: モニタリングを設定する

モニタリングユーティリティを使用してデータを収集します。包括的な手法については references/monitoring.md を参照してください。

from scripts.resource_monitor import ResourceMonitor

# Create and monitor resource
resource = simpy.Resource(env, capacity=2)
monitor = ResourceMonitor(env, resource, "Server")

# After simulation
monitor.report()
ステップ 4: 実行して分析する
# Run simulation
env.run(until=simulation_time)

# Generate reports
monitor.report()
stats.report()

# Export data for further analysis
monitor.export_csv('results.csv')

高度な機能

プロセス間の相互作用

プロセスは、イベント、プロセスの yield、割り込みを通じて相互作用できます。詳細なパターンについては references/process-interaction.md を参照してください。

主要なメカニズム:

  • イベントシグナリング: 調整のための共有イベント
  • プロセスの yield: 他のプロセスの完了を待機
  • 割り込み: プリエンプションのためにプロセスを強制的に再開
リアルタイムシミュレーション

ハードウェアインザループや対話型アプリケーションのために、シミュレーションを実時間(ウォールクロックタイム)と同期させます。references/real-time.md を参照してください。

import simpy.rt

env = simpy.rt.RealtimeEnvironment(factor=1.0)  # 1:1 time mapping
# factor=0.5 means 1 sim unit = 0.5 seconds (2x faster)
包括的なモニタリング

プロセス、リソース、イベントを監視します。以下の手法を含む詳細については references/monitoring.md を参照してください:

  • 状態変数の追跡
  • リソースのモンキーパッチ
  • イベントトレース
  • 統計収集

スクリプトとテンプレート

basic_simulation_template.py

以下の機能を備えた、待ち行列シミュレーションを構築するための完全なテンプレートです:

  • 設定可能なパラメーター
  • 統計収集
  • 顧客生成
  • リソース使用
  • レポート生成

使用方法:

from scripts.basic_simulation_template import SimulationConfig, run_simulation

config = SimulationConfig()
config.num_resources = 2
config.sim_time = 100
stats = run_simulation(config)
stats.report()
resource_monitor.py

再利用可能なモニタリングユーティリティです:

  • ResourceMonitor - 単一のリソースを追跡
  • MultiResourceMonitor - 複数のリソースを監視
  • ContainerMonitor - コンテナーの量を追跡
  • 統計の自動計算
  • CSV エクスポート機能

使用方法:

from scripts.resource_monitor import ResourceMonitor

monitor = ResourceMonitor(env, resource, "My Resource")
# ... run simulation ...
monitor.report()
monitor.export_csv('data.csv')

リファレンスドキュメント

特定のトピックに関する詳細なガイドです:

  • references/resources.md - すべてのリソースタイプと例
  • references/events.md - イベントシステムとパターン
  • references/process-interaction.md - プロセスの同期
  • references/monitoring.md - データ収集の手法
  • references/real-time.md - リアルタイムシミュレーションのセットアップ

ベストプラクティス

  1. ジェネレーター関数: プロセス関数では必ず yield を使用する
  2. リソースのコンテキストマネージャー: 自動的なクリーンアップのために with resource.request() as req: を使用する
  3. 再現性: 一貫した結果を得るために random.seed() を設定する
  4. モニタリング: シミュレーションの終了時だけでなく、全体を通してデータを収集する
  5. 検証: 単純なケースを解析解と比較する
  6. ドキュメント: プロセスのロジックとパラメーターの選択にコメントを付ける
  7. モジュール設計: プロセスのロジック、統計、設定を分離する

よくある落とし穴

  1. yield の忘れ: プロセスは一時停止するためにイベントを yield する必要がある
  2. イベントの再利用: イベントは一度しかトリガーできない
  3. リソースリーク: コンテキストマネージャーを使用するか、確実に解放する
  4. ブロッキング操作: プロセス内で Python のブロッキング呼び出しを避ける
  5. 時間単位: 時間単位の解釈を一貫させる
  6. デッドロック: 少なくとも1つのプロセスが進行できることを保証する

利用例

  • 製造: 機械のスケジューリング、生産ライン、在庫管理
  • 医療: 救急室のシミュレーション、患者の流れ、スタッフの割り当て
  • 通信: ネットワークトラフィック、パケットルーティング、帯域割り当て
  • 交通: 交通の流れ、ロジスティクス、車両ルーティング
  • サービス業務: コールセンター、小売のレジ、予約スケジューリング
  • コンピューターシステム: CPU スケジューリング、メモリ管理、I/O 操作

コメント