前言
这是本书的第三章内容,本章主要目的是理解问题的求解过程和步骤,重点是掌握如何对某个问题进行形式化以及对问题的解的搜索方法。
1.问题的定义
1.1问题的形式化
对问题进行求解前,要清楚Agent可能处于哪些状态,可以采取哪些行动,还有就是该问题所处的环境的性质,通过这个过程才能构建出一个问题的模型–即形式化的过程。
一个问题可以用5个组成部分形式化地描述:
-
问题的状态空间:问题里Agent可以处的所有状态的集合。如教材中的罗马尼亚寻路问题,Agent所到达的每一个地点都可以是它的状态。
这里面还有一个概念就是初始状态,这个就是问题求解的开始状态,比如上述问题中初始状态可以是位于任意的地点。 -
行动空间:即Agent可能采取的行动,如走向下一个地点。
-
转移模型:又可以说是后继状态,即在当前状态下执行某一动作达到的新的状态,有时候采取动作后达到的状态也并不唯一,就比如我吃饭后,可能让我感到困倦,也可能让我状态满满,这是一种转移概率模型,是对转移模型的一种延申。
-
目标测试:即问题的目标状态是什么。
-
路径耗散:教材由于用的是罗马尼亚问题进行形式化,所有用了“路径耗散”,个人认为用“奖励函数”或者“代价函数”可能更加有普适性,顾名思义,就是Agent在求解问题过程中每一次行动会造成的代价。比如寻径问题,路径的长短就是代价,或者消耗的时间步等等。
1.2 问题的抽象
对问题的形式化后,还不能彻底地简化问题,所以需要更近一步对问题进行抽象。
抽象是一个除去细节的过程,现实世界的状态和行动包括许许多多的情况,但在解决某一个特定问题时,我们并不需要太多无关的细节,所以抽象是简化问题的过程。
- 对于教材中的罗马尼亚寻径问题,我们虽然默认Agent的状态只是其位置状态,但事实上是我们除去了许多细节,如路况、天气情况、窗外的景色等等的结果。
- 不仅是状态描述要抽象,我们还需要对行动进行抽象。汽车的驾驶行为不仅仅可以改变车辆自身的位置,它还会消耗汽油和时间等等。而对于
“把方向盘向左转1度”这样层次的细节更不应该是我们这个问题考虑的层次。
对于一些简单的问题,我们可能很快就能抽象出我们想要的问题形式,但对于一些复杂问题来说,如何抽象,抽象到哪一个层次是形式化问题的关键。
因此,选择一个好的问题抽象,包括在保持有效抽象的前提下去除尽可能多的细节和确保抽象后的行动容易完成。如果缺乏能力去构建有用的问题抽象,智能Agent将会被现实世界完全淹没。
1.3 问题实例
这里从书上挑了一个八数码问题的实例,其余的也大体类似,主要是与我们的编程作业有关,如果后续有时间,会把代码整理出来。
- 状态空间:状态描述指明8个棋子以及空格在棋盘9个方格上的分布。
- 初始状态:任何状态都可能是初始状态,注意要到达任何一个给定的目标。
- 后继函数(行动空间+转移模型):用来产生通过四个行动(把空位向Left、Right、Up或Down移动)能够达到的合法状态。
- 目标测试:用来检测状态是否能匹配图3.4中所示的目标布局(其他目标布局也是可能的)。
- 路径耗散:每一步的耗散值为1,因此整个路径的耗散值是路径中的步数。
这个问题我们在哪些地方做了抽象呢?行动被抽象为它的起始和结果状态,忽略了当棋子滑动时所走过的中间过程。这个问题的抽象还包括不考虑如下行动:棋子粘住的时候晃动棋盘、或者用小刀把棋子抠出来再放回去。我们保留和游戏规则有关的描述,避免陷入所有物理操作的细节。
总结
这里是问题求解的第一部分,主要是剖析了问题的形式化,下一部分是对问题解的定义以及求解的过程。