共享服务器的队列模拟

问题描述

我正在处理与咖啡厅柜台相关的队列模拟。这个柜台有 6 把椅子,因此最多可以同时为 6 人服务。客户将参加聚会。每一方的客户数量可以以相同的概率等于 1、2、3、4、5 或 6。 每方入座后在餐厅的时间​​等于0.5个时间单位。 假设多方可能共享计数器。服务顺序为先到先得。假设下一方的大小为 x。当至少有 x 个空位可用时,派对将就座。餐厅将为所有在 t=12 之前到达的派对提供服务,然后关闭。在 t=12 之后到达的各方将被拒之门外。以下是各方的到达时间。

arrival_times=np.array([ 0.0473792,1.06007777,2.02933004,2.37675438,2.69755975,3.50251282,5.98208415,6.14630716,7.3503128,7.60377882,8.22431782,8.5749094,8.98564659,9.12636855,9.75145154,11.01328947])

我原来的代码是这样的:

import numpy as np
import simpy

def arrival(arrival_times):
    i=0
    inter_arrivals = arrival_times
    for inter_arrival in inter_arrivals:
        yield env.timeout(inter_arrival)
        i+=1

        Outcomes["arrival"].append(env.Now)
        env.process(service(i))

def service(i):

    #requesting the front desk

    rqt = resource.request()
    yield rqt
    service_time = 0.5
    yield env.timeout(service_time)
    resource.release(rqt)

    Outcomes["depart"].append(env.Now)
    Outcomes["id"].append(i)
    Outcomes["customers"].append(np.np.random.randint(1,7))

Outcomes = {"arrival":[],"depart":[],"id":[],"customers":[]}
env = simpy.Environment()
resource = simpy.Resource(env)
env.process(arrival(arrival_times))
T = 12
env.run(until=T)

arrival_n = np.array(Outcomes["arrival"])
depart_n = np.array(Outcomes["depart"])
id_n = np.array(Outcomes["id"])
customer_n = np.array(Outcomes["customers"])

但我的代码要求只有一方可以占用柜台。另一方可以在他们之后获得服务。有人可以解释如何模拟队列以便不同方可以共享计数器吗?非常感谢你。我看到有一个名为 Simpy.AllOf() 的函数,它可能很有用,并且会在列表中的所有事件都被触发时处理事件。但我还是不知道。

解决方法

看起来你有一个计数器的资源池。您需要 6 个柜台凳的资源池。队伍中的每个人都需要对凳子进行资源请求,当队伍中的每个人都有凳子时,就可以就座和服务。聚会结束后,每个人都需要释放他们抓住的凳子。 请注意,有一个 simpy.events.AllOf 可以为许多事件产生一个收益

这是我的快速代码示例

"""
Serving parties at a cafe couter

parties are seated fifo
there must be enough available seats to seat the 
entire party befor the party is dequeued and seated

more then one party can be at the cafe counter at a time

Programmer: Michael R. Gibbs
"""

import simpy
import random

def gen_arrivals(env,arrival_sched,partyQ,seats):
    """
    use a arrival schedule to create parties of size 1 to 6
    and put them in to a wait queue
    """

    i = 0
    for next_arrive in arrival_sched:
        gap = next_arrive - env.now
        yield env.timeout(gap)

        # next arrial time has been reacked
        # create a party
        i+= 1
        party = {
            "party_id": i,"arrive_time": env.now,"party_size": random.randrange(1,6)
        }

        # put party in queue
        yield partyQ.put(party)
        print(f"{env.now:06.3f}",f"party {party['party_id']} has arrived and needs {party['party_size']} seats,{6 -seats.count} seats avaliable")

def seat_party(env,counter_seats):
    """
    process the seatting queue,FIFO
    next party will block until there 
    are enough seats for the entire party,even if a latter party
    can fit at the counter
    """

    while True:
        party = yield partyQ.get()

        # get seat request for each person in party
        seat_requests = []
        for _ in range(party['party_size']):
            rqst = counter_seats.request()
            seat_requests.append(rqst)
        
        # save the seats so we can release them lator
        party['seat_requests'] = seat_requests

        # yield until ALL the requests have been filled
        # since we are doing one party at a time,there
        # is not deadlock contention for seats between the parties
        yield simpy.events.AllOf(env,seat_requests)

        print(f"{env.now:06.3f}",f"party {party['party_id']} has been seated taking {party['party_size']} seats,{6 -counter_seats.count} seats avaliable")

        # once seated serve async so we can immediatly start
        # seating the next party,in case there still enough
        # seats to seat the next party imediatly
        env.process(serve_party(env,party,counter_seats))

def serve_party(env,counter_seats):
    """
    serve the party then release the seats
    back to the counter seat resource pool
    """

    yield env.timeout(0.5)

    for seat_request in party['seat_requests']:
        yield counter_seats.release(seat_request)

    # and the party leaves
    print(f"{env.now:06.3f}",f"party {party['party_id']} has been served relasing {party['party_size']} seats,{6 -counter_seats.count} seats avaliable")

""" schedule of arrial times for parties """
arrival_times=[ 0.0473792,1.06007777,2.02933004,2.37675438,2.69755975,3.50251282,5.98208415,6.14630716,7.3503128,7.60377882,8.22431782,8.5749094,8.98564659,9.12636855,9.75145154,11.01328947]

# start simulation and kick off arrival generation,and queue processing
env = simpy.Environment()
counter_seats = simpy.Resource(env,capacity=6)
partyQ = simpy.Store(env,99)
env.process(gen_arrivals(env,arrival_times,counter_seats))
env.process(seat_party(env,counter_seats))

env.run(24)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...