如何使用Python的Simpy库搭建最简单的共享单车租赁业务模拟程序
Simpy学习方法与共享单车场景模拟方案
一、Simpy示例阅读与学习技巧
Simpy是典型的事件驱动模拟框架,核心逻辑围绕进程挂载和事件调度两个点展开,读示例代码不用从下往上追溯,按以下顺序走效率更高:
- 先找程序入口
if __name__ == "__main__"块,优先定位三个核心要素:- 模拟环境初始化:
env = simpy.Environment() - 初始进程挂载:所有一开始就要运行的逻辑都会通过
env.process()挂载到环境上 - 模拟启动条件:
env.run(until=xxx)决定了模拟的停止规则
- 模拟环境初始化:
- 再顺着初始进程的定义顺读代码,遇到
yield关键字重点关注:yield是进程挂起的信号,后面跟的env.timeout(xxx)是等待指定时长,跟其他进程/事件是等待对应事件完成后再唤醒当前进程继续执行。
学习资源优先啃官方自带的示例库,从银行排队、资源抢占这类基础示例开始,跑通后修改参数观察输出变化,很快就能掌握运行逻辑。
二、共享单车租赁场景实现思路
你描述的共享单车站点流转场景是典型的离散事件模拟场景,用Simpy实现不需要手动管理事件队列和并行流程,按以下步骤抽象即可:
- 基础数据抽象:用长度为S的列表
station_bikes存储各站点当前可用车辆数,初始状态下按你的分配规则把T辆自行车填入列表。 - 进程拆分:
- 站点用户生成进程:每个站点独立运行一个进程,按指数分布的间隔生成用户请求,每次生成用户就触发借车逻辑。
- 用户生命周期进程:单个用户从借车到还车的全流程,逻辑如下:
- 检查起始站点可用车辆数,无车则直接结束(或按需求加排队逻辑)
- 扣减起始站点1辆可用车,按指数分布生成租赁时长,用
yield env.timeout(租赁时长)模拟骑行过程 - 骑行结束后按转移概率矩阵随机选择还车站点,给目标站点增加1辆可用车
- 核心代码参考:
import simpy import numpy as np # 模拟配置 SITE_COUNT = 2 TOTAL_BIKES = 20 # 转移矩阵:transfer_prob[出发站点][到达站点] = 对应概率 transfer_prob = [[0.9, 0.1], [0.5, 0.5]] # 指数分布参数:用户平均每0.5单位时间到达1人,租赁平均时长2单位时间 arrival_lambda = 2 rent_lambda = 0.5 SIM_DURATION = 100 def user_lifecycle(env, start_site, site_bikes, transfer_prob, rent_lambda): # 借车逻辑 if site_bikes[start_site] <= 0: return site_bikes[start_site] -= 1 # 模拟骑行时长 rent_time = np.random.exponential(1/rent_lambda) yield env.timeout(rent_time) # 还车逻辑 end_site = np.random.choice(range(SITE_COUNT), p=transfer_prob[start_site]) site_bikes[end_site] += 1 def arrival_generator(env, site_id, site_bikes, arrival_lambda, transfer_prob, rent_lambda): while True: # 生成用户到达间隔 inter_arrival = np.random.exponential(1/arrival_lambda) yield env.timeout(inter_arrival) # 启动对应用户的生命周期进程 env.process(user_lifecycle(env, site_id, site_bikes, transfer_prob, rent_lambda)) # 模拟初始化 env = simpy.Environment() # 初始车辆平均分配到各站点 site_bikes = [TOTAL_BIKES // SITE_COUNT for _ in range(SITE_COUNT)] # 启动所有站点的用户生成进程 for site in range(SITE_COUNT): env.process(arrival_generator(env, site, site_bikes, arrival_lambda, transfer_prob, rent_lambda)) # 运行模拟 env.run(until=SIM_DURATION) print(f"模拟结束各站点可用车辆:{site_bikes}")
上述代码中所有事件的并行调度、执行顺序都由Simpy环境自动处理,不需要你手动管理进行中的租赁流程,只需要按业务逻辑补充数据统计(比如流失用户数、站点空车时长等)即可。
内容的提问来源于stack exchange,提问作者doingmybest99
相关产品推荐
相关产品推荐

