SimPy停车场仿真结果可视化

我最近分享了一个在 Python 中使用 SimPy 的 Python 仿真建模示例。使用 SimPy(Python 中提供的离散事件模拟库),我对一个停车场进行了建模,该停车场具有已定义的停车位数量和已定义的汽车到达过程。在有关 SimPy仿真模型可视化的后续教程中,我展示了如何使用相同的基线示例来收集和可视化停车场位利用率的数据。在接下来的文章中,我将进一步展示如何使用 Python 和 SimPy 对停车场本身进行动画处理。

为什么 SimPy 与运营和物流经理相关

SimPy 是 Python 的开源离散事件模拟库,为供应链管理者提供了一个有价值的工具。这不是关于孤立的功能,而是关于 SimPy 如何帮助这些专业人员解决供应链管理的复杂性。

SimPy 的突出优势之一是它能够创建现实的供应链运营模型。这些模型与供应链中的实际流程非常相似,使管理人员更容易分析和了解其运营情况。在现实操作极其复杂的领域中,拥有准确反映这些复杂性的模拟工具是必不可少的。

SimPy 更具吸引力的是它的灵活性。它是一个通用模拟库,这意味着供应链经理可以对其进行调整以对其运营的各个方面进行建模。无论是库存管理、订单处理、需求预测、运输还是供应链的任何其他关键要素,SimPy 都可以进行定制以应对特定的挑战。

SimPy 的优势还在于它能够促进“假设”分析。供应链经理可以使用 SimPy 测试不同的场景和策略。他们可以探索运营变化的影响,帮助他们就优化供应链流程做出明智的决策。这种对不同场景进行建模并预测结果的能力对于战略规划来说是非常宝贵的。

在效率至关重要的世界中,SimPy 有助于性能优化。供应链经理可以模拟他们的流程,识别瓶颈和低效率,并制定策略以提高整体绩效。这种优化可以降低成本并改善客户服务。

供应链弹性至关重要,SimPy 是风险管理的宝贵工具。通过对各种风险场景进行建模,管理人员可以评估其供应链中的漏洞并制定应急计划以减轻潜在的干扰。这在当今全球化且常常不可预测的供应链格局中至关重要。

资源分配是 SimPy 证明其价值的另一个领域。它可以模拟不同场景下劳动力、机器、存储空间等资源的分配情况。这种洞察力有助于管理者就资源规划做出明智的决策,确保资源得到有效利用。

降低成本是使用 SimPy 的一个显着好处。通过识别效率低下的地方并优化流程,管理人员可以潜在地降低与库存、运输和其他运营方面相关的成本。这种成本降低直接影响公司的利润。

用于 SimPy 停车场模型可视化的模型添加

在我之前的 SimPy停车场模型示例中,我已经编写了停车场基线模型的代码。您可以在这里找到编码示例:SimPy停车场模拟建模示例

在基线模型中没有可视化。停车场的汽车到达和离开只需打印到控制台即可。现在我们将实现 SimPy 模拟结果的可视化。

为了能够可视化模拟结果,我们必须收集相关的模拟数据,并且必须在整个模拟过程中监控相关值。运行模拟后,收集的数据将使用matplotlib .pyplot 进行可视化。

有多种方法可以监控 SimPy仿真模型中的值,但开始监控已占用和可用停车位数量的最简单方法(对于 SimPy 初学者)是实现自定义 SimPy 监控流程:

def monitor_parkingspot(self) -> None:

 
        while self.env.now <= self.simdata.duration:

            self.simdata.data_timeseries[self.env.now, 0] = self.env.now
            self.simdata.data_timeseries[self.env.now, 1] = self.spots_occupied
            self.simdata.data_timeseries[self.env.now, 2] = self.spots_available

            yield self.env.timeout(1)

我向 ParkingLot 类添加了一个方法来实现自定义监控流程。此过程检查模拟时间、可用点的数量和可用点的数量,并将这些值写入numpy ndarray。从上面的示例中可以看到,ParkingLot 类有一些额外的属性和变量:.data_timeseries (: numpy .ndarray)、.spots_ocpied (: int) 和 .spots_available (: int)。这是类的标头和构造函数现在的样子:

class ParkingLot:

    env             :simpy.Environment
    capacity        :int
    spots           :simpy.resources.container.Container
    spots_occupied  :int
    spots_available :int
    simdata         :Simdata

    def __init__(self, 
        env      :simpy.Environment, 
        capacity :int,
        duration :int
        ):
        
        """ constructor """
        
        self.env = env
        self.capacity = capacity
        self.spots = simpy.resources.container.Container(env, capacity, init=capacity)
        self.spots_occupied = 0
        self.spots_available = capacity
        self.simdata = Simdata(duration= duration)
        self.simdata.data_timeseries = np.zeros([duration+1, 3], dtype = int)

对于 .simdata 属性,我编写了一个小类 Simdata。在以后的教程中我将在这个类中编写更多的方法和属性,所以我想在此时介绍它。

class Simdata:

    duration         :int
    data_timeseries  :np.ndarray

    def __init__(self, 
        duration :int,
        ):
    
        """ constructor """

        self.duration = duration
        self.data_timeseries = np.zeros(duration+1, dtype = float)

已占用和可用停车位的数量(现在是 ParkingLot 类的变量)在汽车到达过程中不断更新:

def car_arrival(self,
        car_id          :int, 
        dwelltime_min   :float,
        dwelltime_max   :float
        )               -> None:
        """ 
    
        implement simpy process; 
        models car arrivals in the parking lot, occupying a slot for a randomly distributed duration
    
        """
    
        #print(f"Car {car_id} arrives at {self.env.now}")
    
        yield self.spots.get(1)

        self.spots_occupied += 1
        self.spots_available -= 1
        
        #print(f"Car {car_id} parks at {self.env.now}")
        
        yield self.env.timeout(random.uniform(dwelltime_min, dwelltime_max))
        
        #print(f"Car {car_id} leaves at {self.env.now}")
        
        self.spots_occupied -= 1
        self.spots_available += 1

        yield self.spots.put(1)

这有利于模拟期间的结果收集。我现在可以在模拟运行完成后绘制结果。

使用 SimPy 生成的结果可视化已占用和可用的插槽

最后一步很简单:我使用matplotlib .pyplot 创建一个线段,显示整个模拟时间内停车场上已占用和可用停车位的数量。

env.process(parking_lot.monitor_parkingspot())

# run the model
env.run()

# plot simulation results
plt.plot(parking_lot.simdata.data_timeseries[:,1], linestyle = 'dotted', color = "red", label = "occupied")
plt.plot(parking_lot.simdata.data_timeseries[:,2], linestyle = 'dotted', color = "green", label = "available")
plt.legend()
plt.xlabel("sim time")
plt.ylabel("# of spots")
plt.title("parking lot utilization over time")
plt.show()

您可以看到,在执行之前设置仿真模型时,我添加了另一个 SimPy 流程。这就是监控过程。它收集每个模拟增量的模拟结果,并将这些值存储在numpy ndarray中。

结果如下。

在这种情况下,停车场未得到充分利用。对于这种特定的汽车到达场景来说,2 个停车位就足够了。

结束语及相关内容

在本教程中,我展示了如何在整个仿真过程中监控相关的 SimPy 模型值,以及如何使用 Python 中的matplotlib .pyplot实现 SimPy 仿真结果的可视化。

以下是您可能也感兴趣的一些相关文章:

You May Also Like

Leave a Reply

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据