Skip to content

Instantly share code, notes, and snippets.

@Sinabon2004
Created October 4, 2025 14:18
Show Gist options
  • Select an option

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

Select an option

Save Sinabon2004/1bdcec6e7dbcb2e1c86378a1ce3870a9 to your computer and use it in GitHub Desktop.
import math
import numpy as np
import matplotlib.pyplot as plt
# ==========================
# СЧИТАЕМ МЕТРИКИ
# ==========================
def stationary_distribution(c, g, ro_1, ro_2):
values = []
# n ≤ g
sigma1 = sum(((ro_1 + ro_2) ** n) / math.factorial(n) for n in range(0, g+1))
# n > g
sigma2 = ((ro_1 + ro_2) ** g) / math.factorial(g) * sum((ro_1 ** k) / math.factorial(k) for k in range(1, c-g+1))
p0 = 1 / (sigma1 + sigma2)
for n in range(0, c+1):
if n <= g:
pn = ((ro_1 + ro_2) ** n) / math.factorial(n) * p0
else:
pn = ((ro_1 + ro_2) ** g) / math.factorial(g) * (ro_1 ** (n-g)) / math.factorial(n-g) * p0
values.append(pn)
return values
def time_blocking(pn: list):
"""Вероятность блокировки по времени (последнее состояние)."""
return pn[-1]
def average_number(pn: list):
"""Среднее число обслуживаемых заявок."""
return sum(n * pn[n] for n in range(len(pn)))
def metrics(c: int, lam_1: float, lam_2: float, mu: float, g: int):
"""Вычисление всех основных метрик."""
ro_1 = lam_1 / mu
ro_2 = lam_2 / mu
pn = stationary_distribution(c, g, ro_1, ro_2)
E1 = pn[c]
E2 = sum(pn[n] for n in range(g, c+1))
t_b = time_blocking(pn)
av_num = average_number(pn)
blocking_on_calls_1 = (lam_1 / (lam_1 + lam_2)) * t_b if lam_1 + lam_2 > 0 else 0
blocking_on_calls_2 = (lam_2 / (lam_1 + lam_2)) * t_b if lam_1 + lam_2 > 0 else 0
return {
"pn": pn,
"time_block": t_b,
"average_number": av_num,
"blocking_calls": (blocking_on_calls_1, blocking_on_calls_2),
"blocking_load": (t_b, t_b),
"E1": E1,
"E2": E2,
}
# ==========================
# СЧИТАЕМ РАЗМЕТКУ И РИСУЕМ ГРАФИКИ
# ==========================
def plot_blocking_two_types_vs_lambda(c, g, lam_2, mu, lam_range):
B1_range = []
B2_range = []
for lam_1 in lam_range:
pn = stationary_distribution(c, g, lam_1 / mu, lam_2 / mu)
t_b = time_blocking(pn)
total_lambda = lam_1 + lam_2
if total_lambda > 0:
B1 = (lam_1 / total_lambda) * t_b
B2 = (lam_2 / total_lambda) * t_b
else:
B1, B2 = 0, 0
B1_range.append(B1)
B2_range.append(B2)
plt.figure(figsize=(10,6))
plt.plot(lam_range, B1_range, label="Блокировка заявок 1-го типа", color="crimson", linewidth=2)
plt.plot(lam_range, B2_range, label="Блокировка заявок 2-го типа", color="navy", linewidth=2)
plt.title("Вероятность блокировки по типам заявок", fontsize=16)
plt.xlabel("Интенсивность запросов λ1", fontsize=14)
plt.ylabel("Вероятность блокировки", fontsize=14)
plt.grid(True, linestyle="--", alpha=0.7)
plt.legend(fontsize=12)
plt.tight_layout()
plt.show()
def plot_average_number_vs_lambda(c, g, lam_2, mu, lam_range):
av_num_range = [
average_number(stationary_distribution(c, g, lam / mu, lam_2 / mu)) for lam in lam_range
]
plt.figure(figsize=(10, 6))
plt.plot(lam_range, av_num_range, label="Среднее число обслуживаемых заявок", linewidth=2, color="navy")
plt.title("Среднее число обслуживаемых заявок от интенсивности запросов", fontsize=16)
plt.xlabel("Интенсивность запросов (λ1)", fontsize=14)
plt.ylabel("Среднее число заявок", fontsize=14)
plt.grid(True, linestyle="--", alpha=0.7)
plt.legend(fontsize=12)
plt.tight_layout()
plt.show()
# ==========================
# ЗАПУСКАЕМ!!!
# ==========================
if __name__ == "__main__":
# АРГУМЕНТЫ ИЗ ПРИМЕРА ВЫПОЛНЕНИЯ
g = 56
C = 121
MU = 0.5
LAMBDA_1 = 50
LAMBDA_2 = 40
result = metrics(C, LAMBDA_1, LAMBDA_2, MU, g)
print("\n--- Результаты --- 📊✨")
for n, p in enumerate(result["pn"]):
print(f"P(n={n}) = {p:.5f} 🎲")
print(f"Сумма вероятностей = {sum(result['pn']):.5f} ➕")
print(f"Вероятность блокировки (по времени) = {result['time_block']:.5f} ⏳🚫")
print(f"Среднее число заявок = {result['average_number']:.5f} 👥")
print(f"Вероятность блокировки по вызовам: B1 = {result['blocking_calls'][0]:.5f} 📞🚫, B2 = {result['blocking_calls'][1]:.5f} 📞🚫")
print(f"Вероятность блокировки по нагрузке: C1 = {result['blocking_load'][0]:.5f} 📦🚫, C2 = {result['blocking_load'][1]:.5f} 📦🚫")
print(f"Вероятность блокировки для заявок 1-го типа (E1) = {result['E1']:.5f}")
print(f"Вероятность блокировки для заявок 2-го типа (E2) = {result['E2']:.5f}")
# Диапазон для графиков
lam_1_range = np.arange(0.1, C, 0.5)
# Построение графиков
plot_blocking_two_types_vs_lambda(C, g, LAMBDA_2, MU, lam_1_range)
plot_average_number_vs_lambda(C, g, LAMBDA_2, MU, lam_1_range)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment