你好,看了你的那个关于无向图的最短路径问题,怎么样修改才能实现任意两点经过特定点的问题呢,怎么样能实现从一点出发经过特定点并返回那
具体问题为给出了该城市的交通地图数据,包含路口坐标信息、道路连接信息和道路等级信息。道路等级分为1级,2级和3级,其中1级道路时速60km/h、2级道路时速40km/h、3级道路时速30km/h。车辆通过路口时,左转和直行需要等待红绿灯,等待时间平均1分钟。该出租车公司三公里内起步价10元,超出后收费2.7公里/元,等候时间0.8元/分钟。
如果位于路口1的某乘客包乘一辆出租车,去位于标号为47,49,50,52,58,68,71,73,75,77,79路口的景点观光并回到路口1,请给出费用最少的行驶路线
https://kdocs.cn/l/cosN116RmquZ
import heapq
import math
# 构建图
graph = {}
with open('map.txt', 'r') as f:
for line in f.readlines():
if line.startswith('V'):
_, node, x, y = line.strip().split()
graph[node] = {'x': float(x), 'y': float(y), 'neighbors': {}}
elif line.startswith('E'):
_, start, end, level = line.strip().split()
distance = math.sqrt((graph[start]['x'] - graph[end]['x']) ** 2 + (graph[start]['y'] - graph[end]['y']) ** 2)
speed = 60 if level == '1' else 40 if level == '2' else 30
time = distance / (speed / 60)
graph[start]['neighbors'][end] = time
graph[end]['neighbors'][start] = time
# 初始化
start_node = '1'
end_nodes = ['47', '49', '50', '52', '58', '68', '71', '73', '75', '77', '79']
distances = {node: float('inf') for node in graph}
distances[start_node] = 0
previous_nodes = {node: None for node in graph}
# 迭代更新
priority_queue = [(0, start_node)]
while len(priority_queue) > 0:
current_distance, current_node = heapq.heappop(priority_queue)
if current_distance > distances[current_node]:
continue
for neighbor, time in graph[current_node]['neighbors'].items():
distance = current_distance + time
if distance < distances[neighbor]:
distances[neighbor] = distance
previous_nodes[neighbor] = current_node
heapq.heappush(priority_queue, (distance, neighbor))
# 回溯路径
path = []
current_node = end_nodes[0]
while current_node is not None:
path.append(current_node)
current_node = previous_nodes[current_node]
path.reverse()
# 计算费用
total_distance = 0
total_time = 0
total_wait_time = 0
for i in range(len(path) - 1):
start_node = path[i]
end_node = path[i+1]
total_distance += math.sqrt((graph[start_node]['x'] - graph[end_node]['x']) ** 2 + (graph[start_node]['y'] - graph[end_node]['y']) ** 2)
total_time += graph[start_node]['neighbors'][end_node]
if end_node in end_nodes:
total_wait_time += 1
total_distance /= 1000
total_cost = 10 + max(total_distance - 3, 0) * 2.7 + total_wait_time * 0.8
print('最短路径为:', ' -> '.join(path))
print('总距离为:', round(total_distance, 2), '公里')
print('总时间为:', round(total_time, 2), '分钟')
print('等待时间为:', total_wait_time, '分钟')
print('总费用为:', round(total_cost, 2), '元')
特定点只有一个的话,可以做两次最短路径算法。
特定点多的话,如果特定点有顺序可以拆分为多段起点和终点的最短路,无顺序要求的话用最小生成树求最短路就好了