梯度下降算法出的结果不对
RunModel.py
import numpy as np
from SystemModel import System_Model
from Environment import NumberOfUAVs,NumberOfUsers,F_c,learning_rate,num_iterations
def main():
env = System_Model()
Distance_U2K = env.Get_Distance_U2K(env.PositionOfUAVs, env.PositionOfUsers, NumberOfUAVs, NumberOfUsers)
print("-------UAV和User的距离--------")
print(Distance_U2K)
service_quality = env.evaluate_service_quality(Distance_U2K)
print("服务质量:", service_quality)
find_optimal_uav = env.find_optimal_uav()
print("无人机:", find_optimal_uav)
uav_mapping = {"U0": 0, "U1": 1, "U2": 2} # 根据你的实际情况进行修改
n = min(len(service_quality), len(find_optimal_uav))
features = []
for i in range(n):
if service_quality[i] == "优秀":
quality = 2
elif service_quality[i] == "良好":
quality = 1
elif service_quality[i] == "一般":
quality = 0
else:
quality = -1
uav_index = uav_mapping.get(find_optimal_uav[i], -1) # 查找无人机对应的索引,找不到则设为-1
if uav_index != -1:
features.append([1, quality, uav_index])
features = np.array(features, dtype=float)
print(features)
labels = np.array([20, 30, 40]) # khz 带宽(切片修改为与 features 长度匹配)
# 执行梯度下降算法
env.gradient_descent(features, labels)
# 可视化结果
env.plot_results(features, labels)
if __name__ == '__main__':
main()
SystemModel.py
import numpy as np
import matplotlib.pyplot as plt
import math
import pandas as pd
import copy
from Environment import MAXUserspeed,UAV_Speed,UserNumberPerCell,NumberOfUAVs,NumberOfCells,NumberOfUsers,learning_rate,num_iterations
class System_Model:
def __init__(
self,
):
self.learning_rate = learning_rate
self.num_iterations = num_iterations
self.theta = None
# 初始化无人机及位置
self.UAVspeed = UAV_Speed
self.UAV_number = NumberOfUAVs
self.UserperCell = UserNumberPerCell
self.U_idx = np.arange(NumberOfUAVs) # set up serial number for UAVs 为无人机设置序列号
self.PositionOfUAVs = pd.DataFrame(
np.zeros((3, NumberOfUAVs)),
columns=self.U_idx.tolist(), # Data frame for saving UAVs' position 将Dataframe格式的数据转成List数据类型
)
self.PositionOfUAVs.iloc[0, :] = [100, 200, 400] # UAVs' initial x
self.PositionOfUAVs.iloc[1, :] = [100, 400, 200] # UAVs' initial y
self.PositionOfUAVs.iloc[2, :] = [100, 100, 100] # UAVs' initial z
# 初始化用户和位置
self.User_number = NumberOfUsers
self.K_idx = np.arange(NumberOfUsers) # set up serial number for users
self.PositionOfUsers = pd.DataFrame(
np.random.random((3, NumberOfUsers)),
columns=self.K_idx.tolist(), # Data frame for saving users' position
)
self.PositionOfUsers.iloc[0, :] = [204.91, 493.51, 379.41, 493.46, 258.97, 53.33] # users' initial x
self.PositionOfUsers.iloc[1, :] = [219.75, 220.10, 49.81, 118.10, 332.59, 183.11] # users' initial y
self.PositionOfUsers.iloc[2, :] = 0 # users' hight is assumed to be 0
# 记录最开始的位置
self.Init_PositionOfUsers = copy.deepcopy(self.PositionOfUsers)
# copy.deepcopy()函数是一个深复制函数。所谓深复制,就是从输入变量完全复刻一个相同的变量,无论怎么改变新变量,原有变量的值都不会受到影响。
self.Init_PositionOfUAVs = copy.deepcopy(self.PositionOfUAVs)
# initialize a array to store state 初始化一个数组来存储状态
self.State = np.zeros([1, NumberOfUAVs * 3 + NumberOfUsers], dtype=float)
# data frame to save distance
self.Distence = pd.DataFrame(
np.zeros((self.UAV_number, self.User_number)),
columns=np.arange(self.User_number).tolist(), )
# pd.DataFrame创建了一个二维表,np.zeros((self.UAV_number, self.User_number))多维数组,columns的值相当于列索引
# data frame to save pathloss路径损耗
self.Propergation_Loss = pd.DataFrame(
np.zeros((self.UAV_number, self.User_number)),
columns=np.arange(self.User_number).tolist(), )
# 用户随机移动
def User_randomMove(self, MAXspeed, NumberofUsers):
self.PositionOfUsers.iloc[[0, 1], :] += np.random.randn(2, NumberofUsers) * MAXspeed # users random move
return
# this function is for calculating the distance between users and UAVs
def Get_Distance_U2K(self, UAV_Position, User_Position, UAVsnumber,
Usersnumber):
for i in range(UAVsnumber):
for j in range(Usersnumber):
self.Distence.iloc[i, j] = np.linalg.norm(
UAV_Position.iloc[:, i] - User_Position.iloc[:,
j]) # calculate Distence betwen UAV i and User j
# x_norm = np.linalg.norm(x, ord=None, axis=None, keepdims=False)
# 默认参数ord = None,axis = None,keepdims = False x: 表示矩阵
return self.Distence
def evaluate_service_quality(self, distance_U2K):
service_quality = []
for i in range(distance_U2K.shape[0]):
for j in range(distance_U2K.shape[1]):
distance = distance_U2K.iloc[i, j]
if distance < 150:
result = "优秀"
elif distance < 250:
result = "良好"
elif distance < 350:
result = "一般"
else:
result = "差"
# service_quality.append((distance, result))这个是包含距离值和评价结果
service_quality.append((result))
return service_quality
def Get_Propergation_Loss(self, distence_U2K, UAV_Position, UAVsnumber, Usersnumber,
f_c):
for i in range(
UAVsnumber): # Calculate average loss for each user, this pathloss model is for 22.5m<h<300m d(2d)<4km
for j in range(Usersnumber):
UAV_Hight = UAV_Position.iloc[2, i]
D_H = np.sqrt(np.square(distence_U2K.iloc[i, j]) - np.square(UAV_Hight)) # calculate distance
# calculate the possibility of LOS/NLOS
d_0 = np.max([(294.05 * math.log(UAV_Hight, 10) - 432.94), 18])
p_1 = 233.98 * math.log(UAV_Hight, 10) - 0.95
if D_H <= d_0:
P_Los = 1.0
else:
P_Los = d_0 / D_H + math.exp(-(D_H / p_1) * (1 - (d_0 / D_H)))
if P_Los > 1:
P_Los = 1
P_NLos = 1 - P_Los
# calculate the passlos for LOS/NOLS
L_Los = 30.9 + (22.25 - 0.5 * math.log(UAV_Hight, 10)) * math.log(distence_U2K.iloc[i, j],
10) + 20 * math.log(f_c, 10)
L_NLos = np.max([L_Los,
32.4 + (43.2 - 7.6 * math.log(UAV_Hight, 10)) * math.log(distence_U2K.iloc[i, j],
10) + 20 * math.log(f_c, 10)])
Avg_Los = P_Los * L_Los + P_NLos * L_NLos # average pathloss
gain = np.random.rayleigh(scale=1, size=None) * pow(10, (-Avg_Los / 10)) # random fading
self.Propergation_Loss.iloc[i, j] = gain # save pathloss
return self.Propergation_Loss
def find_optimal_uav(self):
min_loss = np.inf
optimal_uav = []
for i in range(NumberOfUAVs): # Assuming UAVsnumber is defined
total_loss = np.sum(self.Propergation_Loss.iloc[i, :]) # Calculate total loss for the current UAV
if total_loss < min_loss:
min_loss = total_loss
optimal_uav = [i]
elif total_loss == min_loss:
optimal_uav.append(i)
return ["U{}".format(uav_index) for uav_index in optimal_uav]
#计算S2A梯度下降算法
def gradient_descent(self, features, labels):
num_samples, num_features = features.shape
self.coefficients = np.zeros(num_features)
for _ in range(self.num_iterations):
predictions = self.predict(features)
errors = predictions - labels
gradient = np.dot(features.T, errors) / num_samples
self.coefficients -= self.learning_rate * gradient
def predict(self, features):
return np.dot(features, self.coefficients)
def plot_results(self, features, labels):
plt.scatter(features[:, 1], labels, color='b', label='Actual')
plt.plot(features[:, 1], self.predict(features), color='r', label='Predicted')
plt.xlabel('features')
plt.ylabel('labels')
plt.legend()
plt.savefig("E:\paper\TYUTpaper\img/costs_plot.png")
plt.show()
Environment
#迭代更新参数的次数
learning_rate = 0.1
num_iterations = 1000
F_c = 2 # carrier frequency/GHz 载频/GHz
# set up users' speed设置用户速度
MAXUserspeed = 0.5 # m/s
UAV_Speed = 5 # m/s
UserNumberPerCell = 2 # user number per UAV每架无人机服务两个用户
NumberOfUAVs = 3 # number of UAVs无人机的数量
NumberOfCells = NumberOfUAVs # Each UAV is responsible for one cell每架无人机负责一个小区(小区数量等于无人机数量)
NumberOfUsers = NumberOfUAVs * UserNumberPerCell # 用户数量等于无人机数*每架无人机服务的用户数
结果图为
目的是求得卫星的最佳 S2A 单播带宽价格,应该如何修改呢