【发布时间】:2022-01-16 13:23:00
【问题描述】:
全面披露:我是一名学生,可能搞砸了一些约定、符号和最佳实践。我热烈欢迎反馈。
我正在尝试实现 SimPy 文档中的加油站示例版本,附在此处:
Covers:
- Resources: Resource
- Resources: Container
- Waiting for other processes
Scenario:
A gas station has a limited number of gas pumps that share a common
fuel reservoir. Cars randomly arrive at the gas station, request one
of the fuel pumps and start refueling from that reservoir.
A gas station control process observes the gas station's fuel level
and calls a tank truck for refueling if the station's level drops
below a threshold.
import itertools
import random
import simpy
RANDOM_SEED = 42
GAS_STATION_SIZE = 200 # liters
THRESHOLD = 10 # Threshold for calling the tank truck (in %)
FUEL_TANK_SIZE = 50 # liters
FUEL_TANK_LEVEL = [5, 25] # Min/max levels of fuel tanks (in liters)
REFUELING_SPEED = 2 # liters / second
TANK_TRUCK_TIME = 300 # Seconds it takes the tank truck to arrive
T_INTER = [30, 300] # Create a car every [min, max] seconds
SIM_TIME = 1000 # Simulation time in seconds
def car(name, env, gas_station, fuel_pump):
"""A car arrives at the gas station for refueling.
It requests one of the gas station's fuel pumps and tries to get the
desired amount of gas from it. If the stations reservoir is
depleted, the car has to wait for the tank truck to arrive.
"""
fuel_tank_level = random.randint(*FUEL_TANK_LEVEL)
print('%s arriving at gas station at %.1f' % (name, env.now))
with gas_station.request() as req:
start = env.now
# Request one of the gas pumps
yield req
# Get the required amount of fuel
liters_required = FUEL_TANK_SIZE - fuel_tank_level
yield fuel_pump.get(liters_required)
# The "actual" refueling process takes some time
yield env.timeout(liters_required / REFUELING_SPEED)
print('%s finished refueling in %.1f seconds.' % (name,
env.now - start))
def gas_station_control(env, fuel_pump):
"""Periodically check the level of the *fuel_pump* and call the tank
truck if the level falls below a threshold."""
while True:
if fuel_pump.level / fuel_pump.capacity * 100 < THRESHOLD:
# We need to call the tank truck now!
print('Calling tank truck at %d' % env.now)
# Wait for the tank truck to arrive and refuel the station
yield env.process(tank_truck(env, fuel_pump))
yield env.timeout(10) # Check every 10 seconds
def tank_truck(env, fuel_pump):
"""Arrives at the gas station after a certain delay and refuels it."""
yield env.timeout(TANK_TRUCK_TIME)
print('Tank truck arriving at time %d' % env.now)
amount = fuel_pump.capacity - fuel_pump.level
print('Tank truck refuelling %.1f liters.' % amount)
yield fuel_pump.put(amount)
def car_generator(env, gas_station, fuel_pump):
"""Generate new cars that arrive at the gas station."""
for i in itertools.count():
yield env.timeout(random.randint(*T_INTER))
env.process(car('Car %d' % i, env, gas_station, fuel_pump))
# Setup and start the simulation
print('Gas Station refuelling')
random.seed(RANDOM_SEED)
# Create environment and start processes
env = simpy.Environment()
gas_station = simpy.Resource(env, 2)
fuel_pump = simpy.Container(env, GAS_STATION_SIZE, init=GAS_STATION_SIZE)
env.process(gas_station_control(env, fuel_pump))
env.process(car_generator(env, gas_station, fuel_pump))
# Execute!
env.run(until=SIM_TIME)
我最大的挫败感是尝试采用某种方式将容器让给油罐车,这样在加油站(通过油罐车)补充其气体库存时,没有汽车可以加油。我尝试在汽车定义中添加 if 语句,以在 gas_station_control 条件中的循环被触发但未成功时检查加油站燃料库存的状态或产生资源。
我的情况是: 在设定的时间范围内有 3 辆随机汽车。加油站的容量是1.5罐汽油,一辆汽车抽一个负荷需要3个小时。一旦那辆车离开,我需要重新填充我的加油站储液罐,这需要 4 小时(如果液位 = 0.5 @ 0.25 负载/小时的速率,则需要 6 小时才能填充所有 1.5 个油箱)。我还需要确保如果队列中当前没有汽车在等待,我应该重新填充水库,不管我是否超出了汽车可能会停下来的当前时间范围。我需要确保记录每辆车在队列中等待的时间。
【问题讨论】:
-
-
这只是在补充燃油时延迟,但同时仍允许汽车从油箱中拉出。他们共享容器,所以我倾向于认为这与汽车的定义有关。
-
加油站不控制对集装箱的访问吗?因此,如果您希望加油车完全控制集装箱,则必须首先占用两个加油站资源。我会从这个开始,但如果您不希望卡车等待完全访问,您可以使用中断或优先资源队列
标签: python simulation simpy