基于蒙特卡洛的无线基站覆盖区域评估-求基站覆盖区域的总面积
目录
基站坐标点为随机数随机产生,绿色代表落在基站覆盖区域内,红色代表在基站覆盖区域外。可以发现,采样点数和最终结果误差不大。
代码:
"""
无线基站覆盖区域评估算法
假设有N个基站,编号为1~N,分布在二维平面上,其坐标分别为(Xi, Yi)。基站的覆盖范围假设为圆形,半径为R。对平面上的任意点,若与任一个基站的距离
小于R则视为被覆盖,因此这些基站覆盖区域是这些圆形的并集。根据上述条件,计算这些基站覆盖区域的总面积。如难以获得精确解,可以求近似解。
要求:给出问题的数学规范描述和解题思路,给出算法的规范描述,完成算法实现和性能分析(理论分析或实测分析均可)。
"""
import random
import numpy as np
import matplotlib.pyplot as plt
import math
# 使能够正常显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
"""定义一些参数 把点随机生成出来"""
# 生成随机数,并设置随机数种子,以便复现
random.seed(10)
base_station_number = 10 # 基站个数
base_station_r = 50 # 基站半径
point_x_list = random.sample(range(-base_station_number * 10, base_station_number * 10), base_station_number)
point_y_list = random.sample(range(-base_station_number * 10, base_station_number * 10), base_station_number)
print(f"point_x_axis_list:{point_x_list}")
print(f"point_y_axis_list:{point_y_list}")
"""end"""
class MonteCarlo(object):
"""蒙特卡洛算法求基站覆盖面积"""
def __init__(self, points_number, point_x_list, point_y_list, base_station_r):
"""基站属性"""
# 基站坐标
self.point_x_list = point_x_list
self.point_y_list = point_y_list
# 基站半径
self.base_station_r = base_station_r
# 基站数量
self.base_station_number = len(self.point_x_list)
# 基站覆盖面积, 也就是并集
self.cover_area = 0
self.cover_area_radio = 0
"""蒙特卡洛属性"""
# 总的点数
self.points_number = points_number # 总的点数
# 在基站圆面积内的点数
self.point_in_circles = 0
self.xlim_l = min(self.point_x_list) - self.base_station_r
self.xlim_r = max(self.point_x_list) + self.base_station_r
self.ylim_l = min(self.point_y_list) - self.base_station_r
self.ylim_u = max(self.point_y_list) + self.base_station_r
"""画图"""
# 画图
self.plt_obj = plt
self.plt_obj.xlim(self.xlim_l, self.xlim_r)
self.plt_obj.ylim(self.ylim_l, self.ylim_u)
# 画图格式
self.point_in_circle_format_string = 'go'
self.point_outside_format_string = 'r*'
self.fontsize = 14
self.scatter_s = 10
def is_in_circles(self, x, y):
"""根据x,y坐标判断是否在各个基站的圆面积内
点到圆心的距离大于半径——在圆外,否则在圆内"""
is_in_circles = False
for i in range(self.base_station_number):
if (pow(x - self.point_x_list[i], 2) + pow(y - self.point_y_list[i], 2)) <= pow(self.base_station_r,
2): # 点在圆内
is_in_circles = True
break # 在圆内直接停止
# print(f"is_in_circles{is_in_circles}")
return is_in_circles
def monte_carlo(self):
for i in range(self.points_number):
x = random.uniform(self.xlim_l, self.xlim_r) # 产生随机数
y = random.uniform(self.ylim_l, self.ylim_u)
# 判断是否在各个基站的圆面积内
if self.is_in_circles(x, y):
self.point_in_circles += 1
self.plt_obj.plot(x, y, self.point_in_circle_format_string)
else:
self.plt_obj.plot(x, y, self.point_outside_format_string)
# 计算基站覆盖面积
total_area = int((self.xlim_r - self.xlim_l) * (self.ylim_u - self.ylim_l))
self.cover_area_radio = round(self.point_in_circles / self.points_number, 2)
self.cover_area = int(total_area * self.cover_area_radio)
print(f"total_area:{total_area}")
print(f"self.cover_area_radio:{self.cover_area_radio}")
print(f"self.cover_area:{self.cover_area}")
# 显示基站点
self.draw_points(xlabel="x", ylabel="y", title=f"采样点数{self.points_number},基站覆盖面积{self.cover_area},总面积{total_area},比例{self.cover_area_radio}")
def draw_points(self, xlabel: str, ylabel: str, title: str):
"""把点显示出来"""
self.plt_obj.scatter(self.point_x_list, self.point_y_list, s=self.scatter_s)
# # 设置图表标题并给坐标轴加上标签
self.plt_obj.title(title, fontsize=self.fontsize)
self.plt_obj.xlabel(xlabel, fontsize=self.fontsize)
self.plt_obj.ylabel(ylabel, fontsize=self.fontsize)
for i in range(self.base_station_number):
self.plot_circle(x=self.point_x_list[i], y=self.point_y_list[i], r=self.base_station_r)
def plot_circle(self, x, y, r):
"""根据坐标和半径画圆"""
x_list = np.linspace(x - r, x + r, 5000)
y1 = np.sqrt(r ** 2 - (x_list - x) ** 2) + y
y2 = -np.sqrt(r ** 2 - (x_list - x) ** 2) + y
self.plt_obj.plot(x_list, y1, c='k')
self.plt_obj.plot(x_list, y2, c='k')
def plt_show(self):
self.plt_obj.show()
# points_number_list = range(50, 10000, 50)
points_number_list = [100, 1000, 10000]
for points_number in points_number_list:
MonteCarlo_obj = MonteCarlo(points_number=points_number, point_x_list=point_x_list,
point_y_list=point_y_list, base_station_r=base_station_r)
MonteCarlo_obj.monte_carlo()
MonteCarlo_obj.plt_show()
本文来自博客园,作者:JaxonYe,转载请注明原文链接:https://www.cnblogs.com/yechangxin/articles/17073983.html
侵权必究