import pandas as pd
import numpy as np
import math
import heapq
import matplotlib.pyplot as plt
# 读取Excel数据,假设第一行为列名
data = pd.read_excel('概率网格.xlsx')
# 使用正确的列名:根据用户数据描述
points = data[['横向网格位置x', '纵向网格位置y', '发现概率']].values
# 计算距离目的地(24,1)的欧几里得距离(假设网格坐标即公里数)
def calculate_distance(x, y):
return math.sqrt((x - 24)**2 + (y - 1)**2)
# 筛选候选起始点:距离 > 12km
candidate_starts = [] # 存储候选点的原始坐标和概率
for point in points:
x, y, p = point
if calculate_distance(x, y) > 12:
candidate_starts.append((x, y, p))
# 网格尺寸:x从1到48,y从1到25
grid_size = (25, 48) # 注意:数组形状为 (y_size, x_size),即25行48列
# 初始化权重网格和距离数组
weights = np.full(grid_size, 1e10) # 初始化为极大值
predecessors = np.full(grid_size, None, dtype=object) # 记录前驱节点,初始为None
# 填充权重网格:遍历所有点
for point in points:
x, y, p = point
# 转换坐标到数组索引:x从1-48 -> 索引0-47, y从1-25 -> 索引0-24
idx_x = x - 1
idx_y = y - 1
if x == 24 and y == 1: # 目的地,权重设为0
weights[idx_y, idx_x] = 0
else:
if p == 1:
weights[idx_y, idx_x] = 1e10 # p=1时权重极大
else:
weights[idx_y, idx_x] = -math.log(1 - p)
# Dijkstra算法:从目的地(24,1)开始
# 目的地数组索引:x=24 -> idx_x=23, y=1 -> idx_y=0
start_node = (0, 23) # (y_index, x_index)
dist = np.full(grid_size, np.inf) # 初始化距离为无穷大
dist[start_node] = 0
# 优先队列:(当前路径权重, (y_index, x_index))
heap = [(0, start_node)]
predecessors[start_node] = None
# 8连通移动方向: (dy, dx)
directions = [(dy, dx) for dx in (-1, 0, 1) for dy in (-1, 0, 1) if not (dx == 0 and dy == 0)]
while heap:
d, node = heapq.heappop(heap)
y_idx, x_idx = node
# 如果当前距离大于已知距离,跳过
if d > dist[y_idx, x_idx]:
continue
for dy, dx in directions:
ny = y_idx + dy
nx = x_idx + dx
if 0 <= ny < grid_size[0] and 0 <= nx < grid_size[1]: # 检查边界
neighbor = (ny, nx)
new_d = d + weights[ny, nx]
if new_d < dist[ny, nx]:
dist[ny, nx] = new_d
predecessors[ny, nx] = node # 记录前驱节点
heapq.heappush(heap, (new_d, neighbor))
# 选择最优起始点:候选点中路径权重最小
min_weight = np.inf
best_start = None
for x, y, p in candidate_starts:
idx_x = x - 1
idx_y = y - 1
if dist[idx_y, idx_x] < min_weight:
min_weight = dist[idx_y, idx_x]
best_start = (x, y) # 存储原始坐标
# 重构路径:从最优起点到目的地
path = []
# 转换起点坐标到数组索引
current = (best_start[1] - 1, best_start[0] - 1) # (y_index, x_index)
while current != start_node:
path.append(current)
current = predecessors[current] # 回溯前驱节点
path.append(start_node)
path.reverse() # 反转路径,从起点到目的地
# 准备可视化数据:创建概率网格数组
prob_grid = np.zeros(grid_size)
for point in points:
x, y, p = point
idx_x = x - 1
idx_y = y - 1
prob_grid[idx_y, idx_x] = p
# 可视化
plt.figure(figsize=(10, 6))
# 显示概率热图
plt.imshow(prob_grid, cmap='hot', interpolation='nearest', origin='lower')
plt.colorbar(label='Detection Probability')
# 绘制路径:转换路径点到原始坐标
path_x = [x_idx + 1 for y_idx, x_idx in path]
path_y = [y_idx + 1 for y_idx, x_idx in path]
plt.plot(path_x, path_y, 'b-', linewidth=2, label='Path')
# 标记目的地和起点
plt.scatter(24, 1, c='green', marker='*', s=200, label='Destination (24,1)')
plt.scatter(best_start[0], best_start[1], c='red', marker='o', s=100, label='Start')
plt.xlabel('X Grid Position')
plt.ylabel('Y Grid Position')
plt.title('Optimal Path with Minimum Detection Probability')
plt.legend()
plt.grid(True)
plt.show()
题干:将某水域划分为48×25的网格,已知各个网格中发现无人艇的概率和每个网格的水深某重点防卫位置位于(24,1)处,现在需要求出无人机从12km外前往该位置的路径,使无人艇被发现的概率最小。
实验要求:从提供的Excel表格中读取网络节点和探测概率数据;目的地固定,起始点C需在目的地周围12km范围外;找出使探测概率最低的移动路径并进行可视化。
代码缺陷:未从距离目的地最近且满足条件的点出发,使被发现概率过大
要求在不改代码框架的情况下,修改代码,并完全实现功能,编程代码语法正确,仔细检查后再输出