问题求解智能体
智能体可以执行以下 4 个阶段的问题求解过程。
- 目标形式化(goal formulation):智能体的目标为到达 Bucharest。目标通过限制智能体的 目的和需要考虑的动作来组织其行为。
- 问题形式化(problem formulation):智能体刻画实现目标所必需的状态和动作——进而得 到这个世界中与实现目标相关的部分所构成的抽象模型。对智能体来说,一个好的模型 应该考虑从一个城市到其相邻城市的动作,这时,状态中只有“当前所在城市”会由于 动作而改变。
- 搜索(search):在真实世界中采取任何动作之前,智能体会在其模型中模拟一系列动作, 并进行搜索,直到找到一个能到达目标的动作序列。这样的序列称为解(solution)。智能 体可能不得不模拟多个无法到达目标的序列,但最终它要么找到一个解(例如从 Arad 到 Sibiu 到 Fagaras 再到 Bucharest),要么发现问题是无解的。
- 执行(execution):现在智能体可以执行解中的动作,一次执行一个动作。
一些关键概念:
- 可能的环境状态(state)的集合,状态空间(state space)。
- 智能体启动时的初始状态(initial state)。
- 一个或多个目标状态(goal state)的集合。
- 智能体可以采取的行动(action)。
- 转移模型(transition model)用于描述每个动作所起到的作用。
- 动作代价函数(action cost function),在编程中记作 Action-Cost(s, a, s’ ),在数学运算中记 作 c(s, a, s’ )。
搜索问题(problem)的形式化定义如下:
- 可能的环境状态(state)的集合,我们称之为状态空间(state space)。
- 智能体启动时的初始状态(initial state)。
- 一个或多个目标状态(goal state)的集合。
- 智能体可以采取的行动(action)。Actions(s) 将返回在 s 中可以执行的有限 a 动作集合。我们称集合中的任一动作在 s 中都是适用的(applicable)。
- 转移模型(transition model)用于描述每个动作所起到的作用。
- 动作代价函数(action cost function),在编程中记作 Action-Cost(s, a, s’ ),在数学运算中记 作 c(s, a, s’ )。
问题示例
一些问题名字:
- 网格世界(grid world)问题是一个由正方形单元格组成的二维矩形阵列,在这个阵列中, 智能体可以从一个单元格移动到另一个单元格。
- 推箱子问题(sokoban puzzle);
- 滑块问题(sliding-tile puzzle)中,若干滑块(有时称为块或片)排列在一个有若干空 白区域的网格中,其中滑块可以滑进空白区域,或华容道问题;
- 旅行问题(touring problem)描述的是一组必须访问的地点,而非单一目的地。旅行商问 题(traveling salesperson problem,TSP),就是一个旅行问题,即地图上每个城市都必须被访问。
- 超大规模集成电路布图(VLSI layout)问题需要在一个芯片上定位数百万个元件和连接 点,以最小化芯片面积、电路延迟和杂散电容,并最大化成品率。
- 机器人导航(robot navigation)是寻径问题的一个推广。
搜索算法
搜索算法(search algorithm)将搜索问题作为输入并返回问题的解或报告 failure(当解不存在 时)。完备的搜索算法探索无限状态空间的方式必须是系统的(systematic),以确保它最终能够 到达与初始状态相关的任何状态。
问题求解性能评估:
- 完备性(completeness):当存在解时,算法是否能保证找到解,当不存在解时,是否能保 证报告失败?
- 代价最优性(cost optimality):它是否找到了所有解中路径代价最小的解? a
- 时间复杂性(time complexity):找到解需要多长时间?可以用秒数来衡量,或者更抽象地用状态和动作的数量来衡量。
- 空间复杂性(space complexity):执行搜索需要多少内存?
无信息搜索策略
广度优先搜索
当所有动作的 代价相同 时,正确的策略是采用广度优先搜索(breadth-first search),即先 扩展根节点 ,然后扩展根节点的所有后继节点,再扩展后继节点的后继,以此类推。
Dijkstra算法或一致代价搜索
当动作具有不同的代价时,一个显而易见的选择是使用最佳优先搜索,评价函数为从根到当前节点的路径的代价。理论计算机科学界称之为 Dijkstra 算法,人工智能界则称之为 一致代价搜索 (uniform-cost search)。
深度优先搜索与内存问题
深度优先搜索 (depth-first search)总是优先扩展边界中最深的节点。它可以通过调用 Best- First-Search 来实现,其中评价函数 f 为深度的负数。然而,它通常不是以图搜索的形式实现 而是以树状搜索(不维护已达状态表)的形式实现。
回溯搜索 (backtracking search)是深度优先搜索的一种变体,它使用的内存更少。(详见 第 6 章。)在回溯搜索中,一次只生成一个后继,而不是所有后继节点;每个部分扩展的节点 会记住下一个要生成的后继节点。
深度受限和迭代加深搜索
深度受限搜索 (depth-limited search)是一个深度优先搜索的改进版本,在深度受限搜索中,设置深度界限 ,将深度 上的 所有节点视为其不存在后继节点(见图 3-12),深度受限搜索算法的时间复杂性为 O(b ),空 间复杂性为 O(b ),如果我们对 的选择不当,算法将无法得到解,成为不完备的 算法。
迭代加深搜索 (iterative deepening search)解决了如何选择一个合适的问题,方法是尝试所有值:首先是 0,然后是 1,然后是 2,依次类推——直到找到一个解,或者深度受限搜索返回 failure 值(而不是 cutoff 值)。
双向搜索
双向搜索 (bidirectional search)的方法则同时从初始状态正向搜索和从 目标状态反向搜索,直到这两个搜索相遇。算法的动机是,bd/2 + bd/2 要比 bd 小得多(例如,当 b = d = 10 时,复杂性不到之前算法的五万分之一)。
无信息搜索算法对比
有信息(启发式)搜索策略
有信息搜索 (informed search)策略——使用关于目标位置的特定领域线索—— 如何比无信息搜索策略更有效地找到解。线索以启发式函数(heuristic function)的形式出现, 记为 h(n) 。
贪心最佳优先搜索
贪心最佳优先搜索 (greedy best-first search)是最佳优先搜索的一种形式,它首先扩展 h(n) 值最小的节点——看起来最接近目标的节点——因为这样可能可以更快找到解。因此,评 价函数 f(n) = h(n)。
【PS:贪心算法做出在当前看来最优的(即可以最接近目标的)选择,但这也会导致贪心法在全局意义上可能产生比谨慎的算法更糟糕的结果。】
A* 搜索
A星搜索是一种最佳优先 搜索,评价函数为 f(n) = g(n) + h(n) 其中 g(n) 是从初始状态到节点 n 的路径代价,h(n) 是从节点 n 到一个目标状态的最短路径的代价估计值。
【PS:该算法需要用到 h s l d h_{sld} hsld ,到目标的“直线距离”。】
搜索等值线
一种对搜索进行可视化的方法是在状态空间中绘制等值线(contour),就像在地形图中绘 制等高线一样。
满意搜索: 不可容许的启发式函数与加权A*搜索
A* 搜索有很多好的性质,但它扩展了大量节点。如果我们愿意接受次优但“足够好”的 解——我们称之为满意(satisficing)解,则可以探索更少的节点(花费更少的时间和空间)。 如果我们允许 A* 搜索使用 不可容许的启发式函数 (inadmissible heuristic)(它可能会高估到达 某个目标的代价),那么我们就有可能错过最优解,但是该启发式函数可能更准确,从而减少 了需要扩展的节点数。
- 有界次优搜索(bounded suboptimal search)中,我们寻找一个能保证代价在最优代价的常数因子 W 倍内的解,加权 A* 搜索提供了这一保证。
- 在有界代价搜索(bounded-cost search)中,我们寻找一个代价小于某 个常数 C 的解。
- 在无界代价搜索(unbounded-cost search)中,我们接受任何代价的解,只要 能快速找到它。
- 无界代价搜索算法的一个例子是快速搜索(speedy search),它是一种贪心最佳优先搜索, 使用到达目标所需动作个数的估计值作为启发式函数,不考虑这些动作的代价。
内存受限搜索
束搜索 (beam search)对边界的大小进行了限制。最简单的方法是只保留具有最优 f 值的 k 个节点,放弃其他已扩展节点。
双向启发式搜索
一条路径的代价一定不小于两部分路径代价之和(因为它们之间的剩余连接 一定具有非负代价),而且也一定不小于任一部分的 f 代价估计值(因为启发式的估计是乐观 的)。
启发式函数
启发式函数的准确性对性能的影响
启发式函数相当于优化目标的评价函数,找到适合的评价函数很重要,例如: 8数码问题中, h 1 h_1 h1、 h 2 h_2 h2 都是很好的启发式函数。
有效分支因子 (effective branching factor)b*,如果针对 一个特定问题,A* 搜索所生成的总节点数是 n,而解的深度是 d,那么 b* 就是深度为 d 的均衡树要包含 n + 1 个节点所必需的分支因子。因此有 n + 1 = 1 + b ∗ + ( b ∗ ) 2 + . . . + ( b ∗ ) d n+1 = 1+ b^* + (b^*)^2 + ... + (b^*)^d n+1=1+b∗+(b∗)2+...+(b∗)d
有效深度 (effective depth)相比于真实深度的减少量 k h k_h kh (一个 常数)。
从松弛问题出发生成启发式函数
减少了对动作的限制条件的问题称为 松弛问题 (relaxed problem)。适当修改评价函数,将成为优化中的松弛问题。
从子问题出发生成启发式函数模式数据库
列出所有问题的可能性,所有子问题的和仍然是求解完整问题代价的一个下界。
使用地标生成启发式函数
量化地标点,计算地标点与点之间的距离,默认忽视点与点之间的距离。
学习以更好地搜索
元级学习(metalevel learning)算法可以从 这些经验中学习,以避免探索毫无希望的子树。
从经验中学习启发式函数
生成启发式函数的一种方法是设计一个容易找到最优解的松弛问题。