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()