Скачиваний:
1
Добавлен:
08.07.2024
Размер:
6.94 Кб
Скачать
import math
import numpy as np
import random
import matplotlib.pyplot as plt
from tabulate import tabulate

# Эрланговское распределение
def erlang_distribution(order, lam):
    sum_uniform = 0
    for j in range(0, order):
        R = random.uniform(0.0, 1.0)
        sum_uniform += math.log(R)
    return (-1 * sum_uniform) / (lam * order)


# Равномерное распределение
def uniform_distribution(a, b):
    R = random.uniform(0.0, 1.0)
    return R * (b - a) + a


# Пуассоновский закон
def poisson_distribution(lam):
    R = random.uniform(0.0, 1.0)
    return (-1 * math.log(R)) / lam

# Функция для моделирования ЭСМО
def modeling(order, lam, a, b, condition: bool):
    # Количество заявок поступивших / обслуженных / в буфере к данному моменту в СМО, системное время, статус занятости ОУ
    n, k, m, t_system, zan = 0, 0, 0, 0, 0
    # Моменты поступления заявок
    t_request_list = np.array([])
    # Моменты обслуживания заявок
    t_release_list = np.array([])
    # Старая оценка среднего времени пребывания запроса
    T_old = 1000000
    counter_N = 0
    # Формирование случайного момента поступления заявки
    t_request = poisson_distribution(lam) if condition else erlang_distribution(order, lam)
    t_release = t_request
    while True:
        # Счетчик объема выборки
        counter_N += 1
        # Проверяем наступило ли время освобождения ОУ
        if t_request <= t_release:
            t_system = t_request
            n += 1
            # Добавляем момент поступления заявки
            t_request_list = np.append(t_request_list, t_system)
            if zan == 0:
                zan = 1
                t_release = t_system + uniform_distribution(a, b)
            else:
                m += 1
            # Следующий момент поступления заявки
            t_request = t_system + (poisson_distribution(lam) if condition else erlang_distribution(order, lam))
        else:
            # Записываем в системное время момент освобождения ОУ
            t_system = t_release
            # Увеличиваем счетчик обслуженных заявок
            k += 1
            # Добавляем в список момент освобождения ОУ
            t_release_list = np.append(t_release_list, t_system)
            if m > 0:
                m -= 1
                t_release = t_system + uniform_distribution(a, b)
            else:
                zan = 0
                t_release = t_request
        if counter_N % 100 == 0:
            T_new = np.mean(t_release_list - t_request_list[:len(t_release_list)])
            if (np.abs((T_new - T_old) / T_old)) < 0.01:
                return T_new
            T_old = T_new

# Функция для построения графиков
def modeling_experimental(order, nu_0, condition: bool):
    # Генерация списка значений интенсивности входного потока
    lam = np.linspace(0.1, 1, 10) * nu_0
    # Расчет границ для равномерного распределения
    b = 1 / nu_0 + 0.05 * nu_0
    a = b - 0.1 * nu_0
    # Среднее время пребывания запроса
    T_experiment = np.array([])
    for i in lam:
        T_experiment = np.append(T_experiment, modeling(order, i, a, b, condition))
    print('Значения среднего времени Т пребывания запроса:', T_experiment)
    # Расчет теор. значения
    if condition:
        # График эрланговского распределения
        x = np.linspace(0, 10, 200)
        lmbda = np.mean(lam)
        plt.plot(x, (((lmbda ** order) * (x ** (order - 1)) * np.exp(-lmbda * x)) / math.factorial(order - 1)),
                 lw=2, alpha=0.7, color='blue', label='k={}, lambda={}'.format(order, lmbda))
        plt.title('График плотности Эрланговского распределения')
        plt.grid()
        plt.legend()
        plt.show()
        # График равномерного распределения
        x = np.linspace(a, b, 100)
        plt.plot(x, [1 / (b - a)] * 100, lw=2, alpha=0.7, color='blue', label='a={}, b={}'.format(a, b))
        plt.title('График плотности равномерного распределения')
        plt.grid()
        plt.legend()
        plt.show()

        # Расчет коэффициента вариации равномерного распределения
        v = ((b - a) * math.sqrt(3) / 6) / ((a + b) / 2)
        # Расчет коэффициента загрузки системы
        p = lam[:9] / nu_0
        # Расчет среднего числа запросов в системе
        L = (p ** 2 * (1 + v ** 2)) / (2 * (1 - p)) + p
        # Расчет среднего времени пребывания запроса в системе
        T_theory = L / lam[:9]
        # Построение графика теоритически расчитанного значения
        plt.plot(lam[:9], T_theory, label='Теоретическое значение', color='orange')
    else:
        # Матрица результатов моделирования
        results_evaluation = np.empty((11, 2), dtype='object')
        results_evaluation[0] = ['Интенсивность входного потока', 'Среднее время пребывания запроса']
        results_evaluation[1:, 0] = np.transpose(lam)
        results_evaluation[1:, 1] = np.transpose(T_experiment)
        print(tabulate(results_evaluation))

    # Построение графика экспериментально полученного значения
    plt.plot(lam[:9], T_experiment[:9], label='Рассчитанное значение', color='black')
    plt.title('Зависимость среднего времени пребывания запроса от интенсивности входного потока')
    plt.ylabel('Среднее временя Т пребывания запроса')
    plt.xlabel('Инт. входного потока')
    plt.grid()
    plt.legend()
    plt.show()
    return T_experiment


modeling_experimental(5, 4, True)
modeling_experimental(5, 4, False)
Соседние файлы в папке ЛР 4