2022年第十二届MathorCup高校数学建模挑战赛
D 题 移动通信网络站址规划和区域聚类问题
移动通信技术规模飞速发展,运营规模也越来越大,导致带来的通信 网络越来越复杂。随着 5G 的发展,通信的带宽越来越大,但基站的能覆盖范围越来越小,使得覆盖同样的区域,需要的基站数量变的更多。另外, 基站和天线的种类也变多了。这就使得通信网络的规划特别是站址选择的 问题变得越来越复杂。站址选择问题是:根据现网天线的覆盖情况,给出现网的弱覆盖区域,选择一定数量的点,使得在这些点上新建基站后,可以解决现网的弱覆盖区域的覆盖问题。下图为某城市某区域的现网覆盖情况,其中红色的区域表示为弱覆盖区域。
在实际网络规划中,考虑基站的建设成本和一些其他因素,有时候可能无法把所有弱覆盖区域都解决,这时候就需要考虑业务量的因素,尽量 优先解决业务量高的弱覆盖区域。
为了便于计算,将给定的区域用很小的栅格进行划分,只考虑每个栅 格的中心点,即任给一个区域,都可以划分成有限个点。每个点有一些属 性值,包括:坐标,是否为弱覆盖点,业务量等。站址也只能选择区域内的点。某个点是否被规划基站覆盖可以按如下方法判断:
同时,实际中还需要考虑一个约束条件,即新建站址之间以及新建站 址和现有站址之间的距离不能小于等于给定门限。
问题 1: 给定区域的大小是 2500×2500 个栅格即 2500×2500 个点, 其中横坐标范围是 0 到 2499,纵坐标范围是 0 到 2499。附件 1 中是筛选出该区域中的弱覆盖点的信息,包括每个点的坐标和业务量。给定 2 种基站, 分别为:
宏基站(覆盖范围 30,成本 10) 微基站(覆盖范围 10,成本 1)
附件 2 中还给出了现网基站的坐标点,新建站址之以及新建站址和现有站址之间的距离的门限是10。
根据给定的信息和附件中的数据,进行站址规划,使得弱覆盖点总业 务量的 90%被规划基站覆盖。给出选择的站址的坐标以及每个站址选择的基站种类。站址的坐标只能在给定区域内的 2500×2500 个点中选择。
问题 2:进一步考虑,实际中,每个站并不是完全的圆形覆盖,而是每个站上有 3 个扇区,每个扇区指向一个方向。每个扇区在主方向上覆盖范围最大(宏基站为 30,微基站为 10),在主方向左右 60 度的范围内可以覆盖,覆盖范围按线性逐渐缩小,在 60 度的时候,覆盖范围为主方向覆盖范围的一半。超过 60 度,则无法被该扇区覆盖。
考虑每个站的任意 2 个扇区的主方向之间的夹角不能小于 45 度,同时仍然考虑上一问中的基站成本等其他条件,问在最优站址和扇区角度的条 件下,新建站能否覆盖弱覆盖点总业务量的 90%。若能,给出最优站址和扇区角度的结果;否则,给出给出最优站址和扇区角度的结果,并给出最 多可以覆盖的弱覆盖点的总业务量的比例。
问题 3:实际工作中,为了更好的解决弱覆盖问题,需要对弱覆盖点进行区域聚类,把距离近的弱覆盖点聚成一类,可以得到弱覆盖区域,这 样可以对不同的弱覆盖区域分开管理使得可以更好的解决弱覆盖问题。
若 2 个弱覆盖点的距离不大于 20,则这 2 个弱覆盖点应聚为一类,并且考虑聚类性质具有传递性,即若点 A 和点 B 是一类的,点 B 和点 C 是一类的,则点 A、B 和 C 都是一类的。试对所有弱覆盖点进行聚类,要求聚类所用方法的总时间复杂度尽量低。
整体求解过程概述(摘要)
随着 5G 技术的全面普及,通信所需的带宽越来越大,原有基站能够覆盖的范围越来越小,从而需要建立新基站减少弱覆盖区域。本文围绕基站与弱覆盖点,建立基于改进免疫算法的 0-1 规划模型、基于赋权 K-means 算法的决策模型、基于 DBSCAN 算法的聚类模型,得出新基站建立的最优方案、基站的扇区主方向角度和弱覆盖点的聚类情况。
针对问题一,建立基于 0-1 规划的数学规划模型,采用改进免疫算法对规划模型进行求解。根据条件与要求构造数学规划模型的目标函数、决策变量与约束条件,对于候选基站是否选择作为新基站的问题采用 0-1 规划。运用改进的免疫算法对数学规划模型进行求解,其中的初始种群基于贪心算法进行选取。最终分别得出宏基站与微基站的站址坐标,总计宏基站 407 个,微基站 3968 个,覆盖的业务量占比为 90.0016% 。
针对问题二,基于赋权的 K-means 算法对各个基站覆盖范围的扇区主方向进行决策。根据问题一所求得的最优站址,分别对各个基站覆盖范围内的弱覆盖点的业务量进行赋权,将带有权重的弱覆盖点应用 K-means 算法进行聚类,文中聚类参数取 𝑘 = 3 。在满足主方向间夹角不超过 45 度的情况下,聚类的中心点坐标能同时反应该区域弱覆盖点的坐标分布以及业务量分布,从而可以决策 3个扇区主方向。最终得出各个基站的 3 个扇区角度。
针对问题三,本文采用复杂度较低的 DBSCAN 算法对弱覆盖点进行聚类。由于聚类要求为距离不大于 20 的两点聚为一类,且该聚类具有传递性。相比较于基于中心点位置的 K-means 算法,DBSCAN 算法是基于空间密度进行聚类,有着点间距的限制参数以及极优的传递性。本文 DBSCAN算法参数的数值取 𝐸𝑝𝑠 = 20 , 𝑀𝑖𝑛𝑃𝑡𝑠 = 1 。最终求得所有弱覆盖点聚类为 898 类,该方法的总时间复杂度为 𝐎(𝐍𝐥𝐨𝐠𝐍) 。
最终对本文模型进行分析总结,同时对存在的缺点提出改进的方案,并将模型的应用进行了推广。
模型假设:
(1)本题 2500*2500 的区域中,每一个点都可以建立通讯基站,即不考虑自然地理以及人为因素的影响。
(2)本题中建设的所有基站在其自身信号覆盖范围内在任意时间均可做到均匀投射,即不考虑外界环境对于基站的影响,基站覆盖范围内所有位置都能够公平的接受到基站的信号。
(3)特定区域的通信基站用户使用量稳定,即用户使用量不会随着时间变化发生较大调整。
(4)所有通讯基站的性能,不随着时间变化而发生变动,即本题中出现的所有通讯基站性能稳定且不会发生故障。
问题分析:
问题一的分析
针对问题一,在给定区域内规划选取坐标进行新基站的建立,能够使得弱覆盖点的总业务量 90% 被新基站覆盖,同时需要满足各个基站之间的距离需要大于 10,并且成本最小化。新建基站有宏基站与微基站两种类型可供选择。首先对数据进行预处理。根据附件 1,对业务量极低的弱覆盖点进行预处理,删除后对结果的影响差异很小;根据附件 2,筛除现有基站和以现有基站为圆心 10 为半径的圆心范围的点,剩余的所有点作为候选基站点。随后运用基于 0-1 规划的免疫算法求解基站建立的最优方案。基于 0-1 规划模型,对新基站问题建立数学规划模型。以总建站成本为目标函数,问题一的所有要求作为约束条件。基于免疫算法求解数学规划模型,该算法中的初始种群采取贪心算法进行获取。最终得出新基站的选址、基站类型以及覆盖业务量的百分比。
问题二的分析
基于问题一的求解出的新基站最优规划决策,分析覆盖范围的变化时,弱覆盖点的被覆盖情况以及覆盖业务量的占比。因覆盖范围从主方向向两侧按线性减小,所以扇区的主方向应指向弱覆盖点密集且业务量较大的方向。因此采用聚类的方式,对扇区的主方向进行决策。首先对每一新基站点覆盖范围内的弱覆盖点进行赋权,运用 K-means 算法对其进行聚类。本文将覆盖范围内的弱覆盖点聚为 3 类,同时分别求出该 3 类弱覆盖点的 3 个中心点,基站点与该 3 个中心点的连线作为初始的 3 个扇区主方向。其次根据问题二的要求,根据业务量以及主方向间的角度不小于 45 度要求,对各个主方向进行统筹调整。最终得出所有基站的各个扇区主方向的角度情况,以及最多可覆盖的弱覆盖点总业务量占比。
问题三的分析
针对问题三,需要最终得出所有弱覆盖点的聚类情况,同时需要保证较为低的总时间复杂度。弱覆盖点之间的聚类约束条件为,若 𝐴、𝐵 两点之间的距离 ‖𝐴 − 𝐵‖2 ≤ 20 时,那么这两点聚为一类,同时该聚类具有传递性,并保证较低的总时间复杂度。因此本文采用DBSCAN 算法对弱覆盖点进行聚类分析。
选取 DBSCAN 算法的三个原因:
(1) 能够通过 DBSCAN 算法中的参数 𝐸𝑝𝑠 ,即以某点为圆心所划分圆形区域的半径大小,从而可限定两点之间距离,满足问题三的聚类约束条件。
(2) DBSCAN 算法的原理,亦是从各个核心点与之间的传递对目标进行聚类,是一种基于空间密度有传递性质的聚类模型。
(3) 问题三是定点的二维数据聚类分析,因此该算法在此处的总时间复杂度较低。对比 K-means 算法,虽然可以将目标对象进行客观聚类,但是以下三个不选取的原因:首先,K-means 算法需要事先人为确定聚类种数,起始点的选择会极大影响聚类结果,因此具有很大程度的主观性。其次,该算法难以发现任意形状的簇,而地图上的弱覆盖点显然具有形状性。而且,K-means 算法的原理是基于各个点每次迭代的中心点进行聚类,因此该算法缺乏考虑各个弱覆盖点聚类的传递性。
模型的建立与求解整体论文缩略图
全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可
程序代码:(代码和文档not free)
部分Python程序如下:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
#气泡图
def DrawBubble(read_name):
# 设置样式
sns.set(style = "whitegrid")
# 数据来源
data = pd.read_csv(read_name)
# X 轴数据
x = data.x
# Y 轴数据
y = data.y
# 用来调整各个点的大小 s
z = data.traffic
cm = plt.cm.get_cmap('RdYlBu')
fig,ax = plt.subplots(figsize = (12,10))
#注意 s 离散化的方法,因为需要通过点的大小来直观感受其所表示的数值大小
#参数是 X 轴数据、Y 轴数据、各个点的大小、各个点的颜色
bubble = ax.scatter(x, y , s = z, c = z, cmap = cm, linewidth = 0.5, alpha = 0.5)
ax.grid()
fig.colorbar(bubble)
# X 轴标签
ax.set_xlabel('x', fontsize = 15)
# Y 轴标签
ax.set_ylabel('y', fontsize = 15)
#plt.show()
plt.savefig("C:/BubblePic_newdata.png")
#改变顺序
def ChangeOrder(read_name):
# 数据来源
data = pd.read_csv(read_name)
# 根据 traffic 排序
newdata = data.sort_values(by = ['traffic'],ascending = False)
# 保存新顺序的数据
newdata.to_csv("C:/Users/EASKWON/Desktop/2022 年 MathorCup 高校数学建模挑战赛赛题/D
题/附件/new.csv")
data2 = pd.read_csv("C:/Users/EASKWON/Desktop/2022 年 MathorCup 高校数学建模挑战赛赛题
/D 题/附件/new.csv")
p = data2["traffic"].cumsum() / data["traffic"].sum()
# 数据累计占比
print(p)
# 给定 91%占比
key = p[p > 0.98].index[0]
# 找到点对应的位置
key_num = data2.index.tolist().index(key)
print("累计超过 91%的基站坐标:", key)
print("累计超过 91%的基站的索引位置:", key_num)
key_station = data2[:key]
print("核心基站:", key_station)
if __name__=='__main__':
ChangeOrder("C:附件 1 弱覆盖栅格数据(筛选).csv")#改变顺序
程序2
import warnings
import numpy as np
import pandas as pd
from pandas.plotting import scatter_matrix
from sklearn import metrics
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from matplotlib import pyplot as plt, colors
def plot(scores):
"""
画出不同参数模型评估参数轮廓系数折线图
:return:
"""
#plt.plot(list(range(5,20)), scores)
plt.xlabel("Number of Clusters Initialized")
plt.ylabel("Sihouette Score")
plt.show()
plt.savefig("E:/Pic_score.png")
if __name__ == '__main__':
# 1. 读取数据
# data = pd.read_csv("E:/mathorcup/question1/answer/new_station.csv")
file_path = r'E:/筛选.xlsx' # r 对路径进行转义,windows 需要
raw_data = pd.read_excel(file_path, header=0, dtype=float) # header=0 表示第一行是表头,就自动去
除了
data = raw_data.values
X = data[:, 0:2]
print(X)
# 2. 读取特征 X, 并标准化
# X = data[data.columns[data.columns != 'name']]
# 3. DBscan 聚类
db = DBSCAN(eps=9, min_samples=2).fit(X)
labels = db.labels_
print(labels)
# 计算簇的个数并打印,评价聚类效果
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
print("Silhouette Coefficient: %0.3f" % metrics.silhouette_score(X, labels))
# 打印各簇标号以及各簇内数据
# 画直方图,分析实验结果
4. 将聚类结果处理
print(data['cluster_db'])
redata[] = labels
redata.sort_values('cluster_db')
redata.groupby('cluster_db').mean()
5. 画
scatter_matrix(X, c=colors[data.cluster_db], figsize=(10, 10), s=100)
scatter_matrix(X, c=db,figsize=(10, 10), s=100)
plt.savefig('E:/matrix.png')
plt.show()
6. 循环验证最优参数, 并作图
cores = {}
for min_sample in range(2,5):
labels = DBSCAN(eps=9, min_samples=min_sample).fit(X).labels_
score = metrics.silhouette_score(X, labels)
scores[min_sample] = score
print(scores)
best_eps = sorted(scores.items(), key=lambda x: x[1], reverse=True)[0][0]
print(best_eps)
db = DBSCAN(eps=best_eps, min_samples=2).fit(X)
labels = db.labels_
print(labels)
plot(scores=scores)