Вывод
В ходе лабораторной работы были изучены концепции, лежащие в основе теории создания и анализа цепей Маркова, а также систем массового обслуживания.
Было выявлено, что при вторичной оценке переходов в цепи Маркова,
полученные данные будут наиболее походить на исходные при увеличении числа итераций переходов, что доказывается законом больших чисел.
В случае с системами массового обслуживания, было выяснено, что система из задания является не эффективной, так как очередь в ней почти собирается достаточно большая, время пребывания в ней хоть и невелико, но не позволяет уменьшить вероятность отказов, а вероятность отказов стремится к 40%, что тоже неэффективно.
11
Приложение 1.
import numpy as np
import matplotlib.pyplot as plt import networkx as nx
# Исходная матрицапереходов
P = np.array([ [2, 5, 3, 4], [8, 5, 4, 2], [5, 4, 3, 2], [1, 5, 4, 4]
])
states = ['Healthy', 'Unwell', 'Sick', 'Very sick']
# 1. Нормировка матрицы, чтобы каждая строка в сумме давала 1
P_normalized = P / P.sum(axis=1, keepdims=True)
# 2. Выводим нормированную матрицу print("Нормированная матрица переходов:") print(P_normalized)
# 3. Построение графа матрицы переходов
def plot_transition_graph(P, states, title): G = nx.DiGraph()
for i in range(len(states)):
for j in range(len(states)):
G.add_edge(states[i], states[j], weight=P[i, j]) pos = nx.spring_layout(G)
edges = G.edges(data=True)
weights = [edge[2]['weight'] for edge in edges]
nx.draw(G, pos, with_labels=True, node_size=3000, node_color='lightblue', font_size=10, font_weight='bold', arrows=True)
nx.draw_networkx_edge_labels(G, pos, edge_labels={(u, v): f"{d['weight']:.2f}" for u, v, d in G.edges(data=True)}, font_color='red')
nx.draw_networkx_edges(G, pos, edge_color=weights, edge_cmap=plt.cm.Blues, width=2)
plt.title(title)
plt.show()
plot_transition_graph(P_normalized, states, "Transition Graph for Normalized Markov Chain")
# 4. Построение кумулятивной матрицы переходов
P_cum = np.cumsum(P_normalized, axis=1)
12
print("\nКумулятивная матрица переходов:") print(P_cum)
# 5. Моделирование поведения цепи Маркова на 200 итераций
def simulate_markov_chain(P_cum, num_iterations, initial_state=0): current_state = initial_state
states_over_time = [current_state] for _ in range(num_iterations):
r = np.random.rand()
next_state = np.searchsorted(P_cum[current_state], r) states_over_time.append(next_state)
current_state = next_state return states_over_time
def plot_chain_evolution(states_over_time, title): plt.figure(figsize=(10, 6))
plt.plot(states_over_time, drawstyle='steps-mid', linewidth = 0.5) plt.yticks(np.arange(len(states)), labels=states) plt.xlabel("Iteration")
plt.ylabel("State")
plt.title(title)
plt.show()
# 6. График эволюции состояния цепи для 200 итераций states_200 = simulate_markov_chain(P_cum, 200)
plot_chain_evolution(states_200, "Markov Chain Evolution over 200 Iterations")
# 7. Повторяем для 1000 и 10000 итераций states_1000 = simulate_markov_chain(P_cum, 1000)
plot_chain_evolution(states_1000, "Markov Chain Evolution over 1000 Iterations")
states_10000 = simulate_markov_chain(P_cum, 10000)
plot_chain_evolution(states_10000, "Markov Chain Evolution over 10000 Iterations")
# 8. Оценка цепи Маркова по наблюдениям
def estimate_transition_matrix(states_over_time, num_states): transition_counts = np.zeros((num_states, num_states))
for (i, j) in zip(states_over_time[:-1], states_over_time[1:]): transition_counts[i, j] += 1
# Нормируем матрицу по строкам
transition_matrix_est = transition_counts / transition_counts.sum(axis=1, keepdims=True)
13
return transition_matrix_est
# 9. Рассчитываем оценочные матрицы переходов для 200, 1000 и 10000 итераций
P_est_200 = estimate_transition_matrix(states_200, len(states)) P_est_1000 = estimate_transition_matrix(states_1000, len(states)) P_est_10000 = estimate_transition_matrix(states_10000, len(states)) print("\nОценочная матрица переходов для 200 итераций:") print(P_est_200)
print("\nОценочная матрица переходов для 1000 итераций:") print(P_est_1000)
print("\nОценочная матрица переходов для 10000 итераций:") print(P_est_10000)
# 10. Построение графов для оценочных матриц переходов
plot_transition_graph(P_est_200, states, "Transition Graph for Estimated Matrix (200 iterations)")
plot_transition_graph(P_est_1000, states, "Transition Graph for Estimated Matrix (1000 iterations)")
plot_transition_graph(P_est_10000, states, "Transition Graph for Estimated Matrix (10000 iterations)")
# 11. Повторение пункта 7 для полученной матрицы на 200 итераций
P_cum_sec = np.cumsum(P_est_200, axis=1) second_200 = simulate_markov_chain(P_cum_sec, 200)
plot_chain_evolution(second_200, "Markov Chain Evolution over 200 Iterations")
14
Приложение 2.
import math
import pandas as pd
# Задаём начальные значения
n = 2 # Количество каналов
m = 10 # количество мест в очереди
lam = 10 # Интенсивность поступления заявок mu = 5 # интенсивность обслуживания
#коэффициент загрузки системы
rho = lam/mu
# Вероятность что канал окажется свободным p0 = 0
if rho == n:
for i in range(0,n+1):
p0 = p0+(n**i/math.factorial(i))
else:
for i in range(0,n+1):
p0 = p0+(rho**i/math.factorial(i))
p0 = p0 + (rho**(n+1)/n*math.factorial(n))*((1-(rho/n)**m)/(1-(rho/n)))
p0 = 1/p0
# Вероятность что канал окажется занятым p1 = 1-p0
# Вероятность что заявка получит отказ
Potk = rho**(n+m)/((n**m)*math.factorial(n))*p0
# относительная пропускная способность
Q = 1 - Potk
# абсолютная пропускная способность
A = lam*Q
# Среднее количество занятых каналов kzan = A/mu
# Средняя длина очереди в системе if rho == n:
Loch = ((n**n)/math.factorial(n))*((math.factorial(n)*(m+1))/2)*p0 else:
Loch = (rho**(n+1)/n*math.factorial(n))*((1-(rho/n)**m*(m+1- (m/n*rho)))/(1-rho/n)**2)
15
# Среднее время ожидания в очереди
Toch = Loch/lam
# Среднее количество заявок в системе
Lsist = Loch + kzan
# Среднее время пребывания заявки в системе
Tsist = Lsist/lam
# Сведение всех показателей в таблицу data = {
"Показатель": ["Вероятность свободности канала (p0)", "Вероятность занятости канала (p1)", "Абсолютная пропускная способность (A)", "Относительная пропускная способность (Q)", "Вероятность отказа (P_отк)",
"Среднее количество занятых каналов (k_зан)", "Среднее количество заявок в системе (L_сист)", "Среднее время пребывания заявки в системе (T_сист)", "Средняя длина очереди (L_оч)",
"Среднее время ожидания заявки в очереди (T_оч)"],
"Значение": [p0, p1, A, Q, Potk, kzan, Lsist, Tsist, Loch, Toch]
}
# Реализуем и печатаем таблицу df = pd.DataFrame(data) print(df)
# Сохранение в файл Excel df.to_excel("lab3.xlsx", index=False)
16
