Best-First Search 算法研究
Best-First Search(最佳优先搜索)算法是一种启发式搜索算法,用于在图或树的搜索空间中找到最佳解决方案。它通过评估每个搜索节点的启发式估计值
来决定搜索的方向,以期望更快地接近最优解
下面是 Best-First Search 算法的详细步骤:
- 初始化一个
优先级队列
(通常使用最小堆)和一个已访问节点的集合 - 将起始节点放入优先级队列中,并将其标记为已访问
- 当优先级队列不为空时,执行以下步骤:
- 从优先级队列中选择具有最小启发式估计值的节点
- 如果该节点是目标节点,则找到了最优解决方案,可以终止搜索
- 否则,扩展该节点,生成其所有相邻节点,并计算它们的启发式估计值
- 对于每个相邻节点,如果它未被访问过,则将其添加到优先级队列中,并将其标记为已访问
- 如果优先级队列为空而且没有找到目标节点,则表示搜索失败,没有可行的解决方案
Best-First Search 算法的伪代码如下
// Pseudocode for Best First Search
Best-First-Search(Graph g, Node start)
1) Create an empty PriorityQueue
PriorityQueue pq;
2) Insert "start" in pq.
pq.insert(start)
3) Until PriorityQueue is empty
u = PriorityQueue.DeleteMin
If u is the goal
Exit
Else
Foreach neighbor v of u
If v "Unvisited"
Mark v "Visited"
pq.insert(v)
Mark u "Examined"
End procedure
Best-First Search 算法的关键是启发式函数(heuristic function
),它用于评估搜索节点的优先级。启发式函数根据问题的特定信息,例如估计的代价、距离或其他相关因素,为每个节点分配一个估计值。该估计值指导搜索算法选择具有最佳可能性的节点
Best-First Search 算法的优点是可以在较短时间内找到一个相对好的解决方案,特别适用于问题空间庞大且搜索方向有明确指导的情况。然而,它并不能保证找到全局最优解
,因为它更关注当前搜索节点的启发式估计值而不是全局问题的性质
Best-First 算法是一种贪心算法
,一般通过定义一个启发式函数来引导着向离目标更近的方向前进,常见的启发式函数为欧氏距离(Euclidean Distance)或者曼哈顿距离(Manhattan Distance)
举个例子来说明,如下图,知道每个城市间的距离以及所有城市到 Bucharest
的直线距离
上图左侧可以看作带权值的无向图,而右侧的直线距离则可以当做启发函数
以 Bucharest 为终点,Arad
为起点
初始状态
扩展 Arad 后,从 Arad 出发,可以到的三个城市为Zerind(374),Sibiu(253)和Timisoara(329),括号中为启发函数(直线距离)的值,选择最小值对应的城市,即下一个遍历的城市为Sibiu
扩展 Sibiu 后,从 Sibiu 出发,可以到的城市有四个,同理选择启发函数值最小的城市Fagaras
(178)作为下一个遍历的城市
从Fagaras出发,有两个可以到达的城市,终点Bucharest(0)已经找到了
Best-First Search 算法不能保证得到全局最优解的原因在于其贪心
性质。该算法在每一步选择下一个节点时,仅仅考虑当前节点的局部最优选择,而不考虑全局的最优选择
具体来说,Best-First Search 算法根据某种启发式函数对节点进行评估和排序,然后选择评估值最小(或最大)的节点作为下一个探索的节点。这种局部最优的选择可能会导致算法陷入局部最优解,而无法找到全局最优解
另外,Best-First Search 算法还存在以下一些限制和局限性:
- 依赖于启发式函数:算法的效果高度依赖于所选择的启发式函数,不同的启发式函数可能导致不同的结果
- 受限于搜索空间:Best-First Search 算法仅搜索从起始节点到目标节点的路径,而无法保证搜索到其他潜在的更优解
- 缺乏回溯能力:Best-First Search 算法在选择下一个节点后无法回溯到之前的节点,因此可能会错过某些更优的路径
因此,尽管 Best-First Search 算法可以高效地在大规模图中找到较好的局部解,但不能保证得到全局最优解。对于需要确保全局最优解的问题,可以考虑其他更复杂的搜索算法,如 A* 算法或 Dijkstra算法,这些算法结合了启发式函数和全局路径权重的考虑,能够更有效地搜索全局最优解
可以看到当存在障碍物时 Best-First Search
算法搜索到的并不是最短路径
而用 A* 算法则可以快速搜索到可行的最短路径