2022 年第十二届 MathorCup 高校数学建模挑战赛D题思路(移动通信网络站址规划和区域聚类问题)

目录

一、前言

二、问题背景

三、问题

四、解题思路

(1)针对问题1:

(2)针对问题2:

(3)针对问题3:

五、附上几个典型代码

(1)K-means算法

(2)遗传算法

(3)模拟退火算法


一、前言

        本文是对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 都是一类的。试对所有弱覆盖点进行聚类,要求聚类所用方法的总时间复杂度尽量低。

四、解题思路

(1)针对问题1:

        1. 可以使用遗传算法进行站址规划。将每个点看作一条基因,并将该区域内所有点的坐标以及业务量作为初始种群。根据遗传算法的步骤进行迭代,每次选择适应度高的个体进行繁殖和变异,最终得到一组规划站址的基因序列。根据规划站址的坐标可以计算出每个站址覆盖的弱覆盖点的业务量,并根据业务量的大小选择规划基站的种类。
        2. 可以使用层次分析法(AHP)进行站址规划和基站选择。将站址规划和基站选择作为两个主要因素,设定一些子因素,比较宏基站和微基站在子因素上的权重,最终得到宏基站和微基站在总体上的权重比,然后根据所覆盖的弱覆盖点的业务量大小,选择相应的基站类型。

(2)针对问题2:

        1. 可以使用基于遗传算法和模拟退火的混合算法进行站址规划和扇区角度的优化。将每个站点的坐标和三个扇区的角度和主方向看作基当前代的基因序列。将每个基因序列视为一个个体,对每个个体计算弱覆盖点的业务量并根据问题1的规划思路选择基站类型。然后,通过混合算法对基因序列进行优化,得到最优解。
        2. 可以使用聚类算法对弱覆盖点进行聚类,然后在每个聚类区域内进行站址规划和基站选择。可以使用K-Means对所有弱覆盖点进行聚类,或者使用DBSCAN等基于密度的聚类算法。在每个弱覆盖点所属的聚类区域内进行站址规划和基站选择,使得在每个区域内选择的站点能够覆盖尽可能多的弱覆盖点并满足问题1中给定的门限条件。每个区域内不同站点之间夹角的大小需要满足问题2中给定的约束条件。

(3)针对问题3:

        针对问题3,可以使用基于密度的聚类算法进行优化。DBSCAN使用密度来定义聚类,可以自动确定最佳集群数量和最佳聚类半径。基于此,可以使用DBSCAN进行弱覆盖点的聚类,从而得到弱覆盖区域,并根据每个区域内的弱覆盖点的业务量大小进行站址规划和基站选择。在每个区域内选择的站点应该能够覆盖尽可能多的弱覆盖点,并且还应该减少不同区域内站点的重叠,以最大化覆盖率并降低规划成本。

五、附上几个典型代码

        这里是几个典型的算法代码(当然,不是作者在竞赛过程中使用的代码):

(1)K-means算法

        以下是经典的K-means算法的Python实现代码:

```
import numpy as np

def kmeans(X, K, max_iters=10):
    m, n = X.shape # 获取样本数量和特征数量

    # 从样本中随机选择K个质心
    centroids = X[np.random.choice(m, K, replace=False)]

    for i in range(max_iters):
        # 计算每个样本点与每个质心的距离
        distances = np.sqrt(((X - centroids[:, np.newaxis]) ** 2).sum(axis=2))

        # 将每个样本归为距离最近的质心点所在的簇
        labels = distances.argmin(axis=0)

        # 重新计算质心的位置
        centroids = np.array([X[labels == k].mean(axis=0) for k in range(K)])

    return centroids, labels
```

        其中,X是一个(m, n)的numpy数组,表示共有m个n维样本;K是需要聚类的簇数。max_iterations是可选参数,表示最大迭代次数,默认为10次。
        算法返回了每个簇的质心位置centroids和每个样本点所属的簇标签labels。

(2)遗传算法

        以下是经典的遗传算法Python实现代码:

