Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Cơ bản Discrete Event Simulation với SimPy trong Python

Cơ bản Discrete Event Simulation với SimPy trong Python

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