
срв6-7
.docxКассы в супермаркете
1. Тип системы массового обслуживания
Данная система представляет собой многоканальную систему массового обслуживания (СМО) с ограниченным количеством каналов, где каналы — это кассы в супермаркете, а обслуживаемые объекты — это покупатели. В такой системе каждый покупатель проходит через кассу для оплаты своих покупок. Если все кассы заняты, покупатели ждут в очереди.
2. Основные элементы СМО
Заявки (покупатели): Покупатели приходят в супермаркет через случайные интервалы времени. Они запрашивают обслуживание у кассиров и ждут в очереди, если все кассиры заняты.
Обслуживающие каналы (кассиры): Кассиры являются каналами системы обслуживания. В супермаркете определено три кассы (параметр NUM_CASHIERS). Покупатели обслуживаются на кассе в течение фиксированного времени обслуживания (параметр SERVICETIME).
Очередь: Если все кассы заняты, покупатели становятся в очередь. Очередь реализована с помощью механизма ресурсов в SimPy. В этом примере очередь не ограничена по длине, что означает, что количество покупателей, ожидающих в очереди, теоретически не ограничено.
3. Поведение покупателей (заявок)
Каждый покупатель проходит следующие этапы:
Прибытие в супермаркет: Когда покупатель приходит, он пытается получить доступ к кассе.
Запрос обслуживания: Если есть свободная касса, покупатель сразу начинает обслуживание. Если все кассы заняты, покупатель ждёт, пока не освободится кассир.
Обслуживание: Как только кассир освобождается, начинается процесс оплаты (обслуживания), который длится фиксированное количество времени (5 минут в данном примере).
Уход: После завершения обслуживания покупатель покидает супермаркет.
4. Модель обслуживания
Модель использует библиотеку SimPy для имитации работы супермаркета. Ключевым элементом является класс Supermarket, который представляет собой супермаркет с ограниченным количеством кассиров, реализованных через механизм ресурсов (simpy.Resource).
Метод serve моделирует процесс обслуживания покупателя, который длится фиксированное время (servicetime), а результат процесса обслуживания выводится в консоль.
5. Модель генерации заявок
Функция setup отвечает за создание новых покупателей:
Изначально создаются несколько покупателей, которые сразу запрашивают обслуживание.
Затем в течение симуляции новые покупатели продолжают приходить в магазин через случайные интервалы времени (интервалы варьируются в пределах заданного диапазона на основе параметра T_INTER).
6. Основные параметры модели
NUM_CASHIERS (3) — количество касс (каналов), которые могут обслуживать покупателей одновременно.
SERVICETIME (5 минут) — фиксированное время обслуживания одного покупателя на кассе.
T_INTER (7 минут) — среднее время между приходом покупателей.
SIM_TIME (20 минут) — время работы модели (длительность симуляции).
7. Результаты и выводы
Симуляция выводит действия покупателей и их взаимодействие с кассирами:
Покупатель приходит в магазин и либо сразу начинает обслуживание, либо ждёт в очереди, если все кассиры заняты.
По завершении обслуживания кассир завершает процесс оплаты, и покупатель покидает супермаркет.
import itertools
import random
import simpy
# Константы
RANDOM_SEED = 42
NUM_CASHIERS = 3 # Количество касс в супермаркете
SERVICETIME = 5 # Время обслуживания покупателя в минутах
T_INTER = 2 # Новые покупатели приходят каждые ~7 минут
SIM_TIME = 20 # Время моделирования в минутах
QUEUE_LIMIT = 5 # Максимальная длина очереди
class Supermarket:
"""Супермаркет с ограниченным количеством касс и очереди."""
def __init__(self, env, num_cashiers, servicetime, queue_limit):
self.env = env
self.cashier = simpy.Resource(env, num_cashiers)
self.servicetime = servicetime
self.queue_limit = queue_limit
def serve(self, customer):
"""Процесс обслуживания покупателя."""
yield self.env.timeout(self.servicetime)
print(f"Cashier finished serving {customer}.")
def customer(env, name, supermarket):
"""Процесс прихода покупателя в супермаркет."""
print(f'{name} arrives at the supermarket at {env.now:.2f}.')
if len(supermarket.cashier.queue) >= supermarket.queue_limit:
print(f'{name} could not enter the queue at {env.now:.2f}. The queue is full!')
return
with supermarket.cashier.request() as request:
yield request
print(f'{name} starts being served at {env.now:.2f}.')
yield env.process(supermarket.serve(name))
print(f'{name} leaves the supermarket at {env.now:.2f}.')
def setup(env, num_cashiers, servicetime, t_inter, queue_limit):
"""Создание супермаркета и генерация покупателей."""
supermarket = Supermarket(env, num_cashiers, servicetime, queue_limit)
customer_count = itertools.count()
# Создаём начальных покупателей
for _ in range(4):
env.process(customer(env, f'Customer {next(customer_count)}', supermarket))
# Создаём новых покупателей пока длится симуляция
while True:
yield env.timeout(random.randint(t_inter - 2, t_inter + 2))
env.process(customer(env, f'Customer {next(customer_count)}', supermarket))
# Запуск симуляции
print('Supermarket Simulation with Limited Queue')
random.seed(RANDOM_SEED) # Для воспроизводимости результатов
# Создаём окружение и запускаем процесс настройки
env = simpy.Environment()
env.process(setup(env, NUM_CASHIERS, SERVICETIME, T_INTER, QUEUE_LIMIT))
# Запускаем симуляцию
env.run(until=SIM_TIME)