```
import random
import numpy as np

def genetic_algorithm(fitness_func, generation_size, gene_size, mutation_prob, elite_rate=0.1, max_generations=100):
    # 迭代代数为0
    generation = 0

    # 创建初始种群
    population = np.random.rand(generation_size, gene_size)

    # 开始迭代
    while generation < max_generations:
        # 计算适应度分数
        fitness = fitness_func(population)

        # 找到最好的适应度分数和个体(即最大化适应度)
        best_fitness = np.max(fitness)
        best_individual = population[np.argmax(fitness), :]

        # 打印每一代的最好适应度分数
        print("Generation:", generation, "Best Fitness:", best_fitness)

        # 选择下一代
        next_population = []

        # 选择精英个体
        elites = population[np.argsort(fitness)[::-1][:int(generation_size * elite_rate)]]

        # 将精英个体加入下一代中
        next_population.extend(elites)

        # 开始生成新的后代
        while len(next_population) < generation_size:
            # 通过赌轮选择父母
            parent1 = roulette_selection(population, fitness)
            parent2 = roulette_selection(population, fitness)

            # 通过交叉操作,生成新的后代
            child = crossover(parent1, parent2)

            # 通过变异操作,引入新的遗传变异
            child = mutate(child, mutation_prob)

            # 将后代加入下一代中
            next_population.append(child)

        # 更新种群
        population = np.array(next_population)

        # 增加代数
        generation += 1

    # 返回最终的最优解
    return best_individual


# 赌轮选择函数
def roulette_selection(population, fitness):
    total_fitness = np.sum(fitness)
    selection_probs = fitness / total_fitness
    return population[np.random.choice(len(population), p=selection_probs)]

# 交叉操作函数
def crossover(parent1, parent2):
    crossover_point = np.random.randint(len(parent1))
    child = np.concatenate((parent1[:crossover_point], parent2[crossover_point:]))
    return child

# 变异操作函数
def mutate(individual, mutation_prob):
    for i in range(len(individual)):
        if np.random.rand()<mutation_prob:
            individual[i] = 1-individual[i]
    return individual
```

        其中,fitness_func是适应度函数,用于计算种群中每个个体的适合程度;generation_size是种群大小;gene_size是个体基因长度;mutation_prob是变异概率;elite_rate是精英率,即每一代中最好的一部分个体会直接进入下一代。max_generations是最大迭代次数。
算法返回一个最优解(best_individual)。

(3)模拟退火算法

        以下是一个通用的模拟退火算法Python实现代码:

```
import numpy as np

def simulated_annealing(cost_func, initial_solution, max_iterations, initial_temperature=100, cooling_rate=0.95, stopping_temperature=1e-6):
    # 初始温度
    temperature = initial_temperature

    # 初始解
    current_solution = initial_solution
    best_solution = current_solution

    # 计算初始成本值
    current_cost = cost_func(current_solution)

    # 迭代直到温度达到最低值
    for i in range(max_iterations):
        # 选择一个随机解
        next_solution = current_solution + 0.01 * np.random.randn(*current_solution.shape)

        # 计算新成本值
        next_cost = cost_func(next_solution)

        # 计算概率
        acceptance_probability = acceptance_probability_func(current_cost, next_cost, temperature)

        # 根据概率接受或拒绝新解
        if acceptance_probability > np.random.rand():
            current_solution = next_solution
            current_cost = next_cost

        # 如果当前解优于最优解,则更新最优解
        if current_cost < cost_func(best_solution):
            best_solution = current_solution

        # 降低温度
        temperature *= cooling_rate

        # 如果温度降低到阈值以下,则退出循环
        if temperature < stopping_temperature:
            break

    # 返回最优解
    return best_solution

# 温度接受概率函数
def acceptance_probability_func(current_cost, next_cost, temperature):
    if next_cost < current_cost:
        return 1.0
    else:
        return np.exp((current_cost - next_cost) / temperature)
```

        其中,cost_func是成本函数(目标函数),用于计算解的成(目标值);initial_solution是初始解;max_iterations是迭代次数;initial_temperature是初始温度;cooling_rate是温度下降率;stopping_temperature是停止温度阈值。该算法返回最优解(best_solution)。

        在模拟退火算法中,温度下降速度(即初始温度和温度下降率)是一个关键参数,因此在不同的应用场景中需要根据实际情况进行适当调整。另外,由于模拟退火算法本身是一种随机算法,因此每一次运行结果都可能不同。为了得到可靠的结果,通常会运行多次并对结果进行平均。

猜你喜欢

转载自blog.csdn.net/as12138/article/details/131273555