人工智能学习笔记(三)有信息搜索

背景介绍

上一节我们介绍了无信息搜索,这种搜索方式看上去挺无脑的,因为我们的搜索是毫无方向的。这节我们将来了解有信息搜索,这种搜索方式相比无信息搜索能更有策略、更高效的进行问题求解。这节我们会先了解启发式函数,然后学习A星搜索。
在这里插入图片描述

一、问题描述

所有问题描述跟上一节是相同的,这节的具体例子也跟上一节是相同的。

二、A星算法和启发式函数(heuristic function)

启发式函数的作用是评估出从给定状态到目标的成本。比如我们看上面的例子。从Arad 到Bucharest的直线距离的评估就是启发式函数要做的事,启发式函数给出了从Arad到Bucharest的最小路径代价。启发式函数是在搜索算法利用问题额外信息的最常见的形式。在本文中我们规定启发式函数所给出的评估非负,即h(n)>=0。若n是目标节点,则h(n)=0。

下面我们将讲解评估函数f(n)。
Evaluation function f(n) = g(n) + h(n)

  • g(n)代表到目前为止到达n已经花费的成本
  • h(n)代表从n到目标最接近的花费成本,这个成本是评估出来的,并不是实际的成本。
  • f(n)代表穿过n到路径的成本,这个成本里有我们走到n时已经花费的成本,也有评估从n到目标预计花费的成本。

在实现A*算法时,我们需要使用一个能按照成本升序排列的FIFO队列。

A算法的前置知识已经讲完了,现在我们来讲讲什么是A算法。在搜索问题中,我们只需要最优解,然而在无信息搜索中我们并不能避免展开那些成本很高的路径。在A*搜索中,我们可以通过启发式函数来评估当前搜索路径的最小成本,从而避免继续扩展那些路径成本已经很高的路径了。

三、可采纳性和一致性

构建A算法的启发式函数是一个难点。为了让A算法的性能优越,我们需要让启发式函数符合两个特性——可采纳性(admissible)和一致性(consistency)。

1.可采纳性(admissible)

可采纳性是指启发函数不会过高估计到达目标的代价。因为g(n)是当前路径到达结点n的实际代价,而f(n)=g(n)+h(n),我们可以看出f(n)是永远不会超出经过结点n的解的实际成本的。如果h(n)给出的成本高于实际成本,A*算法将无法求出最优解。

2.一致性(consistency)

一致性条件一般作用于在图搜索中的A算法。如果对于每个结点n和通过任一行动a生成的n的每个后继节点n’,从结点n到达目标的估计代价不大于从n到n’的单步代价于从n’到达目标的估计代价之和: h(n)<=c(n,a,n’) + h(n’)。可能大家看到这段描述有点懵,我刚开始也不理解。这里我们画一个图来讲解。
在这里插入图片描述
整个路径是n是起点,经过n’到达终点G。我们在n点时f(n) = g(n)+h(n) = h(n).当我们到达了n’时f(n’) = g(n’)+h(n’) = c(n,a,n’)+h(n’).此时我们可以看出这其实是一个三角不等式。如果h(n)>c(n,a,n’)+h(n’)时,可采纳性不成立,A
算法搜不出最优解。如果从n经过n’到达G比h(n)的成本小,这个三角形也不成立,此时相当于给h(n)规定了一个下界。如果h(n)给出的评估成本过小,那么A*算法会搜索很多多余的节点,启发式函数也就失去了意义。

四、代码

可能大家看到这里已经一头雾水了,这里我们给出代码,通过代码来分析上面我们提到的性质。

def astar_search(problem, h=None, display=False):
    """A* search is best-first graph search with f(n) = g(n)+h(n).
    You need to specify the h function when you call astar_search, or
    else in your Problem subclass."""
    h = memoize(h or problem.h, 'h')
    return best_first_graph_search(problem, lambda n: n.path_cost + h(n), display)

def best_first_graph_search(problem, f, display=False):
    """Search the nodes with the lowest f scores first.
    You specify the function f(node) that you want to minimize; for example,
    if f is a heuristic estimate to the goal, then we have greedy best
    first search; if f is node.depth then we have breadth-first search.
    There is a subtlety: the line "f = memoize(f, 'f')" means that the f
    values will be cached on the nodes as they are computed. So after doing
    a best first search you can examine the f values of the path returned."""
    f = memoize(f, 'f')
    node = Node(problem.initial)
    frontier = PriorityQueue('min', f)
    frontier.append(node)
    explored = set()
    while frontier:
        node = frontier.pop()
        if problem.goal_test(node.state):
            if display:
                print(len(explored), "paths have been expanded and", len(frontier), "paths remain in the frontier")
            return node
        explored.add(node.state)
        for child in node.expand(problem):
            if child.state not in explored and child not in frontier:
                frontier.append(child)
            elif child in frontier:
                if f(child) < frontier[child]:
                    del frontier[child]
                    frontier.append(child)
    return None

五、总结

最后,我们联系上一节的内容对这些搜索算法的使用场景和策略进行总结。

策略解决方案使用场景队列算法与状态空间
DFS任意的存在许多解LIFO有限无圈图的树搜索,有限无圈图的递归算法,为有限图添加循环检测
BFS最短的解的步骤很短FIFO树搜索,图搜索(简单)可以提高性能
UC(一致代价搜索)最优的缺乏良好的可采纳启发式函数优先级队列通过g排序树搜索,图搜索(简单)的等步成本,任意步长成本的图搜索(最优)且不会重复扩展
A*最优的存在良好的可采纳启发式函数优先级队列通过f排列树搜索和可采纳启发式,可采纳启发式的图搜索(最优)(一致性启发式不需要重复扩展)
贪心通常都很好好的(不可采纳性)启发式函数优先级队列通过h排列有限无圈图的树搜索,有限图的图搜索(简单)

这篇博客写的比较简陋,后期我会再补充一些例子的,最近比较忙,很多事情蜂拥而至,耽误了写博客的任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值