简体   繁体   English

在有向图中使用字典和邻接列表查找最短路径

[英]Find the Shortest Path using Dictionary and Ajacency list in Directional Graph

I am trying to create a function that accepts a start and stop number then returns a list of nodes/numbers which represent the shorest path to get from Start to Stop in the graph.我正在尝试创建一个 function,它接受一个开始和停止编号,然后返回一个节点/数字列表,这些节点/数字代表图中从开始到停止的最短路径。 Right now my grpah is stored in a object Graph that has an object varaible Verticies which is the following dictionary where the key is the node and the values are its connected nodes现在我的 grpah 存储在一个 object Graph 中,它有一个 object varaible Verticies 这是下面的字典,其中键是节点,值是它连接的节点

{1: [10, 12, 11],
 9: [1, 11, 12, 4],
 7: [12],
 10: [5, 4, 1, 11],
 12: [],
 4: [9, 11],
 11: [7, 9],
 5: [12]}

I am trying to get the shorest path from 1 to 7 and would expect the funciton to return a list of [11,7] ie the path to get from 1 to 7 and the amount of steps it would take ie 2.我正在尝试获得从 1 到 7 的最短路径,并希望函数返回 [11,7] 的列表,即从 1 到 7 的路径以及它需要的步数,即 2。

I am using recursion to do a depth first search and updating a dictionary with the nodes and amount of steps it takes to get to the node from the start node.我正在使用递归进行深度优先搜索,并使用节点和从起始节点到达节点所需的步数更新字典。

I can get the function to print the shorest path if I use print but I am unsure on how to get a recursive function to return the shorests path as the function returns the shorest path when It finds the end node or finds a better route however it only returns to another inner recursive function which then modfifies path to remove the last node added.如果我使用 print,我可以获得 function 来打印最短路径,但我不确定如何获得递归 function 以返回最短路径,因为 function 在找到结束节点或找到更好的路由时返回最短路径只返回到另一个内部递归 function 然后修改路径以删除最后添加的节点。

I am not sure how I can return path, while also updating path each time I come out of a funciton to remove the node that I searched through?我不确定如何返回路径,同时每次我从函数中出来以删除我搜索过的节点时也会更新路径? Would it be recomneded to store the path list into another list then try to return that list that way when the new list gets returned it is not changed by path being changed?是否建议将路径列表存储到另一个列表中,然后在返回新列表时尝试以这种方式返回该列表,它不会因路径更改而更改?

My funciton is below我的功能在下面

def shortest_path(from_node,to_node,graph,visited={},Cost=0,path=[]):
    connections=graph.Verticies[from_node]
    if to_node in connections:
        if to_node in list(visited.keys()):
            if Cost+1<visited[to_node]:
                visited[to_node]=Cost+1
                try:
                    path.remove(to_node)
                except:
                    pass
                path.append(to_node)
                return((path,Cost+1))
            else:
                pass
        else:
            visited[to_node]=Cost+1
            path.append(to_node)
            return((path,Cost+1))
    else:
        for val in connections:
            if val in list(visited.keys()):
                if Cost+1<visited[val]:
                    visited[val]=Cost+1
                    Cost+=1
                    path.append(val)
                    optimal_path=shortest_path(val,to_node,graph,visited,Cost)
                    path.remove(val)
                    Cost-=1
                else:
                    continue
            else:
                visited[val]=Cost+1
                Cost+=1
                path.append(val)
                optimal_path=shortest_path(val,to_node,graph,visited,Cost)
                path.remove(val)
                Cost-=1
    return(path)
                
    

First, remember that the shortest distance between any two points is a straight line , or the hypotenuse .首先,记住任意两点之间的最短距离是直线,或者斜边 So the first thing you'll want to do in your function is check if it can go directly to the next input.所以你想要在你的 function 中做的第一件事是检查它是否可以 go 直接到下一个输入。 Something like this:是这样的:

if to_node in Graph[from_node]: #from_node is the variable and the key name
  return ([from_node, to_node])

if this doesn't work for the inputted values, which it will not the majority of the time, recursion will be necessary to find the shortest path.如果这对输入的值不起作用(大多数情况下不会),则需要递归来找到最短路径。

else:
  epic_list_object = [from_node]
  for i in Graph[from_node]:
    if to_node in Graph[i]:
      epic_list_object.append(i)
      epic_list_object.append(to_node)
      return epic_list_object
      break
    else:
      pass
# add recursion using for or while statements to the above function to support inputs that are farther than 2 apart :)

finally, if you want just the length, just use len(epic_list_object)-1最后,如果你只想要长度,只需使用len(epic_list_object)-1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM