首页 文章

可视化网格/仓库布局上的离散事件模拟

提问于
浏览
1

我需要模拟一个仓库,其中有几个自动驾驶车辆在给定布局上移动,具有简单的优先级规则 . 根据我的理解,可以使用离散事件模拟(DES)轻松解决问题,我会使用SimPy .

我看到的问题是,我很难想象出这些车辆的实际轨迹和相互作用 . 当然,我可以记录所有时期所有车辆的所有位置,但我如何继续创建可视化?

最愚蠢的方式是制作一百万张图片,但必须有更好的方法 . 是否有任何库或工具可通过在背景之前移动符号来可视化网格上对象的移动?

另一个选择是使用基于代理的方法和AnyLogic这样的软件,但这对我来说似乎更复杂,我想应用DES方法,最好是使用开源软件 .

4 回答

  • 0

    我建议检查一下tkinter库 . 我们使用它来完成所有简单的可视化 .

    这是一个可以实现的动画类型的一个非常基本的例子,原谅戏剧性的镜头:https://www.youtube.com/watch?v=xnZQ0f--Ink

    以下是源代码,大致描述了您在上面看到的内容:https://github.com/harrymunro/Simulations/blob/master/termini_simulation_animation.py

    这是动画组件的复制粘贴:

    ################ SET UP ANIMATION CANVAS #################
    class Train:
        def __init__(self, canvas, x1, y1, x2, y2, tag):
            self.x1 = x1
            self.y1 = y1
            self.x2 = x2
            self.y2 = y2
            self.canvas = canvas
            self.train = canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill="red", tags = tag)
            self.train_number = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = tag)
            self.canvas.update()
    
        def move_train(self, deltax, deltay):
            self.canvas.move(self.train, deltax, deltay)
            self.canvas.move(self.train_number, deltax, deltay)
            self.canvas.update()
    
        def remove_train(self):
            self.canvas.delete(self.train)
            self.canvas.delete(self.train_number)
            self.canvas.update()
    
    class Clock:
        def __init__(self, canvas, x1, y1, x2, y2, tag):
            self.x1 = x1
            self.y1 = y1
            self.x2 = x2
            self.y2 = y2
            self.canvas = canvas
            self.train = canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill="#fff")
            self.time = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = "Time = "+str(tag)+"s")
            self.canvas.update()
    
        def tick(self, tag):
            self.canvas.delete(self.time)
            self.time = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = "Time = "+str(tag)+"s")
            self.canvas.update()
    
    
    if show_animation == True:
        animation = Tk()
        #bitmap = BitmapImage(file="uxbridge.bmp")
    
        im = PhotoImage(file="uxbridge_resized.gif")
    
        canvas = Canvas(animation, width = 800, height = 400)
        canvas.create_image(0,0, anchor=NW, image=im)
        animation.title("Uxbridge Termini Simulation")
    
        canvas.pack()
    
    #### matplotlib plots
    
    
    if show_animation == True and hide_plots == False:
        f = plt.Figure(figsize=(5,4), dpi=100)
    
        a1 = f.add_subplot(221) # mean headway
        a2 = f.add_subplot(222) # TPH meter
        a3 = f.add_subplot(223) # headway distribution
        a4 = f.add_subplot(224) # train count
    
        a1.plot()
        a2.plot()
        a3.plot()
        a4.plot()
    
        from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
    
        dataPlot = FigureCanvasTkAgg(f, master=animation)
        dataPlot.show()
        dataPlot.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        f.tight_layout()
    
        canvas.pack()
    
    # platforms
    if show_animation == True:
        canvas.create_rectangle(50, 100, 200, 150, fill = "yellow")
        canvas.create_rectangle(50, 200, 200, 250, fill = "yellow")
    
        canvas.create_line(50, 75, 200, 75, fill="green", width=3) # platform 4
        canvas.create_line(50, 175, 200, 175, fill="green", width=3) # platform 2/3
        canvas.create_line(50, 275, 200, 275, fill="green", width=3) # platform 1
    
        canvas.create_text(125, 110, text = "Platform 4")
        canvas.create_text(125, 140, text = "Platform 3")
        canvas.create_text(125, 210, text = "Platform 2")
        canvas.create_text(125, 240, text = "Platform 1")
    
    # track
        canvas.create_line(200, 75, 650, 75, fill="green", width=3) # platform 4 run out
        canvas.create_line(200, 175, 650, 175, fill="green", width=3) # platform 2/3 run in
        canvas.create_line(300, 175, 400, 75, fill="green", width=3)
        canvas.create_line(450, 75, 600, 175, fill="green", width=3)
        canvas.create_line(450, 175, 600, 75, fill="green", width=3)
        canvas.create_line(200, 275, 300, 275, fill="green", width=3)
        canvas.create_line(300, 275, 400, 175, fill="green", width=3)
    
    ############ END OF CANVAS #################
    
  • 0

    如果动画应为2D,则可以使用Pygame库 . 我用它制作了一个简单的模拟动画,效果很好 . 请注意,您需要使用线程,否则您的窗口会在几秒钟后冻结 . 这种简单的方法为每个到达的客户绘制一个红色圆圈,并在客户获得服务时将其绘制为绿色 .

    def draw(env, timelist):
        gameDisplay.fill(white)
        start = time.clock()
        kdnr = 0
        kdaktuell = -1
        kdstart = -10
        while True:
            timer = (time.clock() - startzeit)
            if timer > 15: #simulation for 15 sec
                    break
    
        # incoming customers
        if kdnr < len(timelist):
            if timelist[kdnr] <= timer:
                pygame.draw.circle(gameDisplay,red,(50+30*kdnr,400),10)
                print('Customer '+str(kdnr+1)+ ' arrived in minute: ' + str(timelist[kdnr]))
                kdnr = kdnr + 1
    
        # served customers
        if (kdstart+3) <= timer:
            kdaktuell = kdaktuell + 1
            kdstart = time
            pygame.draw.circle(gameDisplay,green,(50+30*kdaktuell,400),10)
            print('Customer '+str(kdaktuell+1)+ ' gets served.')
    
        pygame.display.update()
    
  • 2

    我只是收集所有必需的数据并将它们存储在某处(文件,HDF5,sql,...) . 稍后(或并行),您可以可视化该数据 . 通过使用例如matplotlib生成大量图像或使用D3.js做更多花哨的事情 .

  • 1

    我发现R库gganimate做了我想要的 . 我没有找到Python的等价物(也许是因为在Python中既没有ggplot2也没有animate ...)

相关问题