Advertisement
AIwinter

Untitled

Sep 22nd, 2024
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.67 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3.  
  4. Q_LIMIT = int(input("Введите ограничение длины очереди: ")) # Ограничение длины очереди
  5. BUSY = 1 # Устройство занято
  6. IDLE = 0 # Устройство свободно
  7.  
  8.  
  9. class QueueSystem:
  10. def __init__(self, mean_interarrival, mean_service, time_end):
  11. self.mean_interarrival = mean_interarrival #среднее время между прибытиями требований
  12. self.mean_service = mean_service #среднее время обслуживания требования
  13. self.time_end = time_end #время завершения моделирования
  14.  
  15. # переменные состояния
  16. self.sim_time = 0.0 #текущее время в симуляции.
  17. self.server_status = IDLE #статус устройства (занято или свободно).
  18. self.num_in_q = 0 #количество запросов в очереди.
  19. self.time_last_event = 0.0 #время последнего события.
  20. self.num_custs_delayed = 0 #количество обслуженных запросов.
  21. self.total_of_delays = 0.0 #общее время задержки запросов.
  22. self.area_num_in_q = 0.0 #для расчета средней длины очереди
  23. self.area_server_status = 0.0 # и коэффициента занятости устройства.
  24. self.time_arrival = [0.0] * (Q_LIMIT + 1) #массив. хранит времена поступления запросов.
  25.  
  26. # инициализация списка времени для событий
  27. self.time_next_event = [1.0e+30, self.expon(self.mean_interarrival), 1.0e+30, self.time_end]
  28.  
  29. # Для графика
  30. self.time_values = [] # массив времени моделирования
  31. self.queue_values = [] # массив количества требований в системе
  32.  
  33. def expon(self, mean): #генерируем случайное время по экспоненциальному распределению
  34. return -mean * np.log(np.random.rand())
  35.  
  36. def timing(self): #функция выбирает ближайшее событие, изменяет текущее время симуляции на время этого события и возвращает тип события (например, прибытие или уход).
  37. min_time_next_event = min(self.time_next_event)
  38. self.sim_time = min_time_next_event
  39. next_event_type = self.time_next_event.index(min_time_next_event)
  40. if next_event_type == 0:
  41. print(f"Список событий пуст в момент времени {self.sim_time}")
  42. exit(1)
  43. return next_event_type
  44.  
  45. def update_time_avg_status(self):
  46. time_since_last_event = self.sim_time - self.time_last_event
  47. self.time_last_event = self.sim_time
  48. self.area_num_in_q += self.num_in_q * time_since_last_event #обновляем площадь под графиком количества запросов в очереди (это необходимо для расчета средней длины очереди)
  49. self.area_server_status += self.server_status * time_since_last_event #обновляем площадь занятости устройства (для расчета коэффициента занятости)
  50.  
  51. # обновление значений для графика
  52. self.time_values.append(self.sim_time)
  53. self.queue_values.append(self.num_in_q)
  54.  
  55. def arrive(self): #прибытие запроса
  56. self.time_next_event[1] = self.sim_time + self.expon(self.mean_interarrival) #рассчитывается следующее время прибытия запроса
  57.  
  58. if self.server_status == BUSY: #помещается в очередь + проверка лимита
  59. self.num_in_q += 1
  60. if self.num_in_q > Q_LIMIT:
  61. print(f"Переполнение массива time_arrival в момент времени {self.sim_time}")
  62. exit(2)
  63. self.time_arrival[self.num_in_q] = self.sim_time
  64. else:
  65. delay = 0.0 #свободно. обслуживается немедленно
  66. self.total_of_delays += delay
  67. self.num_custs_delayed += 1
  68. self.server_status = BUSY
  69. self.time_next_event[2] = self.sim_time + self.expon(self.mean_service)
  70.  
  71. def depart(self): #уход запроса
  72. if self.num_in_q == 0: #если нет запросов, свободное состояние
  73. self.server_status = IDLE
  74. self.time_next_event[2] = 1.0e+30
  75. else:
  76. self.num_in_q -= 1 #если не пуста обслуживаем первый запрос
  77. delay = self.sim_time - self.time_arrival[1]
  78. self.total_of_delays += delay
  79. self.num_custs_delayed += 1
  80. self.time_next_event[2] = self.sim_time + self.expon(self.mean_service)
  81.  
  82. # сдвигаем массив прибытия требований
  83. for i in range(1, self.num_in_q + 1):
  84. self.time_arrival[i] = self.time_arrival[i + 1]
  85.  
  86. def report(self):
  87. print(f"\nСредняя задержка в очереди: {self.total_of_delays / self.num_custs_delayed:.3f} мин")
  88. print(f"Среднее число требований в очереди: {self.area_num_in_q / self.sim_time:.3f}")
  89. print(f"Коэффициент занятости устройства: {self.area_server_status / self.sim_time:.3f}")
  90. print(f"Число завершенных задержек в очереди: {self.num_custs_delayed}\n")
  91.  
  92. def plot(self):
  93. #построение графика Q(t)
  94. plt.figure(figsize=(10, 6))
  95. plt.step(self.time_values, self.queue_values, where='post', label="Q(t) — число требований в системе")
  96. plt.xlabel("Время, t")
  97. plt.ylabel("Число требований, Q(t)")
  98. plt.title("График количества требований в системе Q(t) от времени t")
  99. plt.grid(True)
  100.  
  101. # на оси Y только целые числа
  102. max_queue = max(self.queue_values)
  103. plt.yticks(np.arange(1, max_queue + 1, step=1)) # Показываем только целые числа
  104.  
  105. plt.legend()
  106. plt.show()
  107.  
  108.  
  109. def main():
  110. mean_interarrival = float(input("Введите среднее время между прибытиями требований, мин: "))
  111. mean_service = float(input("Введите среднее время обслуживания требования, мин: "))
  112. time_end = float(input("Введите время завершения моделирования, мин: "))
  113.  
  114. queue_system = QueueSystem(mean_interarrival, mean_service, time_end)
  115.  
  116. while queue_system.sim_time < time_end:
  117. next_event_type = queue_system.timing()
  118. queue_system.update_time_avg_status()
  119.  
  120. if next_event_type == 1:
  121. queue_system.arrive()
  122. elif next_event_type == 2:
  123. queue_system.depart()
  124.  
  125. queue_system.report() # отчет по результатам моделирования
  126. queue_system.plot() # построение графика по завершении моделирования
  127.  
  128.  
  129. if __name__ == "__main__":
  130. main()
  131.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement