Визуализация моделирования дискретных событий на сетке / складах

Мне нужно смоделировать склад с несколькими автономными транспортными средствами, движущимися по заданной схеме, с простыми правилами приоритета. Насколько я понимаю, проблему можно легко решить с помощью моделирования дискретных событий (DES), и я бы использовал SimPy для этого.

Проблема, которую я вижу, заключается в том, что мне кажется очень трудным визуализировать фактические траектории и взаимодействия этих транспортных средств. Конечно, я могу регистрировать все положения всех транспортных средств за все периоды, но как я могу продолжить создание визуализации?

Самый глупый способ - создать миллион картинок, но должен быть способ получше. Есть ли какая-нибудь библиотека или инструмент для визуализации движений объектов на сетке путем перемещения символов перед фоном?

Другой вариант - использовать агентный подход с таким программным обеспечением, как AnyLogic, но мне это кажется более сложным. и я хотел бы применить подход DES, желательно с открытым исходным кодом.


person mondano    schedule 24.04.2017    source источник
comment
Обратите внимание, что запрос рекомендаций по библиотекам или инструментам прямо указан как критерий для закрытия вашего вопроса. При этом все коммерческие продукты DES, такие как Simio, Arena или ExtendSim, предоставляют функции анимации / визуализации. Плохая новость в том, что они дорогие. Возможный лучик надежды состоит в том, что некоторые из них легко доступны для академического использования.   -  person pjs    schedule 24.04.2017
comment
Спасибо за разъяснения. Я не уверен, как и где получить помощь по моему вопросу, если не по SO. Где бы вы спросили или как мне перефразировать свой вопрос?   -  person mondano    schedule 24.04.2017


Ответы (5)


Я бы посоветовал проверить библиотеку 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 #################
person bobo    schedule 24.10.2017

Если анимация должна быть двухмерной, вы можете использовать библиотеку 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()
person AUBSieGUL    schedule 26.10.2017
comment
env не используется в функции draw. - person Oliver Wilken; 15.05.2019

Я просто собирал все необходимые данные и где-то их хранил (файл, HDF5, sql,…). Позже (или параллельно) вы можете визуализировать эти данные. Либо путем создания большого количества изображений, например, с помощью matplotlib, либо путем выполнения чего-то более интересного с помощью D3.js.

person Stefan Scherfke    schedule 24.04.2017
comment
Мой вопрос был в том, как именно я буду выполнять эту часть визуализации. Если у меня есть симуляция для настенных часов 8 часов и я делаю снимок каждую секунду, у меня есть 8 часов * 60 мин / ч * 60 секунд / мин * 1 МБ = 28,8 ГБ для визуализации одного прогона симуляции. Это кажется многовато. Ищу более эффективное решение. Я не нашел соответствующего варианта диаграммы D3.js для этой динамической проблемы. Вы можете указать мне прямо на один? - person mondano; 24.04.2017

Я обнаружил, что библиотека R gganimate делает то, что я хочу. Я не нашел эквивалента для Python (возможно, потому, что нет ни эквивалента для ggplot2, ни анимировать в Python ...)

person mondano    schedule 11.05.2017

Небольшой вариацией того, что вы собираетесь использовать для библиотеки моделирования, может быть использование salabim. вместо простого. Он очень похож на simpy, но имеет движок анимации, который значительно упрощает процесс.

person David    schedule 09.02.2021