simpyを使ってみる 2


引き続きsimpy の勉強をしている.

今回は図書館の貸出・返却プロセスをシミュレーションし、時間とともに貸出中の資料数をみてみる.

コードは下記.

import simpy
import random
import matplotlib.pyplot as plt

# シミュレーションパラメータ
NUM_BOOKS = 50           # 資料の総数
NUM_USERS = 30           # 利用者数
ARRIVAL_INTERVAL = 10    # 利用者の到着間隔(分)
BORROW_DURATION = 60     # 貸出期間(分)
SIM_TIME = 1440          # シミュレーション時間(分)= 1日

# データ収集用
borrowed_books = []
time_points = []

def user(env, name, library, stats):
    """図書館利用者の行動を定義するプロセス"""
    while True:
        # 図書館に到着
        arrival_time = env.now
        # print(f"{arrival_time}: {name} が図書館に到着しました。")
        
        with library.request() as request:
            yield request
            borrow_time = env.now
            # print(f"{borrow_time}: {name} が資料を借りました。")
            stats['borrowed'] += 1
            borrowed_books.append((borrow_time, stats['borrowed']))
            
            # 資料の貸出期間
            yield env.timeout(BORROW_DURATION)
            return_time = env.now
            # print(f"{return_time}: {name} が資料を返却しました。")
            stats['borrowed'] -= 1
            borrowed_books.append((return_time, stats['borrowed']))
        
        # 次の訪問までの待機時間
        wait_time = random.expovariate(1.0 / ARRIVAL_INTERVAL)
        yield env.timeout(wait_time)

def setup_library(env, library, stats):
    """図書館のリソースと利用者の生成を設定"""
    for i in range(NUM_USERS):
        env.process(user(env, f"User {i+1}", library, stats))
        yield env.timeout(random.expovariate(NUM_USERS / SIM_TIME))

# シミュレーション環境の設定
env = simpy.Environment()
library = simpy.Resource(env, capacity=NUM_BOOKS)
stats = {'borrowed': 0}

env.process(setup_library(env, library, stats))
env.run(until=SIM_TIME)

# データの整形
borrowed_books.sort()
times, counts = zip(*borrowed_books)

# 可視化
plt.figure(figsize=(10, 6))
plt.step(times, counts, where='post')
plt.xlabel('Time (minutes)')
plt.ylabel('Number of Borrowed Books')
plt.title('Number of Borrowed Books Over Time')
plt.grid(True)
plt.show()

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です