双服务台串联排队系统——Python仿真

串联排队系统是一种常见的排队系统结构,由多个单一排队系统按照特定的顺序连接而成。在串联排队系统中,一个排队系统的输出将成为下一个排队系统的输入,从而形成连续的流程。这种系统结构可以用于模拟和优化许多现实世界中的流程,如生产线、物流运输等。

一、双服务台串联排队系统模型结构

双服务台排队串联模型:假设顾客按照密度为\(\lambda(t),t>0\) 非齐次泊松过程到达某服务站接受服务,服务站有两个服务台1和2,顾客先先到服务台1接受服务,然后再到服务台2接受服务。若顾客到达服务站时且服务台1处于闲期,则直接到服务台1接受服务,若服务台1处于忙期,则排队等候。顾客在服务台1接受服务结束后,则到达服务台2。若服务台2处于闲期,则顾客直接到服务台2接受服务,若服务台2处于忙期,则排队等候接受。两个服务台有顾客排队,则按照先到先服务的原则进行服务;如果服务台空无一人,服务台就处于闲期直到下一个顾客到达进行服务。顾客接受完服务台2的服务后,就离开服务系统,其排队系统模型结构参看下图。

一般地,假设服务台1和2对一名顾客服务的时间为随机变量且分布为\(G_1,G_2\)。假设 \(T\)为一个固定时间,\(T\)时刻后不再接受顾客进入系统,但对系统中剩余顾客仍进行服务,直到对所有顾客服务完为止。

二、供应链订单排队系统

排队论在供应链订单仿真分析中的应用可以帮助评估和改进供应链的订单处理流程、服务水平和效率。通过建立排队模型和进行仿真分析,可以揭示订单处理过程中的瓶颈和拥堵问题,并提供优化策略。以下是一些供应链订单仿真分析中排队论的应用示例:
评估订单处理时间:排队论可以用于评估订单在供应链中的处理时间。通过模拟订单的到达率、处理时间和服务能力,可以分析订单处理过程中的等待时间、延误和效率。这有助于确定订单处理的瓶颈环节,优化资源分配和提高订单处理速度。
预测订单满足率:排队论可以应用于预测订单满足率。通过模拟订单到达率和处理能力,可以评估不同情况下的订单满足率和交付时间。这有助于制定合理的订单接受和处理策略,以提高供应链的客户满意度和交付准时率。
优化订单处理策略:排队论可以帮助优化订单处理策略。通过仿真分析不同的订单处理策略,如先进先出、优先级排序等,可以评估它们对订单处理时间、等待时间和服务水平的影响。这有助于制定最佳的订单处理策略,以提高供应链的效率和客户体验。
评估订单处理能力:排队论可以用于评估供应链中的订单处理能力。通过仿真分析不同的订单到达率和处理能力,可以确定供应链在不同负荷条件下的性能和瓶颈。这有助于决策者评估供应链的承载能力,制定资源投入和扩展计划。
模拟供应链变化和改进效果:排队论可以用于模拟供应链的变化和改进效果。通过建立基准模型和改进方案模型,可以比较不同方案对订单处理时间、等待时间和服务水平的影响。这有助于决策者评估改进措施的可行性和效果,以做出有根据的决策。

三、双服务台串联排队仿真

简要来说,仿真是在纯数学建模和实际系统的优缺点之间的⼀个折中。相对数学模型来说,仿真不需要⾼深的数学技巧,也不需要作过多的简化和假设,并且在求解复杂系统时,不会⾯对状态和空间爆炸的问题。仿真可以⽤来验证数学模型的正确性,而相比实际系统,仿真的成本要⼩得多,并且容易取得更多的统计信息。这里着重考虑两个等待制服务台的串联排队系统模型。针对输入过程为泊松分布,两个服务台的服务时间都服从指数分布的特殊模型,前人已经根据生灭过程理论得到了队长的平稳概率分布。
供应链订单处理涵盖了从订单生成到交付的全过程,包括订单确认、库存管理、生产调度、物流配送等环节,如下图所示。这个流程能确保订单能够高效、准确地处理,满足客户需求,提升供应链的运作效率和响应能力。通过有效的供应链订单流处理,企业可以减少库存积压、降低运营成本、提升客户满意度。

