如何用Salabim/Python实现存储单元满容时的可视化队列
Salabim存储单元与队列管理实现方案
需求概述
- 管理名为"Yellow"的存储单元,容量上限为5
- 物品沿路径进入存储单元,进入后停留5秒从系统移除
- 存储单元满时,后续物品在外部排队,有空间后按顺序进入
- 实现可视化队列,清晰展示排队顺序
- 队列随物品进入存储自动动态调整
核心实现思路
- 使用Salabim内置的
sim.Queue组件管理排队物品,结合sim.Store的容量限制自动触发排队逻辑 - 扩展
Item类的process方法,实现"路径移动→排队等待→进入存储→停留移除"的完整生命周期 - 通过动态计算物品坐标,实现排队物品的有序可视化排列
- 利用Salabim的组件生命周期机制,在物品离开存储时自动唤醒队列中的下一个物品
完整示例代码
import salabim as sim class Route(sim.Component): def setup(self, x1, y1, x2, y2): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 self.line = sim.AnimateLine( spec=(x1, y1, x2, y2), linewidth=30, linecolor='white' ) class ConnectionPoint(sim.Component): def setup(self, x, y, color, layer): self.x = x self.y = y sim.AnimateRectangle( spec=(-15, -15, 15, 15), x=x, y=y, fillcolor=color, layer=layer ) class Item(sim.Component): nr = 0 def setup(self, routes, queue, store): self.routes = routes self.queue = queue self.store = store self.current_route_index = 0 self.x, self.y = routes[0].x1, routes[0].y1 self.anim = sim.AnimateRectangle( spec=lambda: (self.x - 12, self.y - 12, self.x + 12, self.y + 12), fillcolor="green" ) Item.nr += 1 self.id = Item.nr # 记录队列中的位置,用于可视化排列 self.queue_pos = 0 def update_queue_position(self): # 计算排队位置:存储单元右侧,垂直排列 queue_base_x = self.store.x + 40 queue_base_y = self.store.y # 每个物品间隔30像素 self.x = queue_base_x self.y = queue_base_y - self.queue_pos * 30 def process(self): # 第一步:沿路径移动到存储单元入口 route = self.routes[0] step = (route.x2 - route.x1) / abs(route.x2 - route.x1) * 2 while self.x != route.x2: self.hold(0.1) self.x += step # 第二步:进入队列等待(自动触发排队,当store满时) self.enter(self.queue) # 更新队列位置 self.queue_pos = self.queue.index(self) self.update_queue_position() # 等待队列调整:当队列中前面的物品离开时,更新自身位置 while self in self.queue: self.hold(0.1) new_pos = self.queue.index(self) if new_pos != self.queue_pos: self.queue_pos = new_pos self.update_queue_position() # 第三步:进入存储单元 self.enter(self.store) # 移动到存储单元内部位置(示例:存储单元中心) self.x = self.store.x self.y = self.store.y # 第四步:在存储单元停留5秒 self.hold(5) # 第五步:离开存储单元并销毁 self.leave(self.store) self.anim.delete() self.destroy() env = sim.Environment() env.background_color('20%gray') # 定义存储单元(容量设为5),添加可视化标识 yellow_store = sim.Store("yellow", capacity=5) yellow_store.x = 800 yellow_store.y = 700 sim.AnimateRectangle( spec=(-50, -50, 50, 50), x=yellow_store.x, y=yellow_store.y, fillcolor='yellow', layer=0, text="Yellow\nStore" ) # 定义队列,用于存储等待的物品 yellow_queue = sim.Queue("yellow_queue") # Define list of routes routes = [ Route(x1=0, y1=700, x2=800, y2=700), # 物品移动路径 ] connection_points = [ ConnectionPoint(x=800, y=700, color='yellow', layer=0), ] # 生成20个物品,间隔2秒 items = sim.ComponentGenerator(Item, routes=routes, queue=yellow_queue, store=yellow_store, iat=2, number=20) env.animate(True) env.run(till=200) yellow_store.print_info() yellow_queue.print_info()
代码关键说明
- 存储与队列联动:
sim.Store设置capacity=5后,当存储满时,物品调用enter(store)会自动阻塞,此时先让物品进入sim.Queue,通过队列索引动态计算位置实现可视化排队 - 队列可视化:通过
update_queue_position方法,根据物品在队列中的索引计算坐标,让排队物品在存储单元右侧垂直排列,间隔30像素,保证顺序清晰 - 动态队列调整:在等待循环中实时检查物品在队列中的位置,当前面的物品进入存储后,自动更新自身位置,实现队列的动态收缩
- 物品生命周期:完整实现了物品从生成→路径移动→排队→进入存储→停留→销毁的全流程,利用Salabim的
hold和组件生命周期方法实现时间控制
内容的提问来源于stack exchange,提问作者Silberspecht
相关产品推荐
相关产品推荐

