共享服务器的队列模拟

Queue Simulation of sharing the server

我正在处理与咖啡馆柜台相关的队列模拟。这个吧台有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, partyQ, 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, party, 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, partyQ, counter_seats))
env.process(seat_party(env, partyQ,counter_seats))

env.run(24)