Simpy基础系列——基础Resource对象的用法

发布时间:2023年12月25日


案例背景

在用simpy仿真过程中,有些对象具有竞争性和排他性,在实际中往往称为资源,例如原材料(接近)无穷,而产能有限的情况下,生产设备就被视为资源。在仿真环境中,可以把这种容量有限,具有竞争性的资源建模为 R e s o u r c e Resource Resource 对象,当资源被占满时,请求服务的对象只能进行等待,当资源有空缺时,才会对请求服务的对象进行处理。

假设现有一个充电站,充电站内只有两个充电桩,当有电动车来充电时,有空闲的充电桩则可立马充电,若无则需要进行等待,直至有充电桩可用,其中,等待充电的电动车按先到先服务的原则,按序占用空闲出来的充电桩。

示例代码

request & release 的形式

在simpy中,我们将上述例子中的充电站建模为 s i m p y . R e s o u r c e simpy.Resource simpy.Resource 对象,容量设置为2(充电桩2个,可同时为两辆电动车充电),示例中我们假设每2个单位时间来1辆电动车,电动车充电需要5个单位时间,代码如下:

import simpy

class City(object):
    def __init__(self, env, num_bcs, num_car):
        self.env = env
        self.bcs = simpy.Resource(env, capacity=num_bcs)
        for i in range(num_car):
            env.process(self.car(name='%d号车' % i,
                                     driving_time=i * 2,
                                     charge_duration=5))

    def car(self, name, driving_time, charge_duration):
        yield self.env.timeout(driving_time)
        print('%s 到达充电装桩 %d' % (name, self.env.now))

        req = self.bcs.request()
        yield req
        print('%s 开始充电 %s' % (name, self.env.now))
        yield self.env.timeout(charge_duration)
        print('%s 充电完成 %s' % (name, self.env.now))
        self.bcs.release(req)

env = simpy.Environment()
city = City(env, num_car=4, num_bcs=2)
env.run()

上述代码船创建了4辆电动车对象,并为每辆电动车创建一个 Process 事件,分别对应4个事件生成器 car(),生成器的逻辑为:当电动车到达充电站时,会向充电站发出请求 request(),当请求得到回应,说明充电站有空闲充电桩,此时该电动车占用一个充电桩,仿真时间向前推进充电时长,充电结束后将请求释放,此时电动车离开充电桩,原本占用的充电桩被释放,等待下一个电动车来占用。

with 的形式

另一种更加紧凑的方式,就是用 with 来替代,这种形式更加常用

import simpy

class City(object):
    def __init__(self, env, num_bcs, num_car):
        self.env = env
        self.bcs = simpy.Resource(env, capacity=num_bcs)
        for i in range(num_car):
            env.process(self.car(name='%d号车' % i,
                                     driving_time=i * 2,
                                     charge_duration=5))

    def car(self, name, driving_time, charge_duration):
        yield self.env.timeout(driving_time)
        print('%s 到达充电装桩 %d' % (name, self.env.now))

        with self.bcs.request() as req:
            yield req
            print('%s 开始充电 %s' % (name, self.env.now))
            yield self.env.timeout(charge_duration)
            print('%s 充电完成 %s' % (name, self.env.now))

env = simpy.Environment()
city = City(env, num_car=4, num_bcs=2)
env.run()

这种 with 形式与前一种形式的区别是不用额外对请求进行释放,有点类似于用 with 打开文件而不必把文件进行 close 的逻辑一样。这里电动车到达充电站之后,发出充电请求,当请求被响应时,电动车占用充电桩,仿真时间向前推进(充电时长),结束后自动释放 request,完成充电。

两种形式的代码是等价的,运行后打印的结果为:

0号车 到达充电装桩 0
0号车 开始充电 0
1号车 到达充电装桩 2
1号车 开始充电 2
2号车 到达充电装桩 4
0号车 充电完成 5
2号车 开始充电 5
3号车 到达充电装桩 6
1号车 充电完成 7
3号车 开始充电 7
2号车 充电完成 10
3号车 充电完成 12
文章来源:https://blog.csdn.net/Linshaodan520/article/details/135186785
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。