mr-element 2023-12-08 15:55 采纳率: 60%
浏览 6
已结题

关于python的搜索算法路径规划问题

我想让节点 Arad 从出发,需要分别到达 Pitesti、Neamt、Eforie 三个节点(无先后顺序),步数应尽可能少,代价应尽可能低。
目前我的程序已经先写完了,但是运行的时候会随机出来两个结果:
第一个结果(正确结果):Shortest path: ['Arad', 'Timisoara', 'Drobeta', 'Pitesti', 'Urziceni', 'Bucharest', 'Eforie', 'Bucharest', 'Hirsova', 'Neamt']
Shortest path cost: 127
但是Shortest path cost:的结果是错误的,正确结果应该是87
第二个结果(错误结果,Shortest path和hortest path cost均错误):Shortest path: ['Arad', 'Sibiu', 'Fagaras', 'Rimnicu Vilcea', 'Neamt', 'Hirsova', 'Bucharest', 'Eforie', 'Bucharest', 'Urziceni', 'Pitesti']
Shortest path cost: 127
应该如何修改我的程序呢
我的程序如下:

import heapq
import itertools
def calculate_distances(graph, starting_vertex, targets):
     distances = {vertex: (float('infinity'), None) for vertex in graph}
     distances[starting_vertex] = (0, starting_vertex)

     priority_queue = [(0, starting_vertex)]
     visited = set()
     visited_targets = targets.copy()  # Copy the targets to operate on

     while priority_queue and visited_targets:
         current_distance, current_vertex = heapq.heappop(priority_queue)

         if current_vertex in visited_targets:
             visited_targets.remove(current_vertex)

         if current_vertex in visited:
             continue

         visited.add(current_vertex)

         for neighbor, weight in graph[current_vertex].items():
             distance = current_distance + weight

             if distance < distances[neighbor][0]:
                 distances[neighbor] = (distance, current_vertex)
                 heapq.heappush(priority_queue, (distance, neighbor))

     return distances



def find_path(distances, target, starting_vertex):
     path = []
     cost = distances[target][0]
     while target is not None and target != starting_vertex:
         path.append(target)
         target = distances[target][1]
     path.append(starting_vertex)  # Add the starting vertex at the end
     return path[::-1], cost


def find_shortest_path(graph, starting_vertex, targets):
     min_path = None
     min_cost = float('infinity')

     # Generate all permutations of the targets
     for permutation in itertools.permutations(targets):
         total_cost = 0
         current_vertex = starting_vertex
         path = [starting_vertex]

         # Calculate the total cost of visiting the targets in the current permutation
         for target in permutation:
             distances = calculate_distances(graph, current_vertex, {target})
             segment_path, segment_cost = find_path(distances, target, current_vertex)
             total_cost += segment_cost
             current_vertex = target
             # Add the segment path except the starting vertex to avoid duplicates
             path.extend(segment_path[1:])

         # Calculate the cost of returning to the starting vertex
         distances = calculate_distances(graph, current_vertex, {starting_vertex})
         return_path, return_cost = find_path(distances, starting_vertex, current_vertex)
         total_cost += return_cost

         # Check if the current permutation has the lowest cost
         if total_cost < min_cost:
             min_cost = total_cost
             min_path = path

     return min_path, min_cost

