SimPy集装箱码头仿真:如何实现单吊机单次卸箱与顺序运输?
集装箱码头SimPy仿真系统修正方案
需求说明
- 每台吊机同一时间仅能卸载一个集装箱;
- 只要有空卡车可用,吊机应独立于前期卡车运输完成状态继续卸箱;
- 无空卡车时,吊机需等待至有卡车可用才可启动卸箱。
现有问题
当前代码逻辑存在以下问题:
- 吊机先完成卸箱才请求卡车,导致卸箱与运输串行,无法最大化利用吊机资源,未完全满足需求2;
- 若卡车资源不足,卸完的集装箱会堆积,且吊机仍会继续卸箱,违反需求3;
- 一次性启动所有卸箱进程,会出现多台吊机同时作业的情况(若期望单吊机作业,需同步调整资源容量,核心问题是卡车与吊机的同步逻辑)。
代码修正
核心思路
调整吊机卸箱的触发逻辑:启动卸箱前先确保有可用卡车,保证卸完箱子后卡车可立即运输,同时满足吊机独立作业(有卡车就继续卸)和无卡车则等待的要求。
修改后的vessel.py代码:
import random import simpy from config import NUM_CONTAINERS, AVERAGE_INTERARRIVAL_TIME, CRANE_LIFT_TIME, TRUCK_CYCLE_TIME class Vessel: def __init__(self, env, id, berth_resource, crane_resource, truck_resource): self.env = env self.id = id self.containers = NUM_CONTAINERS self.berth_resource = berth_resource self.crane_resource = crane_resource self.truck_resource = truck_resource def berth(self): """模拟船舶靠泊""" with self.berth_resource.request() as request: yield request print(f"Time {self.env.now:.1f}: Vessel {self.id} starts berthing.") print(f"Time {self.env.now:.1f}: Vessel {self.id} finished berthing.") yield self.env.process(self.unload()) def unload_container(self, container_id): """单个集装箱卸箱流程:先申请卡车,再用吊机卸箱""" # 先请求卡车,无空闲则等待(满足需求3) print(f"Time {self.env.now:.1f}: Vessel {self.id} requests truck for container {container_id + 1}.") with self.truck_resource.request() as truck_request: yield truck_request # 卡车到位后,请求吊机卸箱 print(f"Time {self.env.now:.1f}: Vessel {self.id} requests crane for container {container_id + 1}.") with self.crane_resource.request() as crane_request: yield crane_request print(f"Time {self.env.now:.1f}: Quay crane starts unloading container {container_id + 1} from vessel {self.id}.") yield self.env.timeout(CRANE_LIFT_TIME) print(f"Time {self.env.now:.1f}: Quay crane finished unloading container {container_id + 1} from vessel {self.id}.") # 启动卡车运输,同时释放吊机处理下一个箱子 self.env.process(self.transport_container(container_id, truck_request)) def transport_container(self, container_id, truck_request): """模拟集装箱卡车运输""" print(f"Time {self.env.now:.1f}: Truck starts transporting container {container_id + 1} from vessel {self.id}.") yield self.env.timeout(TRUCK_CYCLE_TIME) print(f"Time {self.env.now:.1f}: Truck finished transporting container {container_id + 1} from vessel {self.id}.") # 运输完成后释放卡车资源 truck_request.release() def unload(self): """船舶卸箱全流程:逐个启动卸箱进程""" for i in range(self.containers): yield self.env.process(self.unload_container(i)) print(f"Time {self.env.now:.1f}: Vessel {self.id} has been fully unloaded and leaves the berth.") def process(self): """船舶全流程:到港→靠泊→卸箱""" yield self.env.process(self.berth())
关键修改点
- 卡车请求前置:在请求吊机前先申请卡车,确保无空闲卡车时吊机不会启动卸箱;
- 逐个启动卸箱进程:避免一次性创建所有卸箱请求导致的资源竞争,让吊机按顺序处理集装箱;
- 卡车资源手动释放:运输完成后释放卡车,确保资源正确回收复用;
- 时间格式化:输出时间保留一位小数,日志更清晰易读。
验证效果
调整后仿真流程将完全符合需求:
- 单台吊机同一时间仅处理一个集装箱(满足需求1);
- 只要有空闲卡车,吊机完成当前卸箱后立即启动下一个(满足需求2);
- 无空闲卡车时,吊机等待直到卡车返回(满足需求3)。
示例输出(单吊机、单卡车场景):
Enter the number of hours to run the simulation: 3 Time 104.4: Vessel 1 arrives. Time 104.4: Number of vessels waiting for berths: 0 Time 104.4: Number of vessels currently being served at berths: 0 Time 104.4: Number of cranes currently being used: 0 Time 104.4: Number of trucks currently being used: 0 Time 104.4: Vessel 1 starts berthing. Time 104.4: Vessel 1 finished berthing. Time 104.4: Vessel 1 requests truck for container 1. Time 104.4: Vessel 1 requests crane for container 1. Time 104.4: Quay crane starts unloading container 1 from vessel 1. Time 107.4: Quay crane finished unloading container 1 from vessel 1. Time 107.4: Truck starts transporting container 1 from vessel 1. Time 107.4: Vessel 1 requests truck for container 2. Time 113.4: Truck finished transporting container 1 from vessel 1. Time 113.4: Vessel 1 requests crane for container 2. Time 113.4: Quay crane starts unloading container 2 from vessel 1. Time 116.4: Quay crane finished unloading container 2 from vessel 1. Time 116.4: Truck starts transporting container 2 from vessel 1. ...
内容的提问来源于stack exchange,提问作者Soumya Patel
相关产品推荐
相关产品推荐

