[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
# [url=home.php?mod=space&uid=238618]@Time[/url] : 2022年03月20日 18时43分
# [url=home.php?mod=space&uid=621973]@Email[/url] : [email]yun981128@gmail.com[/email]
# [url=home.php?mod=space&uid=686208]@AuThor[/url] : 王从赟
# [url=home.php?mod=space&uid=155760]@Project[/url] :HuaWei
# [url=home.php?mod=space&uid=267492]@file[/url] : main.py
# @notice :
import numpy as np
from np_load_data import load_demand, load_qos, load_site_bandwidth, logger
from func import duplicate_data, Get_Sum, Constraint
# 读取数据
DataDemand = load_demand() # 时间序列内流量需求
DataQos = load_qos() # qos (处理后的qos 不显示数值 只返回True、False 指向是否可用)
DataBandwidth = load_site_bandwidth() # 每个边缘节点最大带宽
# 处理数据
TNumber = DataDemand.shape[0] # 时间序列长度
NNumber, MNumber = DataQos.shape # NNumber:边缘节点数量 MNumber:客户节点数量
T = range(DataDemand.shape[0]) # 时间序列
N = range(DataQos.shape[0]) # 边缘节点
M = range(DataQos.shape[1]) # 客户节点
DupDataQos = duplicate_data(np.expand_dims(DataQos, axis=0), 100)
DupDataBandwidth = duplicate_data(DataBandwidth.T, 100)
# 设置变量
X = np.zeros((TNumber, NNumber, MNumber)) # 流量分配方案 𝑋[t][n][m] 指在T时刻第m个客户节点像第n个边缘节点分配的带宽
Y: np.ndarray = DataQos.copy()
Y = np.insert(Y, Y.shape[1], values=Y.sum(axis=1), axis=1)
Y = np.insert(Y, Y.shape[0], values=Y.sum(axis=0), axis=0)
np.savetxt("DataQos.csv", Y, fmt="%d")
# 第i个客户节点和第j个边缘节点是否符合分配要求,是的话值为1,否则0;
# 且横纵的行列计算出第j个边缘节点可分配的客户节点个数和第i个客户节点可使用的边缘节点个数
# 目标
# min(Sum)
# 初始化X
logger.info("初始化X,平均分配带宽")
# 100*10
for t in T:
for m in M:
avg = DataDemand[t, m] // Y[-1, m]
remainder = DataDemand[t, m] % Y[-1, m]
Z = np.zeros((TNumber, NNumber, MNumber))
K = DataQos[:, m] * avg
K[np.where(K > 0)[0][:remainder]] = avg + 1
Z[t, :, m] = K
X = X + Z
logger.info("优化方案")
def optimization(X):
# 找出不符合要求的位置
NodeBandwidth = np.sum(X, axis=2)
t, n = np.where(NodeBandwidth > DupDataBandwidth)
if t.shape[0] == 0:
logger.info("优化完成")
return X
# 取出其中第一个超带宽位置及超出的带宽
t, n = t[0], n[0] # t时刻第n个节点超带宽
beyond_bandwidth = (NodeBandwidth[NodeBandwidth > DupDataBandwidth])[0] - \
(DupDataBandwidth[NodeBandwidth > DupDataBandwidth])[0]
logger.info(f"在第{t}时刻第{n}个节点超出带宽{beyond_bandwidth},该节点支持的客户端数量为:{Y[n, -1]}")
avg = beyond_bandwidth // (Y[n, -1])
remainder = int(beyond_bandwidth % (Y[n, -1]))
logger.info(f"该节点支持的客户端平均减少{avg}带宽,前{remainder}个客户端额外减少1带宽")
Z = np.zeros((TNumber, NNumber, MNumber))
K = DataQos[n, :] * avg
K[(np.where((DataQos[n, :]) > 0)[0])[:remainder]] = avg + 1
Z[t, n, :] = K
X = X - Z
logger.info(f"在第{t}时刻,减少带宽的客户端及减少的带宽为:{K}")
for m, reduce_bandwidthin in enumerate(K):
logger.info(f"对于第{t}时刻的第{m}个客户端减少的{int(reduce_bandwidthin)}带宽平均分配至第{t}时刻第{m}个客户端除第{n}个节点外的节点")
avg = int(reduce_bandwidthin // (Y[-1, m] - 1))
remainder = int(reduce_bandwidthin % (Y[-1, m] - 1))
logger.info(f"在第{t}时刻第{n}个客户端缺少带宽{reduce_bandwidthin},该客户端支持的节点数量为:{Y[-1, m] - 1}")
DataQos_tmp = DataQos.copy()
Z = np.zeros((TNumber, NNumber, MNumber))
DataQos_tmp[n, m] = 0
K = DataQos_tmp[:, m] * avg
K[np.where(DataQos_tmp[:, m] > 0)[0][:remainder]] = avg + 1
Z[t, :, m] = K
# logger.info(f"在第{t}时刻为第{n}个客户端增加带宽的节点为:{K}")
X = X + Z
return optimization(X)
X = optimization(X)
logger.info("检查约束")
cons = Constraint(DupDataQos, DataDemand, DupDataBandwidth)
logger.info(f"𝑋tnm 为非负整数:{'符合约束' if cons.constraint_X1(X) == 0 else '不符合约束'}")
logger.info(f"客户节点带宽需求只能分配到满足 QoS 约束的边缘节点:{'符合约束' if cons.constraint_X2(X) == 0 else '不符合约束'}")
logger.info(f"客户节点带宽需求必须全部分配给边缘节点:{'符合约束' if cons.constraint_X3(X) == 0 else '不符合约束'}")
logger.info(f"边缘节点接收的带宽需求不能超过其带宽上限:{'符合约束' if cons.constraint_X4(X) == 0 else '不符合约束'}")
logger.info("保存带宽分配方案")
for index, layer in enumerate(X): np.savetxt(f"result/T{index}.csv", layer, fmt="%d")