广度优先和深度优先和贪心法和Dijkstra和A*算法的总结

广度优先总结

1.在各个方向上都有同样的探索。

对于一个图他的广度优先遍历的步骤:
 1.利用队列实现
 2.从源节点开始依次按照宽度进队列,然后弹出
 3.每弹出一个节点,就把该节点所有没有进过队列的邻接点放入队列
 4.直到队列变空

frontier = Queue()
frontier.put(start )
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal: 
      break           

   for next in graph.neighbors(current):
      if next not in came_from:
         frontier.put(next)
         came_from[next] = current

深度优先总结

1.在各个方向上都有同样权重的探索。遍历的顺序不一样

针对一个图的他深度优先遍历的步骤:
1.利用栈实现
2.从源节点开始把节点按照深度放入栈,然后弹出
3.每弹出一个点,把该节点下一个没有进过栈的邻接点放入栈
4.直到栈变空

 

Dijkstra总结:

1.考虑到成本,对于路径搜索,走不同的路径他花的成本是不一样的。

2.我们添加一个新的变量跟踪从开始位置的总移动成本。我们想在决定如何评估地点时考虑到移动成本;让我们将队列转换为优先队列。我们可能会多次访问一个位置,如果成本变小了就更新字典逻辑。

3.从起始点开始在森林中缓慢地扩张

 

《广度优先和深度优先和贪心法和Dijkstra和A*算法的总结》

 

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      new_cost = cost_so_far[current] + graph.cost(current, next)
      if next not in cost_so_far or new_cost < cost_so_far[next]:
         cost_so_far[next] = new_cost
         priority = new_cost
         frontier.put(next, priority)
         came_from[next] = current

 

 

贪心法总结:

贪心算法是指在对问题求解时,比如路径寻找,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。是一种启发式的方法

 

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      if next not in came_from:
         priority = heuristic(goal, next)
         frontier.put(next, priority)
         came_from[next] = current

 

A*总结:

Dijkstra和贪心算法的缺点:

1.Dijkstra算法很好地找到了最短路径,但它浪费了时间去探索那些没有前途的方向。

2.贪婪的最好的第一次搜索在有希望的方向上探索,但它可能找不到最短的路径。

 

A*的做法:

A*算法结合了这两种方法,算法使用从开始的实际距离和估计的距离到目标的距离。

算法:Dijkstra算法计算出起点的距离。贪婪的第一次搜索估计到目标点的距离。A是用这两个距离的和。

 

在不同的地方开了一个洞。你会发现,当贪婪的最好的第一次搜索找到正确答案时,你也会发现它,探索同一领域。当贪婪的第一次搜索找到了错误的答案(较长的路径)时,找到了正确的答案,就像Dijkstra算法所做的那样,但仍然比Dijkstra算法所做的要少。

 

A算法只要启发式距离不高于实际距离,就会找到一条最优路径,就像Dijkstra算法所做的那样。A使用启发式方法对节点重新排序,以便更有可能更快地遇到目标节点。

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      new_cost = cost_so_far[current] + graph.cost(current, next)
      if next not in cost_so_far or new_cost < cost_so_far[next]:
         cost_so_far[next] = new_cost
         priority = new_cost + heuristic(goal, next)
         frontier.put(next, priority)
         came_from[next] = current

 

区别:

1.如果您想要找到所有位置的路径,请使用广度优先搜索或Dijkstra算法。如果移动成本都是一样的,使用广度优先搜索;如果移动成本不同,使用Dijkstra算法。

2.如果你想找到一个位置的路径,使用贪婪最好的第一次搜索或A。在大多数情况下使用A。当你想要使用贪婪最好的第一次搜索时,考虑使用一个“不可接受”的启发式。

3 那么最佳路径呢?广度优先搜索和Dijkstra算法保证在输入图中找到最短路径。贪婪最好的第一次搜索不是。如果启发式永远不会大于实际距离,则保证找到最短路径。当启发式变得更小时,就变成了Dijkstra算法。当启发式变得更大时,就变成了贪婪的第一次搜索。

 

3D-A*算法的改进:

1.更改输入为3维的输入,以及包含权重和障碍点。

2.更改节点的邻居包含时间维度,即(-1,0,1)(1,0,1)(0,-1,1)(0,1,1),(0,0,1)

计算量大的改进:

3.因为时间的特殊性就是,过去了,不能回来了,根据这个特性,当没有可走的路径时,普通的A*是需要访问到所有节点的,将一些不可能到达终点的一些点设为障碍点。节省了大量时间1/3的时间。

 

 

 

 

 

 

 

 

 

 

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/u014073295/article/details/82721596
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