
SimPy (đọc như "Blimpie") là package Python cho discrete-event simulation hướng process (quy trình).
Cài đặt
Cách dễ nhất qua pip:
pip install simpy
Phiên bản mới nhất lúc viết: simpy-3.0.11. Dùng cho tất cả ví dụ dưới.
Nếu đã cài, dùng --U để upgrade:
pip install --U simpy
Lưu ý: Cần Python 2.7 trở lên. Linux/Unix/MacOS có thể cần root privileges.
Kiểm tra cài đặt thành công: mở Python shell và import simpy.
Khái niệm cơ bản
SimPy là thư viện discrete-event simulation. Các thành phần active (messages, vehicles, customers) được mô hình hóa bằng processes. Trong SimPy, active entities gọi là processes. Process là Python generator yield discrete events. Lưu ý: không return mà yield - đó là khác biệt giữa function thường và generator. Cho phép tạo event và yield để chờ trigger.
Khi process yield event, process bị suspended (treo). SimPy resume process khi event triggered. Nếu nhiều process chờ cùng event, SimPy resume theo thứ tự yield event đó.
def gen(x):
y = yield x + 1
return y
>>> g = gen(1)
>>> next(g)
2
>>> next(g)
Traceback (most recent call last):
File "", line 1, in
next(g)
StopIteration
Iteration dừng sau khi biến x yield lần đầu.
Event kiểu Timeout trigger sau một lượng thời gian (giả lập) trôi qua. Timeout event cho phép process hold/sleep một khoảng thời gian. Tất cả event kể cả Timeout tạo bằng cách gọi method thích hợp của Environment mà process sống trong đó.
Ví dụ: Mô phỏng hội nghị (Conference Attendee)
from random import randint
import simpy
# Config
TALKS_PER_SESSION = 3
TALK_LENGTH = 30
BREAK_LENGTH = 15
ATTENDEES = 1
def attendee(env, name, knowledge=0, hunger=0):
talks = 0
breaks = 0
while True:
# Tham dự talks
for i in range(TALKS_PER_SESSION):
print('Talk {0} begins at {1}'.format(talks + 1, env.now))
knowledge += randint(0, 3) / (1 + hunger)
hunger += randint(1, 4)
talks += 1
yield env.timeout(TALK_LENGTH)
print(f'Talk {talks} ends at {env.now}')
print('Attendee %s finished talks with knowledge %.2f and hunger %.2f' % (name, knowledge, hunger))
# Nghỉ, đi buffet
food = randint(3, 12)
hunger -= min(food, hunger)
yield env.timeout(BREAK_LENGTH)
print('Attendee %s finished eating with hunger %.2f' % (name, hunger))
# Chạy simulation
env = simpy.Environment()
for i in range(ATTENDEES):
env.process(attendee(env, i))
env.run(until=250)
Chạy chương trình cho output mô phỏng hội nghị: random speakers, 3 talks/session, talk length 40 min, break 30 min.
Process attendee cần reference đến Environment (env), name, knowledge, hunger để tạo event mới. Session lặp vô tận cho đến khi False. Hàm attendee() là generator không kết thúc mà trả control flow cho simulation khi gặp yield.
Cuối cùng chạy demo simulation "conference attendee" cho đến giá trị 250 (bao gồm: 3 talks, 1 break, 3 talks, 1 break, 1 talk).