订单确认和订单履行是两个核心的处理环节,订单验证通过后,系统会向客户发送订单确认信息,包括订单号、总价和预计交付时间等,客户需要确认订单信息并进行支付;订单履行涉及到分拣和打包产品以备发货的工作。现某网上商城订单处理的主要流程如下:网上支付成功后的顾客订单列到达的时间间隔服从均值为0.5分钟的负指数分布,订单确认时间服从均值为1分钟的负指数分析;商城采用单一订单分配存货,安排拣货及发货等采用公司软件辅助处理,拣选中心根据实时传送的拣货单进行拣货,订单履行时间平均每单大约4.5分钟。现商城共有工作人员5位,如何安排能使商城处理订单的效率最高?该商城4小时工作时间最多可处理多少订单?

#文件queueing_system_simulation.xlsx记录排队过程关键时刻点,比如服务开始时间、服务结束时间等
import simpy
import random
import pandas as pd

RANDOM_SEED = 42
SIM_TIME = 240  # Total working time in units
ARRIVAL_RATE = 2  # Arrival rate, lambda
SERVICE_RATE_1 = 1.0  # Service rate for the first stage, mu1
SERVICE_RATE_2 = 1 / 4.5  # Service rate for the second stage, mu2

# Read number of servers for each stage from user input
NUM_SERVERS_1 = int(input("Enter the number of servers in the first stage: "))
NUM_SERVERS_2 = int(input("Enter the number of servers in the second stage: "))

# Collect data
data = []

class QueueingSystem:
    def __init__(self, env, num_servers_1, num_servers_2, service_rate_1, service_rate_2):
        self.env = env
        self.server_1 = simpy.Resource(env, num_servers_1)
        self.server_2 = simpy.Resource(env, num_servers_2)
        self.service_rate_1 = service_rate_1
        self.service_rate_2 = service_rate_2

    def first_stage_service(self, customer):
        yield self.env.timeout(random.expovariate(self.service_rate_1))

    def second_stage_service(self, customer):
        yield self.env.timeout(random.expovariate(self.service_rate_2))

def customer(env, name, system):
    arrival_time = env.now
    print(f'{name} arrives at {arrival_time:.2f}')

    with system.server_1.request() as request:
        queue_start_time_1 = env.now
        yield request
        start_first_service_time = env.now
        wait_time_1 = start_first_service_time - queue_start_time_1
        print(f'{name} starts first stage service at {start_first_service_time:.2f}')
        yield env.process(system.first_stage_service(name))
        leave_first_service_time = env.now
        print(f'{name} leaves first stage service at {leave_first_service_time:.2f}')

    with system.server_2.request() as request:
        queue_start_time_2 = env.now
        yield request
        start_second_service_time = env.now
        wait_time_2 = start_second_service_time - queue_start_time_2
        print(f'{name} starts second stage service at {start_second_service_time:.2f}')
        yield env.process(system.second_stage_service(name))
        departure_time = env.now
        print(f'{name} leaves second stage service at {departure_time:.2f}')
        total_time_in_system = departure_time - arrival_time
        print(f'{name} spent {total_time_in_system:.2f} in the system')

    # Collect data
    data.append({
        'Customer': name,
        'Arrival Time': arrival_time,
        'Start First Service Time': start_first_service_time,
        'First Stage Wait Time': wait_time_1,
        'Leave First Service Time': leave_first_service_time,
        'Start Second Service Time': start_second_service_time,
        'Second Stage Wait Time': wait_time_2,
        'Departure Time': departure_time,
        'Total Time in System': total_time_in_system
    })

