Skip to content

Instantly share code, notes, and snippets.

@Sinabon2004
Last active November 28, 2025 21:03
Show Gist options
  • Select an option

  • Save Sinabon2004/aa53389863b9e4038017b8ba3ee540dc to your computer and use it in GitHub Desktop.

Select an option

Save Sinabon2004/aa53389863b9e4038017b8ba3ee540dc to your computer and use it in GitHub Desktop.
import math
import numpy as np
import matplotlib.pyplot as plt
# ==========================
# СЧИТАЕМ МЕТРИКИ
# ==========================
def state_space(c: int, g: int):
"""Множество состояний X: {(n1, n2): 0 <= n1 <= g, 0 <= n2, n1 + n2 <= C}."""
states = []
for n1 in range(0, g + 1):
for n2 in range(0, c + 1):
if n1 + n2 <= c:
states.append((n1, n2))
return states
def stationary_distribution(c: int, g: int, lam_1: float, lam_2: float, mu_1: float, mu_2: float):
"""Стационарное распределение вероятностей p(n1, n2)."""
ro_1 = lam_1 / mu_1 if mu_1 != 0 else 0.0
ro_2 = lam_2 / mu_2 if mu_2 != 0 else 0.0
X = state_space(c, g)
# Нормирующий знаменатель
Z = 0.0
for n1, n2 in X:
Z += (ro_1 ** n1) / math.factorial(n1) * (ro_2 ** n2) / math.factorial(n2)
if Z == 0:
return {(0, 0): 1.0}
p00 = 1.0 / Z
p = {}
for n1, n2 in X:
p[(n1, n2)] = p00 * (ro_1 ** n1) / math.factorial(n1) * (ro_2 ** n2) / math.factorial(n2)
return p
def blocking_probabilities(p: dict, c: int, g: int):
"""Вероятности блокировки по времени для заявок 1-го и 2-го типа."""
B1 = 0.0
B2 = 0.0
for (n1, n2), prob in p.items():
# Блокировка 1-го типа: n1 = g или n1 + n2 = C
if (n1 == g) or (n1 + n2 == c):
B1 += prob
# Блокировка 2-го типа: n1 + n2 = C
if (n1 + n2 == c):
B2 += prob
return B1, B2
def average_number(p: dict):
"""Среднее число заявок в системе: N = sum (n1 + n2) * p(n1, n2)."""
N = 0.0
for (n1, n2), prob in p.items():
N += (n1 + n2) * prob
return N
def metrics(c: int, lam_1: float, lam_2: float, mu_1: float, mu_2: float, g: int):
"""Вычисление всех основных метрик."""
p = stationary_distribution(c, g, lam_1, lam_2, mu_1, mu_2)
B1, B2 = blocking_probabilities(p, c, g)
av_num = average_number(p)
return {
"pn": p,
"B1": B1,
"B2": B2,
"average_number": av_num,
"blocking_calls": (B1, B2),
"blocking_load": (B1, B2),
}
# ==========================
# РИСУЕМ ГРАФИКИ
# ==========================
def plot_blocking_two_types_vs_lambda(c, g, lam_2, mu_1, mu_2, lam_1_range):
"""График зависимости вероятностей блокировки от λ1."""
B1_range = []
B2_range = []
for lam_1 in lam_1_range:
p = stationary_distribution(c, g, lam_1, lam_2, mu_1, mu_2)
B1, B2 = blocking_probabilities(p, c, g)
B1_range.append(B1)
B2_range.append(B2)
plt.figure(figsize=(10, 6))
plt.plot(lam_1_range, B1_range, label="B1(λ1) — блокировка 1-го типа",
color="crimson", linewidth=2)
plt.plot(lam_1_range, B2_range, label="B2(λ1) — блокировка 2-го типа",
color="navy", linewidth=2)
plt.title("Вероятность блокировки по времени в зависимости от λ1", fontsize=14)
plt.xlabel("Интенсивность λ1", fontsize=12)
plt.ylabel("Вероятность блокировки", fontsize=12)
plt.grid(True, linestyle="--", alpha=0.7)
plt.legend(fontsize=10)
plt.tight_layout()
plt.show()
def plot_average_number_vs_lambda(c, g, lam_2, mu_1, mu_2, lam_1_range):
"""График зависимости среднего числа заявок от λ1."""
N_range = []
for lam_1 in lam_1_range:
p = stationary_distribution(c, g, lam_1, lam_2, mu_1, mu_2)
N = average_number(p)
N_range.append(N)
plt.figure(figsize=(10, 6))
plt.plot(lam_1_range, N_range, label="N(λ1)", color="darkgreen", linewidth=2)
plt.title("Среднее число заявок в системе в зависимости от λ1", fontsize=14)
plt.xlabel("Интенсивность λ1", fontsize=12)
plt.ylabel("Среднее число заявок N", fontsize=12)
plt.grid(True, linestyle="--", alpha=0.7)
plt.legend(fontsize=10)
plt.tight_layout()
plt.show()
# ==========================
# ЗАПУСКАЕМ!!!
# ==========================
if __name__ == "__main__":
# Параметры модели
C = 4
G = 3
MU_1 = 2.0
MU_2 = 1.0
LAMBDA_1 = 1.0
LAMBDA_2 = 1.0
result = metrics(C, LAMBDA_1, LAMBDA_2, MU_1, MU_2, G)
print("\n--- Результаты ---")
for (n1, n2) in sorted(result["pn"].keys()):
print(f"P(n1={n1}, n2={n2}) = {result['pn'][(n1, n2)]:.5f}")
print(f"Сумма вероятностей = {sum(result['pn'].values()):.5f}")
print(f"Вероятность блокировки по времени для 1-го типа (B1) = {result['B1']:.5f}")
print(f"Вероятность блокировки по времени для 2-го типа (B2) = {result['B2']:.5f}")
print(f"Среднее число заявок = {result['average_number']:.5f}")
print(
f"Вероятность блокировки по вызовам: "
f"B1 = {result['blocking_calls'][0]:.5f}, "
f"B2 = {result['blocking_calls'][1]:.5f}"
)
print(
f"Вероятность блокировки по нагрузке: "
f"C1 = {result['blocking_load'][0]:.5f}, "
f"C2 = {result['blocking_load'][1]:.5f}"
)
# Диапазон λ1 для графиков
lam_1_range = np.arange(0.1, 50, 0.5)
# Построение графиков
plot_blocking_two_types_vs_lambda(C, G, LAMBDA_2, MU_1, MU_2, lam_1_range)
plot_average_number_vs_lambda(C, G, LAMBDA_2, MU_1, MU_2, lam_1_range)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment