Скачиваний:
7
Добавлен:
25.06.2023
Размер:
13.82 Кб
Скачать
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):
    '''Генерация списка расположения абоненских станций'''
    distans = np.sqrt(np.random.uniform(0, R ** 2, N))
    angle = np.random.uniform(0, 2 * np.pi, N)
    x = distans * np.cos(angle)
    y = distans * np.sin(angle)
    return pd.DataFrame(data={'distans' : distans, 'angle' : angle, 'x' : x, 'y' : y})


def buffer_increase(data, add_data):
    '''Добавление пакетов в буффер'''
    for idx, val in enumerate(add_data):
        data.at[idx, 'buffer'] = data.iloc[idx]['buffer'] + val
    return data



def get_ITU_sent_data_size(f0, R, Ptx, DF, Pn, T_rb):
    '''Вычисление размера сообщения передоваемого АБ'''
    # Модель UTI
    L = 10 ** ((20 * np.log10(f0) + 29 * np.log10(R) + 0 - 28 + np.random.normal(0, 1)) / 10)
    Prx = Ptx / L  # расчёт мощности
    SNR = Prx / Pn  # сигнал/шум
    C = DF * np.log2(SNR)  # макс пропускспособность канала связи
    return C * T_rb

def get_Okamura_Hata_sent_data_size(f0, h_rx, h_bs, distans, Ptx, Pn, f, T_rb, S=0):
    # Модель Окамура-Хата
    # Уровень потерь 
    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)
    С = f * np.log2(1 + SNR)
    return С * T_rb  # Макс. пропускная способность канала связи (Сhannel Сapacity)



def plot_buffer_grade(buffer_grade):
    '''Построение графиков измеренных величин'''
    buffer_grade = buffer_grade.reset_index(['N', 'Lambda'])
    groups = buffer_grade.groupby('N')

    for n, g in groups:
        plt.plot(g['Lambda'], g['buffer_sum'], label=f'Number User {n}')
    # plt.title('Заголовок графика')
    plt.xlabel('Интенсивность входного потока, пакет/сек')
    plt.ylabel('Средний объем данных находящийся в буфере, бит')
    plt.ticklabel_format(style='plain')
    plt.grid()
    plt.legend()
    plt.show()
    return 0



def main():
    # Параметры варианта
    # ===============================================
    # Общие пораметры моделий
    T = 300                 # Абсолютная температура
    subs_list = [2, 4, 8, 16]#[8, 16, 64] # Список кол-ва АБ
    lambd_step = 5          # Шаг изменения 
    lambd_start = 1
    lambd_end = 101
    T_rb = 5 * 10**-4       # Длительность слота
    slot_cnt = 10**3        # Кол-во моделируемых слотов
    V = 1 * 1024 * 8        # Объем данных содержащихся в одном пакете равеный 1 кбайт
    # ===============================================
    # -----------------------------------------------
    # Параметры варианта
    # -----------------------------------------------
    # ITU, commercial area
    R = 40      # Радиус
    Ptx = 0.05  # Мощность излучения БС
    f0 = 4000   # Частота БС
    kn = 4      # Коэф. теплового шума приёмника

    DF = 180 * 10**6        # Полоса пропускания канала связи
    k = 1.38 * 10**-23      # Постоянная Больцмана
    Pn = DF * T * k * kn    # Мощность теплового шума
    # -----------------------------------------------
    # Окумура-Хата
    # 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    # Мощность теплового шума
    # -----------------------------------------------

    # Датафрейм для сбора оценок работы модели
    buffer_grade = pd.DataFrame(columns=['N', 'Lambda', 'buffer_sum'])


    # graph_location_subs_stations(subs_generator(40, 64))


    # Цикл по кол-ву АБ
    for subs_cnt in subs_list:

        # Генерация расположения АБ
        subs = subs_generator(R, subs_cnt)
        subs['buffer'] = 0      # Добавления столбца пустого буфера
        print(subs)

        for lambd in range(lambd_start, lambd_end, lambd_step):
            print('subs_cnt', subs_cnt, 'lambd', lambd)
            # Параметр геометрического распределения
            prob = 1 / (lambd * T_rb + 1)

            # Цикл по слотам
            for slot_num in range(slot_cnt):
                
                # Герерация посткпающих пакетов информации
                buffer_add_data = [(np.random.geometric(prob) - 1) * V for _ in range(subs_cnt)]
                # print('buffer_add_data', buffer_add_data)
                # Передача данных абаненту из буфера
                if slot_num != 0:
                    sub_slot_idx = slot_num % subs_cnt      # Индекс АБ, которому выделен слот

                    temp_buffer = subs.iloc[sub_slot_idx]['buffer']
                    sent_data = get_ITU_sent_data_size(f0, subs.iloc[sub_slot_idx]['distans'], Ptx, DF, Pn, T_rb)                      # Модель ITU
                    # sent_data = get_Okamura_Hata_sent_data_size(f0, h_rx, h_bs, subs.iloc[sub_slot_idx]['distans'], Ptx, Pn, f, T_rb)    # Модель Окумура-Хата
                    # print('sent_data', sent_data)


                    subs.at[sub_slot_idx, 'buffer'] = 0 if temp_buffer <= sent_data else temp_buffer - sent_data

                # Запись данных в буфер
                for idx, val in enumerate(buffer_add_data):
                    subs.at[idx, 'buffer'] = subs.iloc[idx]['buffer'] + val
                
                # Запись состаяния буфера в датафрейм
                buffer_grade = pd.concat([buffer_grade, pd.Series({'N' : subs_cnt, 'Lambda' : lambd, 'buffer_sum' : subs['buffer'].sum()}).to_frame().T], ignore_index=True)
                
    
    buffer_grade.set_index(['N', 'Lambda'], inplace=True)
    buffer_grade = buffer_grade.groupby(level=['N', 'Lambda']).mean()
    # print(buffer_grade)

    plot_buffer_grade(buffer_grade)
    return 0


def main1():
    # Параметры варианта
    # ===============================================
    # Общие пораметры моделий
    T = 300                 # Абсолютная температура
    subs_list = [2,16]#[8, 16, 64] # Список кол-ва АБ
    lambd_step = 5          # Шаг изменения 
    lambd_start = 1
    lambd_end = 101
    T_rb = 5 * 10**-4       # Длительность слота
    slot_cnt = 10**3        # Кол-во моделируемых слотов
    V = 1 * 1024 * 8        # Объем данных содержащихся в одном пакете равеный 1 кбайт
    # ===============================================
    # -----------------------------------------------
    # Параметры варианта
    # -----------------------------------------------
    # ITU, commercial area
    R = 40      # Радиус
    Ptx = 0.05  # Мощность излучения БС
    f0 = 4000   # Частота БС
    kn = 4      # Коэф. теплового шума приёмника

    DF = 180 * 10**3        # Полоса пропускания канала связи
    k = 1.38 * 10**-23      # Постоянная Больцмана
    Pn = DF * T * k * kn    # Мощность теплового шума
    # -----------------------------------------------
    # Окумура-Хата
    # 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    # Мощность теплового шума
    # -----------------------------------------------

    # Датафрейм для сбора оценок работы модели
    buffer_grade = pd.DataFrame(columns=['N', 'Lambda', 'buffer_sum'])


    # graph_location_subs_stations(subs_generator(40, 64))


    # Цикл по кол-ву АБ
    for subs_cnt in subs_list:

        # Генерация расположения АБ
        subs = subs_generator(R, subs_cnt)
        subs['buffer'] = 0      # Добавления столбца пустого буфера
        print(subs)

        for lambd in range(lambd_start, lambd_end, lambd_step):
            print('subs_cnt', subs_cnt, 'lambd', lambd)
            # Параметр геометрического распределения
            prob = 1 / (lambd * T_rb + 1)

            # Индекс текущего АБ
            currently_user = 0

            # Цикл по слотам
            for slot_num in range(slot_cnt):
                
                # Герерация посткпающих пакетов информации
                buffer_add_data = [(np.random.geometric(prob) - 1) * V for _ in range(subs_cnt)]
                # print('buffer_add_data', buffer_add_data)
                # Передача данных абаненту из буфера
                if slot_num != 0:

                    # print('\t\t', [i % subs_cnt for i in range(currently_user, currently_user + subs_cnt) if subs.iloc[i % subs_cnt]['buffer'] != 0])
                    # print('subs["buffer"]\t', subs['buffer'].to_list())
                    # print('buffer_add_data\t', buffer_add_data)
                    # print('currently_user\t', currently_user)
                    # print()

                    # Присок АБ с заполненным буфером
                    user_with_full_buffer = [i % subs_cnt for i in range(currently_user, currently_user + subs_cnt) if subs.iloc[i % subs_cnt]['buffer'] != 0]

                    if user_with_full_buffer:
                        # Прем первого
                        sub_slot_idx = user_with_full_buffer[0]

                        # Берем размер буфера для выбранного Аб
                        temp_buffer = subs.iloc[sub_slot_idx]['buffer']

                        # Расчет объема передаваемого сообщения АБ
                        sent_data = get_ITU_sent_data_size(f0, subs.iloc[sub_slot_idx]['distans'], Ptx, DF, Pn, T_rb)                      # Модель ITU
                        # sent_data = get_Okamura_Hata_sent_data_size(f0, h_rx, h_bs, subs.iloc[sub_slot_idx]['distans'], Ptx, Pn, f, T_rb)    # Модель Окумура-Хата
                        # print('sent_data', sent_data)

                        # Передача информации из буфера базовой станции абоненту
                        subs.at[sub_slot_idx, 'buffer'] = 0 if temp_buffer <= sent_data else temp_buffer - sent_data
                        
                        # обновлениие текущего Аб
                        currently_user = (sub_slot_idx + 1)  % subs_cnt

                buffer_grade = pd.concat([buffer_grade, pd.Series({'N' : subs_cnt, 'Lambda' : lambd, 'buffer_sum' : subs['buffer'].sum()}).to_frame().T], ignore_index=True)   

                # Запись данных в буфер
                for idx, val in enumerate(buffer_add_data):
                    subs.at[idx, 'buffer'] = subs.iloc[idx]['buffer'] + val
                
                # Запись состаяния буфера в датафрейм
                
                
    
    buffer_grade.set_index(['N', 'Lambda'], inplace=True)
    buffer_grade = buffer_grade.groupby(level=['N', 'Lambda']).mean()
    # print(buffer_grade)

    plot_buffer_grade(buffer_grade)
    return 0



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