导入必要的库
import numpy as np
import pylab as plt
plt.rc('font',size = 16,family='Times New Roman')
plt.rc('axes',unicode_minus=False)
np.random.seed(0)
初始化参数
参考论文Joint task offloading, D2D pairing, and resource allocation in device-enhanced MEC: A potential game approach https://ieeexplore.ieee.org/abstract/document/9488278/
# Initialize simulation parameters
area_size = (200, 200) # Simulation area size in meters (200x200 m^2)
N = 20 # Number of computation-intensive users
H = 10 # Number of cooperative terminals
BS_height = 100 # BS height in meters
D2D_dist_limit = 50 # D2D communication distance limit in meters
Md = 3 # Number of D2D communication channels
Me = 4 # Number of cellular communication channels
B = 5e6 # Channel bandwidth in Hz (5MHz)
alpha = 4 # Path loss exponent
N0 = -174 # Background noise power spectral density in dBm
K_n = 1e-28 # Effective capacitance switching for each user
f_e = 20e9 # Edge cloud computing resources in CPU cycles/s
# Generate users and cooperative terminals randomly within the area
user_positions = np.random.rand(N, 2) * area_size*0.8
coop_positions = np.random.rand(H, 2) * area_size*0.8
# Initialize task characteristics for each user
D_n = np.random.uniform(0.2e6, 5e6, N) # Data size in bits (uniformly distributed between 0.2 and 5 Mbits)
tao_n = np.random.uniform(1500, 2000, N) # Required CPU cycles per bit (uniformly distributed between 1500 and 2000 cycles/bit)
# Initialize computing resources for each user and cooperative terminal
f_n = np.random.uniform(0.5e9, 2e9, N) # Computing resources for each user in CPU cycles/s
f_h = np.random.uniform(6e9, 10e9, H) # Computing resources for each cooperative terminal in CPU cycles/s
循环过程
对卸载比例进行从[0,1]步长为0.1循环,进行迭代,取距离最近的协同终端进行卸载或者MEC进行卸载,后续考虑一个动态的卸载过程,考虑资源分配,包括计算资源(主频),通信资源(带宽B),以及能耗资源(发射功率和本地主频)等的分配,考虑终端的移动性,将D2D虚拟化等,利用强化学习进行卸载等
result = []
t_total_list = []
e_total_list = []
u_nm_list=[]
for i in np.arange(11):
for j in np.arange(11-i):
# Assuming some random values for alpha_n_m(t) and mu_n_m(t) for each user
# alpha_n_m = np.random.uniform(0, 0.5, N) # D2D offloading ratio for each user
# mu_n_m = np.random.uniform(0, 0.5, N) # MEC offloading ratio for each user
alpha_n_m = i/10 # D2D offloading ratio for each user
mu_n_m = j/10 # MEC offloading ratio for each user
# Ensure that the sum of alpha_n_m, mu_n_m, and local computation ratio is <= 1
local_ratio = 1 - alpha_n_m - mu_n_m
# Calculate the local computation delay and energy consumption for each user
t_local = local_ratio * (tao_n*D_n / f_n)
# print('t_local=',t_local)
e_local = local_ratio * K_n * tao_n * D_n * (f_n ** 2)
distances = np.sqrt(np.sum((user_positions[:, np.newaxis, :] - coop_positions[np.newaxis, :, :]) ** 2, axis=2))
#coop_positions[np.newaxis, :, :] 的结果是将 coop_positions 的形状从 (H, 2) 变成了 (1, H, 2)。
# 这样,每个合作终端的坐标都位于一个单独的子数组中,并且在第一个维度上多了一个长度为1的维度。
# 这种改变是为了在之后的计算中能够与形状为 (N, 1, 2) 的数组进行逐元素操作,以便使用 NumPy 的广播规则
#distances 是一个矩阵,它的形状是 (N, H)
# Find the nearest cooperative terminal for each user
nearest_coop_idx = np.argmin(distances, axis=1)
nearest_coop_distances = distances[np.arange(N), nearest_coop_idx]
# Calculate the D2D offloading transmission rate (simplified, without considering interference for now)
N0_linear = 10 ** (N0 / 10) # Convert N0 from dBm to linear scale
P_n_d2d = 0.1
SNR = P_n_d2d * np.power(nearest_coop_distances,-4) / (N0_linear * B) # Signal-to-Noise Ratio (assuming unit power for simplicity)
R_d2d = B * np.log2(1 + SNR) # D2D transmission rate
# Calculate the D2D offloading transmission delay
t_off_d2d = (alpha_n_m * D_n) / R_d2d
# Calculate the D2D offloading computation delay (assuming all users offload to their nearest cooperative terminal)
f_nearest_coop = f_h[nearest_coop_idx]
t_d2d = (alpha_n_m * tao_n * D_n) / f_nearest_coop
# Calculate the D2D offloading energy consumption (assuming unit power for simplicity)
e_d2d = P_n_d2d*t_off_d2d # Energy is proportional to time when power is constant
# Show calculated D2D offloading parameters for the first 5 users
# Calculate the distances between users and the Edge Cloud/BS (located at the center of the area)
bs_position = np.array([area_size[0] / 2, area_size[1] / 2])
distances_to_bs = np.sqrt(np.sum((user_positions - bs_position) ** 2, axis=1))
# Calculate the MEC offloading transmission rate (simplified, without considering interference for now)
# Assuming path loss model: PL(d) = d ^ alpha
P_n_mec = 0.1
path_loss_to_bs = distances_to_bs ** alpha
SNR_mec = P_n_d2d * path_loss_to_bs / (N0_linear * B ) # Signal-to-Noise Ratio for MEC (assuming unit power for simplicity)
R_mec = B * np.log2(1 + SNR_mec) # MEC transmission rate
# Calculate the MEC offloading transmission delay
t_off_mec = (mu_n_m * D_n) / R_mec
# Calculate the MEC offloading computation delay (assuming equal sharing of edge resources among users)
u_mec = N # Number of users sharing the edge resources (for simplicity, assuming all users share equally)
t_mec = (mu_n_m * tao_n * D_n) / (f_e / u_mec)
# Calculate the MEC offloading energy consumption (assuming unit power for simplicity)
e_mec = P_n_d2d * t_off_mec # Energy is proportional to time when power is constant
beta1 = 0.5
beta2 = 0.5
# Calculate the total delay and energy consumption for each user
t_total = np.maximum(t_local,np.maximum(t_mec + t_off_mec,t_d2d + t_off_d2d )
e_total = e_mec + e_d2d + e_local
# Calculate the offloading gain for each user
z_nm = -(beta1 * t_total + beta2 * e_total)
l = ['d2d比例为',i/10,'mec比例为',j/10,'时延为',np.mean(t_total),
'能耗为',np.mean(e_total)]
result.append(l)
t_total_list.append((i/10,j/10,t_total))
e_total_list.append((i/10,j/10,e_total))
u_nm_list.append((i/10,j/10,z_nm))
画图
仅作为示例,后续考虑动态情况
plt.figure(1)
plt.plot(u_nm_list[0][2], label='computing locally')
plt.plot(u_nm_list[-1][2], label=f'd2d offloading')
plt.plot(u_nm_list[10][2], label=f'mec offloading')
plt.plot(u_nm_list[50][2], label=f'd2d ratio:{u_nm_list[50][0]}, mec ratio:{u_nm_list[50][1]}')
plt.legend()
plt.xlabel('compute-intensive user1~20')
plt.ylabel('Utility')
plt.show()
plt.figure(2)
plt.plot(t_total_list[0][2], label='computing locally')
plt.plot(t_total_list[-1][2], label=f'd2d offloading')
plt.plot(t_total_list[10][2], label=f'mec offloading')
plt.plot(t_total_list[50][2], label=f'd2d ratio:{t_total_list[50][0]}, mec ratio:{t_total_list[50][1]}')
plt.legend()
plt.xlabel('compute-intensive user1~20')
plt.ylabel('delay/s')
plt.show()
plt.figure(3)
plt.plot(e_total_list[0][2], label='computing locally')
plt.plot(e_total_list[-1][2], label=f'd2d offloading')
plt.plot(e_total_list[10][2], label=f'mec offloading')
plt.plot(e_total_list[50][2], label=f'd2d ratio:{e_total_list[50][0]}, mec ratio:{e_total_list[50][1]}')
plt.legend()
plt.xlabel('compute-intensive user1~20')
plt.ylabel('energy consumption')
plt.show()
根据以上代码,可以跑出20个计算密集型用户的卸载收益
学习中,请各位巨佬指教