Правильный подсчет доли простоя каналов обслуживания СМО
Как правильно подсчитать долю простоя каналов обслуживания? При увеличении времени работы мы получаем довольно высокую погрешность: Доля простоя A ожидаемая = 0,23 Доля простоя B ожидаемая = 0,38 Схема СМО:
import random
import matplotlib.pyplot as plt
# Параметры системы
simulation_time = 30 * 60 # время симуляции в секундах (30 минут)
lambda_ = 3 # среднее количество требований в минуту
arrival_probability = lambda_ / 60 # вероятность прибытия требования за каждую секунду
mu_A = 1 # средняя скорость обслуживания на канале A (требований за минуту)
mu_B = 3 # средняя скорость обслуживания на канале B (требований за минуту)
max_queue_length = 2 # максимальная длина очереди
# Вероятность обслуживания за каждую секунду
service_probability_A = mu_A / 60
service_probability_B = mu_B / 60
# Состояние системы
queue = 0 # текущее количество требований в очереди
failures = 0 # количество отказов
# Состояние каналов
busy_A = False # канал A занят или нет
busy_B = False # канал B занят или нет
# Счетчики времени простоя
idle_time_A = 0
idle_time_B = 0
sum_received_claims = 0 # сумма пришедших требований
# Отслеживание данных по времени
queue_over_time = []
failures_per_minute = []
# Имитация в течение заданного времени
for t in range(simulation_time):
print("---Секунда:\t", t+1, "---")
# Прибытие требований
if random.random() < arrival_probability:
print("Пришел клиент")
if queue < max_queue_length:
queue += 1
print("Текущая очередь: ", queue)
sum_received_claims += 1
else:
print("человек отклонен")
failures += 1
# Проверка возможности начать обслуживание на каналах
if not busy_A and queue > 0:
print("Начато обслуживание в А")
queue -= 1
print("Текущая очередь: ", queue)
busy_A = True
elif not busy_B and queue > 0:
print("Начато обслуживание в B")
queue -= 1
print("Текущая очередь: ", queue)
busy_B = True
# Время простоя каналов
if not busy_A and queue == 0:
idle_time_A += 1
if not busy_B and queue == 0:
idle_time_B += 1
# Проверка освобождения каналов
if busy_A and random.random() < service_probability_A:
print("Завершено обслуживание в А")
busy_A = False
if queue > 0:
print("Начало обслуживания в A")
busy_A = True
queue -= 1
if busy_B and random.random() < service_probability_B:
print("Завершено обслуживание в B")
busy_B = False
if queue > 0:
print("Начало обслуживания в B")
busy_B = True
queue -= 1
# Сбор данных каждую минуту
if t == 0:
queue_over_time.append(queue)
failures_per_minute.append(failures)
elif (t+1) % 60 == 0:
queue_over_time.append(queue)
failures_per_minute.append(failures)
# Среднее время простоя канала A и B
average_idle_A = idle_time_A / simulation_time
average_idle_B = idle_time_B / simulation_time
print("Общее количество пришедших требований: ", sum_received_claims)
print("Количество обслуженных требований", sum_received_claims-failures)
print("Доля обслуженных требований:", (sum_received_claims - failures) / sum_received_claims)
print("Количество отказов:", failures)
print("Доля отказов:", failures / sum_received_claims)
print("Средняя доля времени простоя канала A:", average_idle_A)
print("Средняя доля времени простоя канала B:", average_idle_B)
print("Средняя доля времени простоя обоих каналов обслуживания:", (average_idle_A + average_idle_B) / 2)
# Графики
plt.figure(figsize=(16, 9))
# Добавляем точки на график очереди во времени
plt.plot(list(range(0, simulation_time+1, 60)), queue_over_time, marker='o', linestyle='-', markersize=6)
plt.grid(True)
plt.xlabel("Время (в минутах)")
plt.ylabel("Количество требований в очереди")
plt.title("Состояние очереди по минутам")
plt.show()
plt.figure(figsize=(16, 9))
# Добавляем точки на график отказов за каждую минуту
plt.plot(list(range(0, simulation_time+1, 60)), failures_per_minute, marker='o', linestyle='-', markersize=6, color='red')
plt.grid(True)
plt.xlabel("Время (в минутах)")
plt.ylabel("Количество отказов")
plt.title("Отказы за каждую минуту")
plt.show()