Скачиваний:
8
Добавлен:
25.06.2023
Размер:
7.55 Кб
Скачать
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt



def graph_location_subs_stations(subs_data):
    '''Построение графика расположения станиций'''
    fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
    ax.scatter(subs_data['angle'], subs_data['distans'])
    ax.set_rmax(2.1)
    plt.title(f'Распредление {len(subs_data)} абонентов', )
    plt.show()
    return 0


def subs_generator(R, n, Ptx, Pn, f, f0, h_bs, h_rx, S = 0):
    '''Генерация списка расположения абоненских станций'''
    subs = pd.DataFrame(columns=['distans', 'angle', 'x', 'y', 'CC'])
    for _ in range(n):
        distans = np.sqrt(R**2 * np.random.random())    # Дистанция от абоненцкой до базовой станции
        angle = 2 * np.pi * np.random.random()          # Угол координат
        # Перевод в декартову систему координат
        x = distans * np.cos(angle)             
        y = distans * np.sin(angle)
        
        # Уровень потерь
        a = (1.1 * np.log10(f0) - 0.7) * h_rx - (1.56 * np.log10(f0) - 0.8)
        L = 46.3 + 33.9 * np.log10(f0) - 13.82 * np.log10(h_bs) - a + (44.9 - 6.55 * np.log10(h_rx)) * np.log10(distans) + S
        L = 10**(L/10)

        Prx = Ptx/L                 # Мощьность сигнала
        SNR = Prx/Pn                # Отношение сигнал/шум (SNR)
        CC = f * np.log2(1 + SNR)   # Макс. пропускная способность канала связи (Сhannel Сapacity)

        subs = pd.concat([subs, pd.Series({'distans': distans, 'angle': angle, 'x': x, 'y': y, 'CC': CC}).to_frame().T], ignore_index=True)
    return subs



def equal_blind(CC):
    '''Алгоритм ПРС - Равные скорости абонентам'''
    D = sum([c**-1 for c in CC])**-1    # Cкорость передачи для абонента

    return pd.Series({'algorithm': 'Equal Blind', 'count': len(CC),
            'minD': D, 'meanD': D, 'sumD': D*len(CC)}).to_frame().T


def maximum_throughput(CC):
    '''Алгоритм ПСС - Максимальная суммарная скорость передачи данных'''
    equal_max = np.array(CC) == max(CC)
    # Суммарная скорость передачи
    D = [1/sum(equal_max) * c * equal_max[i] for i, c in enumerate(CC)]

    return pd.Series({'algorithm': 'Maximum Throughput', 'count': len(CC),
            'minD': min(D), 'meanD': np.mean(D), 'sumD': sum(D)}).to_frame().T


def proportion_fair(CC):
    '''Алгоритм ПРД - Равные доли выделенных ресурсов'''
    D = [cc/len(CC) for cc in CC]       # Суммарная скорость передачи

    return pd.Series({'algorithm': 'Proportion Fair', 'count': len(CC),
            'minD': min(D), 'meanD': np.mean(D), 'sumD': sum(D)}).to_frame().T



def plot_M_gradeD(D_grade):
    '''Построение графиков измеренных величин'''
    fig, axs = plt.subplots(1, 3)
    fig.suptitle('Графики зависимости оценок')

    x_axis = 'count'
    y_axis = ['minD', 'meanD', 'sumD']
    x_lable = 'Кол-во абонентов'
    y_lable = ['МО мин. скорости передачи', 'МО средней скорости передачи', 'МО макс. скорости передачи']
    D_grade = D_grade.reset_index(level=['algorithm', 'count'])
    groups = D_grade.groupby('algorithm')

    for idx in range(3):
        for n, g in groups:
            axs[idx].plot(g[x_axis], g[y_axis[idx]], label=n)
        axs[idx].set_xlabel(x_lable)
        axs[idx].set_ylabel(y_lable[idx])
        axs[idx].set_title(f'M[{y_axis[idx]}]')
        axs[idx].legend()
        axs[idx].grid(True)
    plt.show()
    return 0


def get_M_gradeD(R, Ptx, Pn, f, f0, h_bs, h_rx, N_test=100, N_subs_pow2=6, isPrintLocGraph=False):
    '''Определение мат ожидания для суммарной скорости передачи'''
    # Таблица результатов измерений
    D_grade = pd.DataFrame(columns=['algorithm', 'count', 'minD', 'meanD', 'sumD'])
    for n in [2**i  for i in range(N_subs_pow2+1)]:     # Кол-во абонентов (1,2,4,8,16...)
        for _ in range(N_test):
            subs = subs_generator(R, n, Ptx, Pn, f, f0, h_bs, h_rx)
            D_grade = pd.concat([D_grade,        equal_blind(subs['CC'])], ignore_index=True)
            D_grade = pd.concat([D_grade, maximum_throughput(subs['CC'])], ignore_index=True)
            D_grade = pd.concat([D_grade,    proportion_fair(subs['CC'])], ignore_index=True)

    if isPrintLocGraph: graph_location_subs_stations(subs)

    D_grade.set_index(['algorithm', 'count'], inplace=True)
    D_grade = D_grade.groupby(level=['algorithm', 'count']).mean()
    plot_M_gradeD(D_grade)
    return D_grade



def extra(R, Ptx, Pn, f, f0, h_bs, h_rx, N_test=100, N_subs_pow2=6):
    '''Построение графика зависимости среднего минимального расстояния от БС до Аб и кол-ва абонентов'''
    # Таблица результатов измерений
    Data = pd.DataFrame(columns=['users_count', 'min_distans'])
    for n in [2**i  for i in range(N_subs_pow2+1)]:     # Кол-во абонентов (1,2,4,8,16...)
        print(n)
        for _ in range(N_test):
            subs = subs_generator(R, n, Ptx, Pn, f, f0, h_bs, h_rx)
            Data = pd.concat([Data, pd.Series({'users_count': n, 'min_distans': min(subs['distans'])}).to_frame().T], ignore_index=True)

    Data.set_index(['users_count'], inplace=True)
    Data = Data.groupby(level=['users_count']).mean()
    print(Data)
    Data = Data.reset_index()
    plt.plot(Data['users_count'], Data['min_distans'])
    plt.title('Графики зависимости среднего мин. расстояния АБ от БД\nв зависимости от кол-ва абонентов')
    plt.xlabel('Кол-во абонентов')
    plt.ylabel('Сред. мин. раст. (км)')
    plt.show()
    return 0


def main():
	# Параметры варианта
    R = 2    # Радиус
    Ptx = 40    # Мощность излучения БС
    f0 = 900    # Частота БС
    f = 3       # Полоса пропускания канала связи
    kn = 4      # Коэф. теплового шума приёмника
    T = 300     # Абсолютная температура
    h_bs = 100  # Высота БС
    h_rx = 5    # Высота точки приема
    Pn = f * 10**6 * T * 1.38 * 10**-23 * kn    # Мощность теплового шума
    # ------------------

    D_grade = get_M_gradeD(R, Ptx, Pn, f, f0, h_bs, h_rx, N_test=100, N_subs_pow2=6, isPrintLocGraph=True)
    print(D_grade)

    # ------------------
    # Доп. задание
    # Построить график зависимости среднего минимального расстояния от БС до Аб и кол-ва абонентов
    extra(R, Ptx, Pn, f, f0, h_bs, h_rx, N_test=100, N_subs_pow2=6)

    return 0

if __name__ == "__main__":
	main()
    
Соседние файлы в папке ЛР1