Python中Dijkstra算法实现最短路径的问题,有没有老哥帮我看一看代码啊?

100,0,0,0,100,100,100
1000,20.892,986,602,138.97,206.2,10.44
200,25,25,10,1,50,25,140,30
输入格式是这样,每一行第一个数是地图限制,100 就说明这张图是 100x100,后面的点两两组合,第一个点(0,0)就是起点,最后一个点(100,100)就是终点,中间的点是可以去的城镇.
程序是模拟一个无人机从起点出发去往终点,最大移动距离 100,点与点之间移动举例按 math.sqrt(x_dis * x_dis + y_dis * y_dis)也就是欧几里得距离算.
如果点超出移动距离或者不在地图范围内是不算的.
案例输入的输出是
200.00
-1
115.14
import heapq
import sys
import math
sys.setrecursionlimit(10000)
INF = 999999999
class Point:
def init(self, x, y):
self.x = float(x)
self.y = float(y)
def getCost(p,c):
x_dis = abs(p.x - c.x)
y_dis = abs(p.y - c.y)
cost = math.sqrt(x_dis * x_dis + y_dis * y_dis)
return cost
def dijkstra(G, start, endp):
dis = dict((point, INF) for point in G)
dis[start] = 0.00
vis = dict((point, False) for point in G)
# heap
pq = []
heapq.heappush(pq, [dis[start], start])
path = dict((point, [start]) for point in G)
while len(pq) > 0:
v_dis, v = heapq.heappop(pq)
if vis[v] == True:
continue
vis[v] = True
p = path[v].copy()
for point in G:
distance = getCost(v,point)
if distance > 100.00:
continue
new_dis = dis[v] + distance

if new_dis < dis[point] and (not vis[point]):
dis[point] = new_dis

heapq.heappush(pq, [dis[point], point])
temp = p.copy()
temp.append(point)
path[point] = temp
distance = dis[endp]
if distance == INF:
print("-1")
else:
print("{:.2f}".format(distance))

while True:
try:
numbers = input().strip().split(",")
limit = int(numbers[0])
point_list = []
numbers = list(map(float, numbers))
stap = Point(numbers[1],numbers[2])
endp = Point(numbers[-2],numbers[-1])
if stap.x>limit or stap.y>limit or stap.x<0 or stap.y<0 :
print("-1")
elif endp.x>limit or endp.y>limit or endp.x<0 or endp.y<0 :
print("-1")
else:
for i in range(1, len(numbers), 2):
if numbers[i]<=limit and numbers[i+1]<=limit:
point_list.append(Point(numbers[i], numbers[i+1]))
dijkstra(point_list, point_list[0], point_list[-1])
except EOFError:
break

在一个黑箱运行测试输入显示部分答案错误,一共五个案例,我只有 1,2 是全对,3,4,5 正确率越来越低.
现在我的代码在本地能很好的输出答案,只好猜测是不是逻辑出了问题,有老哥帮忙看一下的话感激不尽!
Python中Dijkstra算法实现最短路径的问题,有没有老哥帮我看一看代码啊?


12 回复

能不能给个有高亮有缩进的代码 这种没缩进的看都不想看…


import heapq

def dijkstra(graph, start):
    """
    使用优先队列实现Dijkstra算法
    
    参数:
        graph: dict, 邻接表表示的图 {节点: [(邻居节点, 权重), ...]}
        start: 起始节点
    
    返回:
        distances: dict, 从起始点到各节点的最短距离
        previous: dict, 最短路径的前驱节点
    """
    # 初始化距离字典,所有节点距离设为无穷大
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    
    # 优先队列 (当前距离, 节点)
    priority_queue = [(0, start)]
    
    # 记录路径前驱节点
    previous = {node: None for node in graph}
    
    while priority_queue:
        current_distance, current_node = heapq.heappop(priority_queue)
        
        # 如果当前距离大于已记录距离,跳过
        if current_distance > distances[current_node]:
            continue
        
        # 遍历邻居节点
        for neighbor, weight in graph[current_node]:
            distance = current_distance + weight
            
            # 如果找到更短路径
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                previous[neighbor] = current_node
                heapq.heappush(priority_queue, (distance, neighbor))
    
    return distances, previous

