Скачиваний:
0
Добавлен:
29.04.2025
Размер:
7.33 Кб
Скачать
import numpy as np
import matplotlib.pyplot as plt

# константы
R = 30  # радиус действия БС
Ptx = 0.1  #
f0 = 5600  # частота
df = 40  # частота пропускания канала
kn = 3  # этаж
T = 300  # температура (К)
K = 1.380649 * 10 ** -23  # постоянная Больцмана
Pn = df * T * K * kn * 10 ** 6  # мощность теплового шума
K = 29  # коэффициент типа помещения ?


# график расположения абонентов
def plot_ab(subs):
    angles = [s['angle'] for s in subs]
    distances = [s['distance'] for s in subs]
    fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
    ax.scatter(angles, distances)
    ax.set_title(f'Расположение {len(subs)} абонентов')
    plt.show()


# генерация абонентов и расчёт пропускных способностей
def generate_ab(n):
    subs = []
    for _ in range(n):
        angle = 2 * np.pi * np.random.rand()  # случ. угол
        distance = R * np.sqrt(np.random.rand())  # расстояние от БС до АБ
        x, y = distance * np.cos(angle), distance * np.sin(angle)  # полярные координаты АБ
        L_dB = 20 * np.log10(f0) + K * np.log10(distance) - 28  # потери мощности в дБ
        L = 10 ** (L_dB / 10)  # перевод потерь в разы
        Prx = Ptx / L  # принятая мощность сигнала
        SNR = Prx / Pn  # отношение сигнал / шум
        CC = df * np.log2(1 + SNR)  # пропускная способность
        subs.append({'x': x, 'y': y, 'angle': angle, 'distance': distance, 'CC': CC})  # добавление АБ
    return subs


# равные скорости
def equal_blind(CC_list):
    D = 1 / sum(1 / c for c in CC_list)
    return {'algorithm': 'Equal Blind', 'minD': D, 'meanD': D, 'sumD': D * len(CC_list)}


# максимальная суммарная скорость
def maximum_throughput(CC_list):
    max_CC = max(CC_list)
    active_count = CC_list.count(max_CC)
    D_list = [(c if c == max_CC else 0) / active_count for c in CC_list]
    return {'algorithm': 'Maximum Throughput', 'minD': min(D_list), 'meanD': sum(D_list) / len(D_list),
            'sumD': sum(D_list)}


# равные нагрузки
def proportion_fair(CC_list):
    D_list = [c / len(CC_list) for c in CC_list]
    return {'algorithm': 'Proportion Fair', 'minD': min(D_list), 'meanD': sum(D_list) / len(D_list),
            'sumD': sum(D_list)}


# прогон алгоритмов
def modulate(n_ab, tests):
    results = {}
    # перебор N АБ
    for n in n_ab:

        calculations = {'Equal Blind': [], 'Maximum Throughput': [], 'Proportion Fair': []}

        # 100 прогонов
        for _ in range(tests):
            subs = generate_ab(n)  # генерация n АБ
            CC_list = [s['CC'] for s in subs]  # получение пропускных спос. для АБ
            # перебор алгоритмов
            for algo_func in [equal_blind, maximum_throughput, proportion_fair]:
                # вычисление оценок
                result = algo_func(CC_list)
                calculations[result['algorithm']].append(result)  # под именем алг. записаны результаты

        # вычисление средних оценок для 100 прогонов
        for algo_name in calculations:
            avg = average_val(calculations[algo_name])
            # пустой массив для результатов ср. оценок для каждого алгоритма
            if algo_name not in results:
                results[algo_name] = {'count': [], 'minD': [], 'meanD': [], 'sumD': []}
            # запись результатов
            results[algo_name]['count'].append(n)
            results[algo_name]['minD'].append(avg['minD'])
            results[algo_name]['meanD'].append(avg['meanD'])
            results[algo_name]['sumD'].append(avg['sumD'])

    return results


# вычисление средних значений
def average_val(list_of_dicts):
    keys = ['minD', 'meanD', 'sumD']
    result = {}

    # перебор оценок
    for key in keys:
        total = 0
        # перебор вычислений
        for d in list_of_dicts:
            # суммирование
            total += d[key]
        # вычисление ср. значения
        result[key] = total / len(list_of_dicts)

    return result


# построение графиков оценок
def plot_results(results):
    fig, axs = plt.subplots(1, 3, figsize=(15, 5))  # три графика в ряд
    rating = ['minD', 'meanD', 'sumD']  # вар. оценок
    # названия
    titles = ['Средняя минимальная скорость от числа АБ', 'Средняя скорость от числа АБ',
              'Средняя суммарная скорость от числа АБ']

    # перебор вар. оценок
    for i, r in enumerate(rating):
        # перебор алгоритмов
        for algo_name, data in results.items():
            # построение оценок алгоритма
            axs[i].plot(data['count'], data[r], label=algo_name)
        axs[i].set_title(titles[i])
        axs[i].set_xlabel('Количество абонентов')
        axs[i].set_ylabel('Скорость передачи')
        axs[i].legend()
        axs[i].grid(True)  # сетка
    plt.tight_layout()
    plt.show()


# построение гистограммы и эмпирической функции распределения положения абонентов
def plot_ab_histogram(subs):
    # углы расположения АБ
    angles = [s['angle'] for s in subs]
    # построение гистограммы распределения
    plt.figure(figsize=(10, 5))
    plt.subplot(1, 2, 1)
    plt.hist(angles, bins=30, range=(0, 2 * np.pi), edgecolor='black')
    plt.title('Гистограмма распределения абонентов')
    plt.xlabel('Угол (радианы)')
    plt.ylabel('Плотность вероятности')

    # построение эмпирической функции распределения
    plt.subplot(1, 2, 2)
    sorted_angles = np.sort(angles)
    y_vals = np.arange(1, len(angles) + 1) / len(angles)
    plt.step(sorted_angles, y_vals, where='post', color='b')
    plt.title('Эмпирическая функция распределения')
    plt.xlabel('Угол (радианы)')
    plt.tight_layout()
    plt.show()


def main():
    # генерация 10 000 Аб для демонстрации распределения
    subs = generate_ab(5000)
    plot_ab_histogram(subs)

    # генерация N АБ по 100 прогонов и вычисление оценок
    n_ab = [2 ** i for i in range(0, 7)]
    results = modulate(n_ab, 100)

    # пример распределения АБ в радиусе БС
    plot_ab(subs)

    # графики оценок
    plot_results(results)


main()
Соседние файлы в предмете Моделирование систем распределения ресурсов