图论DFS(Depth First Search)Algorithm深度优先搜索遍历空间平面图选择路径,networkx,Python

x33g5p2x  于2021-12-22 转载在 Go  
字(3.9k)|赞(0)|评价(0)|浏览(412)

图论DFS(Depth First Search)Algorithm深度优先搜索遍历空间平面图选择路径,networkx,Python

程序初始代码是模式0,即随机生成最多20个障碍物点,验证算法的效果。打红色X点表示此路不通。出发点是(1,1),终点是(5,7)。最终红色的点即为选出的路径,并用红色的粗线连起来。

  1. import random
  2. import networkx as nx
  3. import matplotlib.pyplot as plt
  4. WALKABLE = 'walkable'
  5. PARENT = 'parent'
  6. VISITED = 'visited'
  7. def my_graph():
  8. M = 7
  9. N = 9
  10. G = nx.grid_2d_graph(m=M, n=N)
  11. pos = nx.spring_layout(G, iterations=100)
  12. nx.draw_networkx(G, pos=pos,
  13. # labels=labels, #labels = dict(((i, j), 'Phil') for i, j in G.nodes())
  14. font_size=8,
  15. font_color='white',
  16. node_color='green',
  17. node_size=500,
  18. width=1)
  19. START = (1, 1)
  20. GOAL = (M - 1 - 1, N - 1 - 1)
  21. # 0,随机生成障碍物点
  22. # 1,精心挑选的障碍物构成陷阱
  23. obstacle_mode = 0
  24. road_closed_nodes = []
  25. if obstacle_mode == 0:
  26. obstacle = 20 # 障碍物(断点、不可达点)数量
  27. road_closed_nodes = obstacle_nodes(G, START, GOAL, obstacle, M, N)
  28. elif obstacle_mode == 1:
  29. road_closed_nodes = dummy_nodes(G)
  30. nx.draw_networkx_nodes(
  31. G, pos,
  32. nodelist=road_closed_nodes,
  33. node_size=500,
  34. node_color="red",
  35. node_shape="x",
  36. # alpha=0.3,
  37. label='x'
  38. )
  39. dfs(G, START, GOAL)
  40. path = find_path_by_parent(G, START, GOAL)
  41. print('path', path)
  42. nx.draw_networkx_nodes(
  43. G, pos,
  44. nodelist=path,
  45. node_size=400,
  46. node_color="red",
  47. node_shape='o',
  48. # alpha=0.3,
  49. # label='NO'
  50. )
  51. # nx.draw_networkx_nodes(
  52. # G, pos,
  53. # nodelist=path,
  54. # node_size=100,
  55. # node_color="yellow",
  56. # node_shape='*',
  57. # # alpha=0.3,
  58. # # label='NO'
  59. # )
  60. path_edges = []
  61. for i in range(len(path)):
  62. if (i + 1) == len(path):
  63. break
  64. path_edges.append((path[i], path[i + 1]))
  65. print('path_edges', path_edges)
  66. # 把path着色加粗重新描边
  67. nx.draw_networkx_edges(G, pos,
  68. edgelist=path_edges,
  69. width=8,
  70. alpha=0.5,
  71. edge_color="r")
  72. plt.axis('off')
  73. plt.show()
  74. # 基于栈实深度优先遍历搜索
  75. def dfs(G, START, GOAL):
  76. for n in G.nodes():
  77. G.nodes[n]['visited'] = False
  78. stack = [] # 用列表当作一个栈,只在栈顶操作(数组的第1个位置)
  79. stack.append(START)
  80. close_list = []
  81. while True:
  82. if len(stack) == 0:
  83. break
  84. print('-----')
  85. print('stack-', stack)
  86. visit_node = stack[0]
  87. G.nodes[visit_node]['visited'] = True
  88. print('访问', visit_node)
  89. if visit_node == GOAL:
  90. break
  91. close_list.append(visit_node)
  92. count = 0
  93. neighbors = nx.neighbors(G, visit_node)
  94. for node in neighbors:
  95. visited = G.nodes[node][VISITED]
  96. try:
  97. walkable = G.nodes[node][WALKABLE]
  98. except:
  99. walkable = True
  100. if (visited) or (node in stack) or (node in close_list) or (not walkable):
  101. continue
  102. G.nodes[node][PARENT] = visit_node
  103. stack.append(node)
  104. count = count + 1
  105. if count == 0:
  106. print(visit_node, '尽头')
  107. del (stack[0])
  108. print('弹出', visit_node)
  109. print('stack--', stack)
  110. return stack
  111. def find_path_by_parent(G, START, GOAL):
  112. t = GOAL
  113. path = [t]
  114. is_find = False
  115. while not is_find:
  116. for n in G.nodes(data=True):
  117. if n[0] == t:
  118. parent = n[1][PARENT]
  119. path.append(parent)
  120. if parent == START:
  121. is_find = True
  122. break
  123. t = parent
  124. list.reverse(path)
  125. return path
  126. # 障碍物点
  127. def obstacle_nodes(G, START, GOAL, obstacle, M, N):
  128. road_closed_nodes = []
  129. for i in range(obstacle):
  130. n = (random.randint(0, M - 1), random.randint(0, N - 1))
  131. if n == START or n == GOAL:
  132. continue
  133. if n in road_closed_nodes:
  134. continue
  135. G.nodes[n][WALKABLE] = False
  136. road_closed_nodes.append(n)
  137. return road_closed_nodes
  138. def dummy_nodes(G):
  139. fun_nodes = []
  140. n0 = (1, 2)
  141. G.nodes[n0][WALKABLE] = False
  142. fun_nodes.append(n0)
  143. n1 = (1, 3)
  144. G.nodes[n1][WALKABLE] = False
  145. fun_nodes.append(n1)
  146. n2 = (1, 4)
  147. G.nodes[n2][WALKABLE] = False
  148. fun_nodes.append(n2)
  149. n3 = (1, 5)
  150. G.nodes[n3][WALKABLE] = False
  151. fun_nodes.append(n3)
  152. n4 = (1, 6)
  153. G.nodes[n4][WALKABLE] = False
  154. fun_nodes.append(n4)
  155. n5 = (2, 6)
  156. G.nodes[n5][WALKABLE] = False
  157. fun_nodes.append(n5)
  158. n6 = (3, 6)
  159. G.nodes[n6][WALKABLE] = False
  160. fun_nodes.append(n6)
  161. n7 = (4, 6)
  162. G.nodes[n7][WALKABLE] = False
  163. fun_nodes.append(n7)
  164. n8 = (5, 6)
  165. G.nodes[n8][WALKABLE] = False
  166. fun_nodes.append(n8)
  167. n9 = (5, 5)
  168. G.nodes[n9][WALKABLE] = False
  169. fun_nodes.append(n9)
  170. n10 = (5, 4)
  171. G.nodes[n10][WALKABLE] = False
  172. fun_nodes.append(n10)
  173. n11 = (5, 3)
  174. G.nodes[n11][WALKABLE] = False
  175. fun_nodes.append(n11)
  176. n12 = (5, 2)
  177. G.nodes[n12][WALKABLE] = False
  178. fun_nodes.append(n12)
  179. return fun_nodes
  180. if __name__ == '__main__':
  181. my_graph()

算法选路效果:

由于代码中对于随机生成的障碍物点限制不多(不等于出发点和终点即可),那么极大概率生成的点集把出发点到终点之间的路线堵死,最终选路选不出来,出于简单代码说明算法的目的,程序对这些情况未增加代码量规避处理。

现在,使用障碍物模式1,

  1. obstacle_mode = 1

故意生成一组精心挑选的点,这些点形成一个凹形的围墙,围墙正面对出发点,同时把出发点改成(2,2),

  1. START = (2, 2)

看看算法的表现:

算法走出的路线很聪明,机智的以捷径绕过围墙。

图论BFS(Breath First Search)Algorithm广度优先搜索遍历空间平面网格图路径选择,networkx,Python_Zhang Phil-CSDN博客

networkx图论Dijkstra Algorithm最短路径实现,Python_Zhang Phil-CSDN博客

相关文章

最新文章

更多