def get_shortest_path(previous, target):
    """根据前驱节点字典重构最短路径"""
    path = []
    node = target
    
    while node is not None:
        path.append(node)
        node = previous[node]
    
    return path[::-1]  # 反转得到从起点到终点的路径

# 示例图
graph = {
    'A': [('B', 4), ('C', 2)],
    'B': [('C', 1), ('D', 5)],
    'C': [('D', 8), ('E', 10)],
    'D': [('E', 2)],
    'E': []
}

# 测试
start_node = 'A'
distances, previous = dijkstra(graph, start_node)

print("从节点 {} 出发的最短距离:".format(start_node))
for node in distances:
    print(f"到节点 {node}: {distances[node]}")

print("\n最短路径示例 (A -> E):")
path = get_shortest_path(previous, 'E')
print(" -> ".join(path))

核心要点:

  1. 优先队列优化:使用heapq实现最小堆,确保每次取距离最小的节点
  2. 距离松弛:发现更短路径时更新距离和前驱节点
  3. 路径重构:通过前驱节点字典反向追踪得到完整路径

常见问题检查:

  • 确保图使用邻接表正确表示
  • 权重必须为非负值(Dijkstra要求)
  • 处理不可达节点(距离保持inf

建议先检查图的表示是否正确。

你这样的代码和提问都是没有灵魂的。。。

1 哪里的题目
2 代码高亮

第一次发帖,不知道怎么设置.
那我发图好了,这是代码的图

图呢?

这代码不能格式化一下再贴过来?
用 Markdown 的
python<br>
格式下啊🙃

我已经上传了 gist 的版本,我试试看吧
python<br>import heapq<br>import sys<br>import math<br>sys.setrecursionlimit(10000)<br>INF = 999999999<br>class Point:<br> def __init__(self, x, y):<br> self.x = float(x)<br> self.y = float(y)<br>def getCost(p,c):<br> x_dis = abs(p.x - c.x)<br> y_dis = abs(p.y - c.y)<br> cost = math.sqrt(x_dis * x_dis + y_dis * y_dis)<br> return cost<br>def dijkstra(G, start, endp): <br> dis = dict((point, INF) for point in G) <br> dis[start] = 0.00<br> vis = dict((point, False) for point in G) <br> # heap<br> pq = [] <br> heapq.heappush(pq, [dis[start], start])<br> path = dict((point, [start]) for point in G) <br> while len(pq) &gt; 0:<br> v_dis, v = heapq.heappop(pq) <br> if vis[v] == True:<br> continue<br> vis[v] = True<br> p = path[v].copy() <br> for point in G: <br> distance = getCost(v,point)<br> if distance &gt; 100.00:<br> continue<br> new_dis = dis[v] + distance<br> <br> if new_dis &lt; dis[point] and (not vis[point]):<br> dis[point] = new_dis <br><br> heapq.heappush(pq, [dis[point], point])<br> temp = p.copy()<br> temp.append(point) <br> path[point] = temp <br> distance = dis[endp]<br> if distance == INF:<br> print("-1")<br> else:<br> print("{:.2f}".format(distance))<br><br>while True:<br> try:<br> numbers = input().strip().split(",")<br> limit = int(numbers[0])<br> point_list = []<br> numbers = list(map(float, numbers))<br> stap = Point(numbers[1],numbers[2])<br> endp = Point(numbers[-2],numbers[-1])<br> if stap.x&gt;limit or stap.y&gt;limit or stap.x&lt;0 or stap.y&lt;0 :<br> print("-1")<br> elif endp.x&gt;limit or endp.y&gt;limit or endp.x&lt;0 or endp.y&lt;0 :<br> print("-1")<br> else: <br> for i in range(1, len(numbers), 2):<br> if numbers[i]&lt;=limit and numbers[i+1]&lt;=limit:<br> point_list.append(Point(numbers[i], numbers[i+1]))<br> dijkstra(point_list, point_list[0], point_list[-1])<br> except EOFError:<br> break<br>

#8
飞机因为最近原因坏了,gist 估计是没办法。
评论区不支持 md 语法。

已经解决了,最后发现是一个返回值的问题,代码逻辑没有问题

回到顶部