
Добавил:
SleepyOwl703
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:lab3
.pyimport numpy as np
from matplotlib import pyplot as plt
# константы
R = 300 # радиус действия БС
Ptx = 0.1 #
f0 = 4000 # частота
df = 180 * 10**3 # частота пропускания канала
kn = 3 # коэффициент теплового шума
T = 300 # температура (К)
K = 1.380649 * 10 ** -23 # постоянная Больцмана
Pn = df * T * K * kn # мощность теплового шума
SLOTS = 10**3 # количество слотов
K_ITU = 29 # коэффициент типа помещения ?
subs_list = [2,4,8,16] # [8, 16, 64], # Список кол-ва АБ
algoritm_list = ['Maximum Throughput', 'Equal Blind', 'Proportional fair'] # названия алгоритмов рр
T_rb = 0.5 * (10 ** -3) # длительность слота
y = 1 # последняя секунда
y_slot = round(y / T_rb) # кол-во слотов, на которых рассчитывается ср скорость
Nrb = 100 # кол-во ресурсных блоков
V = 2**13 # объем данных в пакете (1Кб)
lambd_list = np.arange(1, 10, 1) # значения интенсивности входного потока
buffer_scores_by_alg = {}
def generate_ab(n, lam):
# Генерация случайных расстояний пользователей до базовой станции
dist = np.sqrt(np.random.uniform(0, R**2, n))
L_list = 10 ** ((20 * np.log10(f0) + K_ITU * np.log10(dist) - 28) / 10)
subs = []
packs = []
for L in L_list:
# помеха
fading_dB = np.random.normal(loc=0, scale=1, size=SLOTS)
# Суммарное затухание в дБ
total_loss_dB = 10 * np.log10(L) + fading_dB # L уже в линейной шкале
# Перевод в линейную шкалу: L_total = 10^(total_dB / 10)
L_total = 10 ** (total_loss_dB / 10)
# Мощность на приёме (в линейной шкале)
Prx = Ptx / L_total
SNR = Prx / Pn
CC = df * np.log2(1 + SNR)
subs.append(list(CC * T_rb))
# Генерация количества пакетов
user_packs = [(np.random.poisson(lam=lam)) * V for _ in range(SLOTS)]
packs.append(user_packs)
return subs, packs
def get_avg_R(slot_resource_blocks, subs, sub_idx, slot_idx):
packs_sum = 0
for i in range(max(0, slot_idx - 1 - y_slot), slot_idx):
sub_slot_res_block_cnt = slot_resource_blocks[i].count(sub_idx)
packs_sum += subs[sub_idx][i] * sub_slot_res_block_cnt
return packs_sum / y_slot
def get_avg_R_smooth(slot_resource_blocks, subs, sub_idx, slot_idx, sub_R_mean_list):
betta = 1 / y_slot
return (1 - betta) * sub_R_mean_list[sub_idx] + betta * sum(
[subs[sub_idx][slot_idx] for res_sub_idx in slot_resource_blocks[-1] if res_sub_idx == sub_idx]) / T_rb
# сортировка аб по приоритетам
def filter_and_sort(priorities, sub_with_full_buffer):
sorted_indices = np.argsort(priorities)
return [idx for idx in sorted_indices if idx in sub_with_full_buffer]
# Equal blind
def equal_blind(sub_R_mean_list, sub_with_full_buffer):
priorities = [1 / r if r > 0 else 1 for r in sub_R_mean_list]
return filter_and_sort(priorities, sub_with_full_buffer)
# Maximum throughput
def maximum_throughput(subs_slot_CC, sub_with_full_buffer):
return filter_and_sort(subs_slot_CC, sub_with_full_buffer)
# Proportional fair
def proportional_fair(subs_slot_CC, sub_R_mean_list, sub_with_full_buffer):
priorities = [cc / (rm if rm > 0 else 1) for cc, rm in zip(subs_slot_CC, sub_R_mean_list)]
return filter_and_sort(priorities, sub_with_full_buffer)
# получаем индекс абонента, котором передаем данные в зависимости от алгоритма распределения
def get_sub_index(subs_slot_CC, algorithm, sub_with_full_buffer, sub_R_mean_list):
match algorithm:
case 'Equal Blind':
return equal_blind(sub_R_mean_list, sub_with_full_buffer)
case 'Maximum Throughput':
return maximum_throughput(subs_slot_CC, sub_with_full_buffer)
case 'Proportional fair':
return proportional_fair(subs_slot_CC, sub_R_mean_list, sub_with_full_buffer)
return 0
def get_avg_score(subs, packs, algorithm):
subs_cnt = len(subs)
buffer = [[packs[i][0] for i in range(subs_cnt)]] # начальное число пакетов в буфере
slot_resource_blocks = [[]] # ресурсные блоки
sub_R_mean_list = [[get_avg_R(slot_resource_blocks, subs, i, 0) for i in range(subs_cnt)]] # ср зн скорости передачи для первого слота
cur_sub_idx = 0
# перебор слотов
for slot_idx in range(SLOTS):
# распределение нагрузки
if algorithm in ['Equal Blind', 'Proportional fair']:
sub_R_mean_list.append([
get_avg_R_smooth(slot_resource_blocks, subs, i, slot_idx, sub_R_mean_list[-1])
for i in range(subs_cnt)])
# Список абонентов, у которых буфер в текущем слоте не пустой
sub_with_full_buffer = [i % subs_cnt for i in range(cur_sub_idx, cur_sub_idx + subs_cnt)
if buffer[-1][i % subs_cnt] != 0]
# установление приоритета
cur_sub_idx = (cur_sub_idx + 1) % subs_cnt
# оставшиеся данные копируем в следующий слот
buffer.append(buffer[-1].copy())
# получение очереди аб, по приоритету
if sub_with_full_buffer:
subs_priority_idx = get_sub_index([subs[i][slot_idx] for i in range(subs_cnt)], algorithm,sub_with_full_buffer, sub_R_mean_list[-1])
new_slot_res_block = []
# print(f'Алг = {algorithm} Приоритет = {subs_priority_idx}')
# перебор аб
for sub_idx in subs_priority_idx:
# выделение ресурсных блоков
sub_res_block_cnt = int(np.ceil(buffer[-1][sub_idx] / subs[sub_idx][slot_idx]))
new_slot_res_block.extend([sub_idx] * sub_res_block_cnt)
if len(new_slot_res_block) >= Nrb: # ресурсные блоки кончились (всего 100)
break
slot_resource_blocks.append(new_slot_res_block[:Nrb])
# передача данных приоритетам
for sub_idx in [i for i in slot_resource_blocks[-1] if i != -1]:
buffer[-1][sub_idx] = max(0, buffer[-1][sub_idx] - subs[sub_idx][slot_idx])
else:
slot_resource_blocks.append([]) # нечего передавать
buffer[-1] = [buf + packs[i][slot_idx] for i, buf in enumerate(buffer[-1])]
return np.mean([sum(slot) for slot in buffer]) # средний суммарный объем
def modeling():
plt.figure(figsize=(12, 6))
for subs_cnt in subs_list:
for lambd in lambd_list:
subs, packs = generate_ab(subs_cnt, lambd)
for alg in algoritm_list:
score = get_avg_score(subs, packs, alg)
key = f'{subs_cnt} {alg}'
if lambd == lambd_list[0]:
buffer_scores_by_alg[key] = []
buffer_scores_by_alg[key].append(score)
print(f'lam : {lambd}, метод :{alg}, абонентов : {subs_cnt}, V : {score}')
# Отрисовка графиков
for key, buffer_scores in buffer_scores_by_alg.items():
plt.plot(lambd_list, buffer_scores, marker='o', label=key)
plt.title(f"Зависимость среднего объёма данных в буферах от интенсивности потока (SLOTS={SLOTS})")
plt.xlabel("Интенсивность входного потока (λ)")
plt.ylabel("Средний суммарный объём в буферах")
plt.legend()
plt.grid()
plt.show()
modeling()
Соседние файлы в предмете Моделирование систем распределения ресурсов