import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import distance
from coords_nsga2 import CoordsNSGA2, Problem
from coords_nsga2.spatial import region_from_range
# 定义监控区域
region = region_from_range(0, 20, 0, 15)
# 定义目标函数
def objective_coverage(coords):
"""最大化覆盖面积"""
# 简化的覆盖模型:每个传感器覆盖半径为3的圆形区域
coverage_radius = 3.0
# 生成网格点来评估覆盖
x_grid, y_grid = np.meshgrid(np.linspace(0, 20, 50), np.linspace(0, 15, 40))
grid_points = np.column_stack([x_grid.ravel(), y_grid.ravel()])
covered_points = 0
for grid_point in grid_points:
distances = np.sqrt(np.sum((coords - grid_point)**2, axis=1))
if np.any(distances <= coverage_radius):
covered_points += 1
return covered_points / len(grid_points) # 覆盖率
def objective_energy_efficiency(coords):
"""最大化能量效率(最小化总传输距离)"""
# 假设有一个中心节点在(10, 7.5)
center = np.array([10, 7.5])
distances = np.sqrt(np.sum((coords - center)**2, axis=1))
total_distance = np.sum(distances)
return -total_distance # 负号因为我们要最大化
# 定义约束条件
def constraint_sensor_spacing(coords):
"""传感器最小间距约束"""
dist_list = distance.pdist(coords)
min_spacing = 2.0
violations = min_spacing - dist_list[dist_list < min_spacing]
return np.sum(violations)
def constraint_battery_life(coords):
"""电池寿命约束(基于距离中心节点的距离)"""
center = np.array([10, 7.5])
distances = np.sqrt(np.sum((coords - center)**2, axis=1))
max_distance = 12.0 # 最大传输距离
violations = distances[distances > max_distance] - max_distance
return np.sum(violations)
# 创建问题
problem = Problem(
objectives=[objective_coverage, objective_energy_efficiency],
n_points=8, # 8个传感器
region=region,
constraints=[constraint_sensor_spacing, constraint_battery_life]
)
# 创建优化器
optimizer = CoordsNSGA2(
problem=problem,
pop_size=40,
prob_crs=0.6,
prob_mut=0.03
)
# 运行优化
result = optimizer.run(600)
# 可视化结果
plt.figure(figsize=(16, 12))
# 绘制监控区域和传感器部署
plt.subplot(2, 3, 1)
x, y = region.exterior.xy
plt.fill(x, y, alpha=0.1, fc='lightgreen', ec='green', label='Monitoring Area')
# 找到帕累托最优解
from coords_nsga2.utils import fast_non_dominated_sort
fronts = fast_non_dominated_sort(optimizer.values_P)
pareto_solutions = result[fronts[0]]
# 绘制最优解
best_solution = pareto_solutions[0] # 选择第一个帕累托解
plt.scatter(best_solution[:, 0], best_solution[:, 1],
c='red', marker='s', s=200, label='Sensors')
# 绘制覆盖范围
coverage_radius = 3.0
for sensor in best_solution:
circle = plt.Circle(sensor, coverage_radius, alpha=0.2, fc='blue')
plt.gca().add_patch(circle)
# 绘制中心节点
plt.scatter(10, 7.5, c='black', marker='*', s=300, label='Center Node')
plt.title('Sensor Network Deployment')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.legend()
plt.grid(True)
# 绘制目标函数值
plt.subplot(2, 3, 2)
plt.scatter(optimizer.values_P[0], optimizer.values_P[1], alpha=0.6, label='All Solutions')
plt.scatter(optimizer.values_P[0][fronts[0]], optimizer.values_P[1][fronts[0]],
c='red', s=100, label='Pareto Front')
plt.title('Objective Function Space')
plt.xlabel('Coverage Rate')
plt.ylabel('Energy Efficiency')
plt.legend()
plt.grid(True)
# 绘制优化历史
plt.subplot(2, 3, 3)
best_coverage = [np.max(vals[0]) for vals in optimizer.values_history]
best_energy = [np.max(vals[1]) for vals in optimizer.values_history]
plt.plot(best_coverage, label='Best Coverage')
plt.plot(best_energy, label='Best Energy Efficiency')
plt.title('Optimization History')
plt.xlabel('Generation')
plt.ylabel('Best Objective Value')
plt.legend()
plt.grid(True)
# 绘制种群多样性
plt.subplot(2, 3, 4)
diversity_coverage = [np.std(vals[0]) for vals in optimizer.values_history]
diversity_energy = [np.std(vals[1]) for vals in optimizer.values_history]
plt.plot(diversity_coverage, label='Coverage Diversity')
plt.plot(diversity_energy, label='Energy Diversity')
plt.title('Population Diversity')
plt.xlabel('Generation')
plt.ylabel('Standard Deviation')
plt.legend()
plt.grid(True)
# 绘制收敛性分析
plt.subplot(2, 3, 5)
avg_coverage = [np.mean(vals[0]) for vals in optimizer.values_history]
avg_energy = [np.mean(vals[1]) for vals in optimizer.values_history]
plt.plot(avg_coverage, label='Average Coverage')
plt.plot(avg_energy, label='Average Energy Efficiency')
plt.title('Population Average')
plt.xlabel('Generation')
plt.ylabel('Average Objective Value')
plt.legend()
plt.grid(True)
# 绘制帕累托前沿
plt.subplot(2, 3, 6)
pareto_coverage = optimizer.values_P[0][fronts[0]]
pareto_energy = optimizer.values_P[1][fronts[0]]
plt.scatter(pareto_coverage, pareto_energy, c='red', s=100)
plt.title('Pareto Front')
plt.xlabel('Coverage Rate')
plt.ylabel('Energy Efficiency')
plt.grid(True)
plt.tight_layout()
plt.show()
# 输出结果统计
print(f"传感器网络部署优化完成")
print(f"找到 {len(pareto_solutions)} 个帕累托最优解")
print(f"最佳覆盖率: {np.max(optimizer.values_P[0]):.4f}")
print(f"最佳能量效率: {np.max(optimizer.values_P[1]):.4f}")