graph = {
     'Arad': {'Zerind': 15, 'Sibiu': 10, 'Timisoara': 12},
     'Zerind': {'Arad': 15, 'Oradea': 15, 'Sibiu': 8},
     'Oradea': {'Zerind': 15, 'Fagaras': 7, 'Iasi': 9},
     'Iasi': {'Oradea': 9, 'Neamt': 15, 'Vaslui': 18},
     'Vaslui': {'Iasi': 18, 'Neamt': 13, 'Eforie': 16, 'Glurgiu': 9},
     'Eforie': {'Vaslui': 16, 'Glurgiu': 7, 'Bucharest': 8, 'Connecticut': 18},
     'Connecticut': {'Eforie': 18, 'Bucharest': 9, 'Craiova': 19},
     'Craiova': {'Drobeta': 11, 'Pitesti': 12, 'Bucharest': 15, 'Connecticut': 19},
     'Drobeta': {'Craiova': 11, 'Pitesti': 13, 'Mehadia': 7, 'Lugoj': 8, 'Timisoara': 13},
     'Timisoara': {'Arad': 12, 'Lugoj': 8, 'Drobeta': 13},
     'Sibiu': {'Zerind': 8, 'Arad': 10, 'Lugoj': 11, 'Fagaras': 10},
     'Fagaras': {'Sibiu': 10, 'Oradea': 7, 'Rimnicu Vilcea': 9, 'Lugoj': 12, 'Atlanta': 12},
     'Rimnicu Vilcea': {'Fagaras': 9, 'Neamt': 11, 'Urziceni': 14, 'Atlanta': 6},
     'Neamt': {'Rimnicu Vilcea': 11, 'Iasi': 15, 'Vaslui': 13, 'Hirsova': 11},
     'Hirsova': {'Neamt': 11, 'Glurgiu': 10, 'Bucharest': 8, 'Urziceni': 13},
     'Glurgiu': {'Hirsova': 10, 'Eforie': 7, 'Vaslui': 9},
     'Lugoj': {'Timisoara': 8, 'Mehadia': 11, 'Fagaras': 12, 'Sibiu': 11, 'Atlanta': 7, 'Urziceni': 16, 'Drobeta': 8},
     'Atlanta': {'Lugoj': 7, 'Fagaras': 4, 'Rimnicu Vilcea': 6, 'Urziceni': 8},
     'Urziceni': {'Atlanta': 8, 'Rimnicu Vilcea': 14, 'Hirsova': 13, 'Bucharest': 7, 'Lugoj': 16, 'Pitesti': 7},
     'Bucharest': {'Urziceni': 7, 'Hirsova': 8, 'Eforie': 8, 'Craiova': 15, 'Pitesti': 15, 'Connecticut': 9},
     'Pitesti': {'Bucharest': 15, 'Craiova': 12, 'Drobeta': 13, 'Mehadia': 10, 'Urziceni': 7},
     'Mehadia': {'Drobeta': 7, 'Lugoj': 11, 'Pitesti': 10}
 }

targets = {'Pitesti', 'Neamt', 'Eforie'}
starting_vertex = 'Arad'
distances = calculate_distances(graph, starting_vertex, targets.copy())

total_cost = 0
paths = {}
for target in targets:
     path, cost = find_path(distances, target, starting_vertex)
     paths[target] = path
     total_cost += cost

shortest_path, shortest_path_cost = find_shortest_path(graph, starting_vertex, targets)

print("Shortest path:", shortest_path)
print("Shortest path cost:", shortest_path_cost)
  • 写回答