def setup(env, arrival_rate, system):
    i = 0
    while True:
        yield env.timeout(random.expovariate(arrival_rate))
        i += 1
        env.process(customer(env, f'Customer {i}', system))

# Setup and start the simulation
print('Queueing System Simulation')
random.seed(RANDOM_SEED)
env = simpy.Environment()

# Create the queueing system
system = QueueingSystem(env, NUM_SERVERS_1, NUM_SERVERS_2, SERVICE_RATE_1, SERVICE_RATE_2)

# Start the arrival process
env.process(setup(env, ARRIVAL_RATE, system))

# Execute the simulation
env.run(until=SIM_TIME)

# Convert collected data to DataFrame
df = pd.DataFrame(data)

# Save to Excel file
output_file = 'queueing_system_simulation.xlsx'
df.to_excel(output_file, index=False)
print(f'Simulation data saved to {output_file}')

# Calculate and print performance metrics
total_customers_served = len(df)
average_time_in_system = df['Total Time in System'].mean()
average_waiting_time_in_system = df['First Stage Wait Time'].mean() + df['Second Stage Wait Time'].mean()

print(f'Total customers served: {total_customers_served}')
print(f'Average time in system: {average_time_in_system:.2f} units')
print(f'Average waiting time in system: {average_waiting_time_in_system:.2f} units')
Enter the number of servers in the first stage: 2    #从键盘输入第一站服务台数量
Enter the number of servers in the second stage: 3    #从键盘输入第二站服务台数量
Total customers served: 130                          #完成服务订单量
Average time in system: 96.94 units                   #顾客系统逗留时间
Average waiting time in system: 90.71 units           #顾客平均排队等待时间

 Enter the number of servers in the first stage: 1    #从键盘输入第一站服务台数量
Enter the number of servers in the second stage: 4    #从键盘输入第二站服务台数量
Total customers served: 207                          #完成服务订单量
Average time in system: 70.45 units                   #顾客系统逗留时间
Average waiting time in system: 65.22 units           #顾客平均排队等待时间

5个工作人员最优分配为第一站1人、第二站4人工作效率最高。通过模拟排队仿真解决了订单子系统的工作分配问题,当然所有数据都是模拟的,其精度还要测试和调整,不过已可管中窥豹了。

# Plotting system state over time
time_data = sorted(time_data, key=lambda x: x[0])
time, customers = zip(*time_data)
plt.plot(time, customers)
plt.xlabel('Time')
plt.ylabel('Number of Customers in System')
plt.title('System State Over Time')
plt.show()

总结

在这次排队系统仿真中,我们构建并模拟了一个两阶段服务系统,旨在分析其性能指标。使用SimPy库进行仿真,设定总仿真时间为240个时间单位,客户到达率为每单位时间2个,第一阶段服务率为每单位时间1个,第二阶段服务率为每个为4.5分钟。系统包含两个服务阶段,5人的最优配置为1个和4个服务器。在仿真过程中,我们跟踪了每个客户的到达时间、服务开始和结束时间、等待时间以及在系统中总共花费的时间。我们还记录了系统中客户数量随时间的变化。通过数据分析,我们得出

平均系统逗留时间:这是客户在系统中从到达至离开的平均时间。仿真结果显示,平均系统逗留时间为一定值,表明系统在设定条件下具有一定的处理效率。
平均等待时间:包括第一阶段和第二阶段服务的等待时间。平均等待时间的计算揭示了客户在每个阶段等待服务的时间。
系统中顾客的变化图:记录系统中顾客户数量随时间的变化。

这些结果为优化排队系统提供了数据支持,例如调整服务器数量和服务速率以提高整体效率和客户满意度。本次仿真提供了宝贵的洞察,帮助理解复杂排队系统的行为及其性能特征。

参考文献

  1. 两服务台串联排队系统
  2. 串联双服务台的排队模型及其R实现
  3. python实现电影院仿真(SimPy)
posted @ 2023-07-12 23:19  郝hai  阅读(639)  评论(0编辑  收藏  举报