16条回答 默认 最新

  • 专家-郭老师 Java领域新星创作者 2023-12-08 16:27
    关注
    获得0.60元问题酬金

    结果是87吗?

    img

    代码:

    import heapq
    import itertools
    
    
    def calculate_distances(graph, starting_vertex, targets):
        distances = {vertex: (float('infinity'), None) for vertex in graph}
        distances[starting_vertex] = (0, starting_vertex)
    
        priority_queue = [(0, starting_vertex)]
        visited = set()
        visited_targets = targets.copy()  # Copy the targets to operate on
    
        while priority_queue and visited_targets:
            current_distance, current_vertex = heapq.heappop(priority_queue)
    
            if current_vertex in visited_targets:
                visited_targets.remove(current_vertex)
    
            if current_vertex in visited:
                continue
    
            visited.add(current_vertex)
    
            for neighbor, weight in graph[current_vertex].items():
                distance = current_distance + weight
    
                if distance < distances[neighbor][0]:
                    distances[neighbor] = (distance, current_vertex)
                    heapq.heappush(priority_queue, (distance, neighbor))
    
        return distances
    
    
    def find_path(distances, target, starting_vertex):
        path = []
        cost = distances[target][0]
        while target is not None and target != starting_vertex:
            path.append(target)
            target = distances[target][1]
        path.append(starting_vertex)  # Add the starting vertex at the end
        return path[::-1], cost
    
    
    def find_shortest_path(graph, starting_vertex, targets):
        min_path = None
        min_cost = float('infinity')
    
        # Generate all permutations of the targets
        for permutation in itertools.permutations(targets):
            total_cost = 0
            current_vertex = starting_vertex
            path = [starting_vertex]
    
            # Calculate the total cost of visiting the targets in the current permutation
            for target in permutation:
                distances = calculate_distances(graph, current_vertex, {target})
                segment_path, segment_cost = find_path(distances, target, current_vertex)
                total_cost += segment_cost
                current_vertex = target  # 设置当前目标点为下一段路径的出发点
                # Add the segment path except the starting vertex to avoid duplicates
                path.extend(segment_path[1:])
    
            # 检查当前的路径排列是否满足最低代价条件
            if total_cost < min_cost:
                min_cost = total_cost
                min_path = path
    
        return min_path, min_cost
    
    
    graph = {
        'Arad': {'Zerind': 15, 'Sibiu': 10, 'Timisoara': 12},
        'Zerind': {'Arad': 15, 'Oradea': 15, 'Sibiu': 8},
        'Oradea': {'Zerind': 15, 'Fagaras': 7, 'Iasi': 9},
        'Iasi': {'Oradea': 9, 'Neamt': 15, 'Vaslui': 18},
        'Vaslui': {'Iasi': 18, 'Neamt': 13, 'Eforie': 16, 'Glurgiu': 9},
        'Eforie': {'Vaslui': 16, 'Glurgiu': 7, 'Bucharest': 8, 'Connecticut': 18},
        'Connecticut': {'Eforie': 18, 'Bucharest': 9, 'Craiova': 19},
        'Craiova': {'Drobeta': 11, 'Pitesti': 12, 'Bucharest': 15, 'Connecticut': 19},
        'Drobeta': {'Craiova': 11, 'Pitesti': 13, 'Mehadia': 7, 'Lugoj': 8, 'Timisoara': 13},
        'Timisoara': {'Arad': 12, 'Lugoj': 8, 'Drobeta': 13},
        'Sibiu': {'Zerind': 8, 'Arad': 10, 'Lugoj': 11, 'Fagaras': 10},
        'Fagaras': {'Sibiu': 10, 'Oradea': 7, 'Rimnicu Vilcea': 9, 'Lugoj': 12, 'Atlanta': 12},
        'Rimnicu Vilcea': {'Fagaras': 9, 'Neamt': 11, 'Urziceni': 14, 'Atlanta': 6},
        'Neamt': {'Rimnicu Vilcea': 11, 'Iasi': 15, 'Vaslui': 13, 'Hirsova': 11},
        'Hirsova': {'Neamt': 11, 'Glurgiu': 10, 'Bucharest': 8, 'Urziceni': 13},
        'Glurgiu': {'Hirsova': 10, 'Eforie': 7, 'Vaslui': 9},
        'Lugoj': {'Timisoara': 8, 'Mehadia': 11, 'Fagaras': 12, 'Sibiu': 11, 'Atlanta': 7, 'Urziceni': 16, 'Drobeta': 8},
        'Atlanta': {'Lugoj': 7, 'Fagaras': 4, 'Rimnicu Vilcea': 6, 'Urziceni': 8},
        'Urziceni': {'Atlanta': 8, 'Rimnicu Vilcea': 14, 'Hirsova': 13, 'Bucharest': 7, 'Lugoj': 16, 'Pitesti': 7},
        'Bucharest': {'Urziceni': 7, 'Hirsova': 8, 'Eforie': 8, 'Craiova': 15, 'Pitesti': 15, 'Connecticut': 9},
        'Pitesti': {'Bucharest': 15, 'Craiova': 12, 'Drobeta': 13, 'Mehadia': 10, 'Urziceni': 7},
        'Mehadia': {'Drobeta': 7, 'Lugoj': 11, 'Pitesti': 10}
    }
    
    targets = {'Pitesti', 'Neamt', 'Eforie'}
    starting_vertex = 'Arad'
    distances = calculate_distances(graph, starting_vertex, targets.copy())
    
    total_cost = 0
    paths = {}
    for target in targets:
        path, cost = find_path(distances, target, starting_vertex)
        paths[target] = path
        total_cost += cost
    
    shortest_path, shortest_path_cost = find_shortest_path(graph, starting_vertex, targets)
    
    print("Shortest path:", shortest_path)
    print("Shortest path cost:", shortest_path_cost)
    
    
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月16日
  • 修改了问题 12月8日
  • 创建了问题 12月8日

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向