aima被传很难啃,我觉得跟中文翻译时追求保留原书内容有关吧。
如果让某个知之者来读,然后写一篇更简洁的笔记。
相当于有人帮你消化了知识,后来者再看会不会更轻松一点?
如果学过数据结构,再来看这个入门第一篇章,应该是很轻松的。
我觉得这个篇章,放在入门这里,最重要的是去习惯【2个概念】:
①评价 evaluation 表示某一步的【好坏】。大部分情况下,其本质上是个【数值】!
②启发 heuristic 评估某一步的【成本】。同上,基本可以当【数值】来看。
(heuristic 这东西很怪,看起来像个形容词,翻译过来又很模糊,就成了阅读上的劝退点之一。)
无论哪个领域,所谓学习就是学到圈内人的【语言】,适应并使用这些【语言】。
在这一章,只需要掌握上述2个新单词,比背英语简单。
通常我们在一本书里会有默认的符号体系。
①evaluation,在n结点的评价值,记为f(n)
②heuristic , 从n点出发到目标点的启发值(成本大小), 记为 h(n)
③accumulated cost, 从起始点到达n点的累计成本 , 记为 g(n)
很显然,我们可以用不同的方法来做【评估】。
例如, 令f(n) = h(n) , 此举下,我们以【从n点往下走的启发值】作为评估值,f(n)越大,则认为这个n越坏。
例如,令f(n) = g(n) + h(n) , 此举下,我们综合考虑 【到达n点累积的成本】与【从n点往下走需要消耗的成本】,f(n)越大,则认为n越坏。
显然,f(n)是一个超然的东西,你可以自己任意指定一种方式,来计算【评估值】。
而评估值是bigger-better还是smaller-better,也是随自己心意的。
还有一些其他细枝末节的概念
完备性 comleteness, 若有解则必得之,若未得则必无解。
最优性 optimism (似乎又叫optimistic efficiency?)
问题形式化(problem formulation)是给定一个目标,决定要考虑的动作与状态的处理。
- 全态形式化 (Complete-state formulation) 比如八皇后问题一开始就上八个皇后直击终极目标
- 增量形式化 (Incremental formulation) 比如开局一皇后,每次加一个皇后
补充一句话
有限状态空间的图搜索是完备的(complete)。
【无限图(infinity graph)的搜索却未必。】
又称blind search
本节就4种基本算法,对应到数据结构的树图部分。
- breadth-first 广度优先 ,空间O(b^d), b是expand factor,举例,二叉树的话就是2。d 是最浅解深度。
- depth-first 深度优先 时间O(b^m) ,m for some depth 某个解深度。
- uniform-cost 一致代价搜索 (注意uniform和uninform的区别)
- Bidirectional search 双向搜索
2)
稍微值得一提的是,在图搜索中,如果是无限图,depth-first显然会失效。
于是我们很自然的想,如果限制depth到某个定值,再去搜索好不好呀?
于是得到 depth-first family的一个成员。给定mak_depth = K
Depth-limited Search 深度受限搜索。
进一步的,我们又会很自然的想,我们慢慢增大K的值,这样再去搜不是更好吗?
于是又得到一个
Iterative Deepening Search 迭代加深搜索。
就是做了点微小改进罢了。
3)
一致代价搜索中,评价函数f(n) = g(n), 选择这个函数是无可奈何的事。
因为我们得不到未来的信息,只能知道自己的累积成本。
因为引入了外部信息,所以往往比无信息搜索能更好地求解。很好理解。
本节用经典的罗马尼亚问题引出2个算法
- Greedy Best-first Search 贪婪最值优先搜索(GBS) , f(n) = h(n)
- A* Search A星搜索 , f(n) = g(n) + h(n)
两个算法唯一的区别就在于评价函数。
采用 f(n) = h(n) 的贪婪搜索之所以失败,核心原因在于h(n)只是一个【实际cost的估计值】。
每次都选【估计值最小的节点】,就有可能漏掉一些【实际cost最小、但是估计值并非最小的最优解】。
这也是无可奈何的事情。
而采用A*的好处是,加入了一个accumulated cost,使贪婪的人稍微清醒一点。
如果输光了裤子就别头铁了赶紧回家。
上面的罗马尼亚都是引子,其主要目的,除了介绍算法,更重要的却是引入另外2个概念。
①可采纳性,admissable
②一致性 , consistent
对所有n,代价的估计值h(n) ≤ 实际代价,则称h(n)为admissable的启发函数。
对所有n,从n点到目标的代价的估计值h(n) ≤ 从n点走到n'点的实际代价c(n,n') + 从n'点到目标的代价的估计值h(n'),则称h(n)为consistent(或者monotone)。
可采纳性,在我理解里,意思是【总是保守地估计】。
非常像我们平时讨论问题,都有一些口癖,像“最起码”、“保守估算”、“哪怕”、“退一万步说”。
显然只有【保守地估计】才是【可采纳的】。
如果你不保守,而是非常大胆地估计,那么你说的话就会被质疑,你给的数字就没人信。
所以admissable这个单词,选的也是略微精妙。
一致性,又称单调性。
书上用三角形关系来比喻。
如果学过dijkstra的话,就会觉得这个不等式非常熟悉。
通俗地说就是【成本不递减】。
(否则就等于图算法里出现了负值圈,越走下去值还越小了,那我多走几圈好不好?)
而①和②的关系是,
若consistent,则必admissable。(习题3.29,递推法易证)
即便admissable,却也有可能unconsistent。
理论上可以证明,
若同时满足admissable和consistent,则A*类的算法全都是optimally efficient(最优效率的)。
若只满足admissable,不满足consistent,则一个节点可能被多次展开。最坏情况下被展开的次数是一个指数级的值,此时采用Dijkstra算法远胜A*算法。(引自wiki:https://en.wikipedia.org/wiki/A*_search_algorithm)
再考虑不同的任务场景。
若admissable,则A*的树搜索版本最优。
若consistent,则A*的图搜索版本最优。
无论哪个版本,A*算法的共同缺点都是,太耗内存了。
所以又引出了一些改进内存消耗的A*衍生物。
不细述。
同一个问题,例如8数码问题(8-puzzle problem),可以定义不同的启发函数。
同上,目前为止的所谓heuristic function,依然可以理解为 【到目标的代价的估计值】。
若2个启发函数,总有h2(x) ≥ h1(x),则称h2(x)比h1(x)占优势。
注意,这句话的前提是默认了h1(x)与h2(x)遵守admissable原则,即大家都对代价作保守估计。
在admissable限制下,h1(x) ≤ h2(x) ≤ RealCost(x)。
显然h2(x)更接近实际代价,显然h2(x)更精确,这样h2(x)扩展的结点数不会大于h1(x)。
显然采用h2(x)搜索效率更高。(如果计算h2(x)的开销不是特别特别大的话)
(你用一个更精确的估计值去跑搜索,结果还能干不过一个不精确的估计值?)
一切都符合直觉。
松弛(relaxation)这个概念,跟启发(heuristic)一样,都是中文莫名其妙的东西。
但是要习惯它。
定义:
松弛问题 = 减少了行动限制的问题。
用大白话讲,松弛 = 约束条件更少的简化版问题。
书上的栗子倒是蛮好。
(图源:https://blog.csdn.net/weixin_39278265/article/details/80923249 )
因为松弛问题减少了行动约束,所以增大了状态空间。
原问题的最优解一定是松弛问题的解,但是松弛问题可能存在更好的解。
【注:中文版翻译成“原问题的最优解一定是松弛问题的最优解”,这句话显然是错的。】
书上原句【由于得出的启发式是松弛问题的确切代价,那么它一定遵守三角不等式,因而是一致的。】
这句话我觉得应该这样解读。
首先,松弛问题是很好提出的,我们可以任意减少行动限制得到一个松弛问题。
其次,任何一个问题都可以有多种启发函数,这是随我们高兴自己定义的。
第三,这句话的潜在意思是,我们可以对自己提出的松弛问题,设计一种【能够表达确切代价】的启发式(启发函数)。
第四,基于上述前提,我们为松弛问题设计的启发函数能够表达确切代价,即 h'(n) == RealCost'(n)。
因而在松弛问题内,h'(n)是一致的(consistent)。
从一致性可得,在对松弛问题而言,我们设计的h'(n)同时还是可采纳的(admissable)。
【特别需要注意的是,这个h'(n)一定要是能够确切表达代价的!!!实际操作中,如果你提出的松弛问题,找不到一个好的确切表达代价的计算方法,这个松弛问题就没有意义!】
还可以直观地这样理解。
原问题是限制A->B->C,则原来在A点的启发函数值 h(A) ≤ RealCost = distance(A,B)+distance(B,C)
松弛问题对行动的限制减少,导致A->C可能增加了一条更短的直连路径。
(就算没增加也没关系)
反正就算没增加,松弛问题对【代价的估计】,即新的启发函数h'(n),至少不会大于原来的实际代价。
(这句话成立的前提,如上文所言,是h'(n)能够表达确切代价,h'(n)==RealCost'(n))
(若增加了捷径,从A->C有更短路,那么h'(n)==RealCost'(n) < RealCost(n),就比原来的实际代价小)
(若没加捷径,从A->C还是得走B,那么h'(n)==RealCost'(n) == RealCost(n))
即,h'(n) ≤ RealCost(n),所以松弛问题的启发函数,对原问题而言(重点), is admissable。
从这段描述也可以看出,新构造的h'(n)比原来的启发式,很容易更有优势(精度更高)。
因为实践中,一个行动严格受限的问题的启发函数,h(n)会偏离实际代价很远。
例如罗马尼亚问题用直线距离作为h(n),8数码问题用错位棋子数作为h1(n)。
即h(n) << RealCost(n)。
而我们的 h'(n) == RealCost'(n) ≤ RealCost(n),直觉上h'(n)会更加精确一些。
上面2段话,就是为了直观地理解为什么需要提出一个松弛问题。
哦!!!
原来,可以通过在松弛问题里设计【精确表达代价】的启发式(启发函数)h'(n),
来获得在原问题里精度更高的启发式(启发函数)。
由上一小节的知识我们知道,精度更高(占优势)的启发函数总是更让人愉悦的!
这样我们用h'(n)求解原问题,就更加优雅而有效。
这就是松弛(relaxation)为什么在wiki被称为技巧(technique)的原因。
【wiki地址: https://en.wikipedia.org/wiki/Relaxation_(approximation) 】
它本质是帮我们获得更精确的启发函数的方法。
太神奇了!
这是有用性的证明。再来看一下必要性,为什么非得是松弛问题不可呢?
我不能直接在原问题里设计出一个“精确表达代价”的启发函数吗?
不,你不可以。
因为原问题往往有诸多限制,不直观,非线性,等等等等。
这导致你很难有一个“易于计算的”、“精确表达代价的”的启发函数。(有些式子根本写不出来,只能用符号+自然语言描述,为了计算又需要设计一套算法。)
精度和计算成本需要权衡。
sorry,松弛问题就是可以为所欲为。
不过北大OJ里,王文敏先生没有怎么讲松弛问题。
也没有讲【从子问题出发设计可采纳的启发式:模式数据库】这一节,有点遗憾。
局部搜索 local search:
局部搜索算法是从单个当前结点(而不是多条路径)出发,通常只移动到它的邻近状态,通常不保留搜索路径。
局部搜索不是系统化的。
所以有2个优点,(1)很少内存,通常为常数 (2)通常能在系统化算法不适用的很大或无限的(连续的)状态空间中找到合理的解。
所谓局部呢,就是片面。
何谓片面呢?
就在于,局部搜索不关心路径,只关心最终状态是什么。
我只想知道8个皇后怎么摆,你不需要告诉我怎么移动。
也就是说,局部搜索是来搜索状态(state)的,而不是路径(path)。
很自然的,我们会想到把局部搜索放到优化问题里去。
对于纯粹的优化问题( pure optimical problem),可以给定一个目标函数,找到一个更优的状态。
定义一个状态空间图,state-space landscape
横轴为状态,纵轴为启发式代价函数或目标函数。
像不像神经网络里对loss function求最优参数?
本节4个基础局部搜索算法。
①爬山法 Hill-Climbing
我们假设目标函数是bigger-better的。
那么爬山法简单的说,就是每次向目标函数增大的方向移动。
爬山法有一个最陡版本(steepest -ascent version),每次都选取最佳邻接点。
因为这种短视的特性,又称贪婪局部搜索(greedy local search)。
从短视来看,其缺点是容易陷入局部极大值。
于是很自然的引申出一个随机重启爬山法(random restart hill climbing),类似给定初动量的优化函数SGD,帮忙跳出局部极值。
还有一种随机爬山法(random hill cimbing),以不同方向的斜率(梯度)为概率值,随机往某个方向前进。
很像deepwalk吧,随机游走一哈,没准就摆脱局部极值陷阱了。
②模拟退火搜索 Simulated Annealing Search
这个做过信息题的人应该不陌生。
此处我们假设目标函数是smaller-better的,即可以理解为loss function。
简单的说,每次随机移动到某点,若loss降低则接受该移动。
若loss增加,则以一个p概率接受该移动。
p的计算方式含2层。
1) △Loss,即损失的增加幅度,指数级增长,loss增加的越多,p概率越小,我们越不允许这次移动发生。
2) 当前loss。原句【开始温度T高的时候可能允许“坏的”移动,T越低则越不可能发生】。
③局部束搜索 Local Beam Search
我们假设目标函数是bigger-better的。
本算法的特性在于能存储K个状态,而不是一个。
你可以理解为,K个局部搜索任务并行,其中一个任务达到目标就停止。
但与完全并行不同的是,K个任务之间会互相传递信息,反而更像大家分散出去四面八方找水源,找到的人通知其他人也过来。
和爬山法相比,无非是一个人爬山,变成了K个人爬山。
最简单的局部束搜索,很容易K个人一起在局部极大值顶点被套牢罚站。
于是很自然的有人就提出了随机局部束搜索。
假设K个结点移动一次之后生成N个后继状态,那么不再从N个里面按目标函数最大的topK这么无脑取了。
而是随机地从N个后继状态中选择K个,概率值随N个后继状态的权值(目标函数值)的增大而增大(类似于softmax)。
④遗传算法 Genetica Algorithm GA
遗传算法是一类算法,而不是某个算法。
(deeplearning早期就有用遗传算法去搜参数的论文,但是模型一深参数一多就爆炸了,后来还是反向传播一统天下。)
本质是受达尔文进化论启发创造出来的。
无非是把目标函数的名字偷换成了“适应度函数”这种。
同样的,适应度函数是bigger-better的。
选择后代的过程,和随机局部束搜索类似,也是“适应度”权重作为概率值,然后随机选择。
本节概括一下就是......
没什么困难是一层随机不能解决的。
如果有就再套一层随机。(摊手)
这一节看着短,涉及到好多课外知识。
王文敏mooc没讲,需要自己补作业。
【注意北大mooc只讲了4种基础局部搜索算法,以及后面的集群智能算法。aima上第四章的其他内容都没介绍。
】
如果环境是部分可观察或不确定的(也可能两者都有),就需要引入“感知信息”这一概念。
此处分两类。
1)环境确定,但是仅部分可观察。那么agent无法确定自己处在哪里,每一个感知信息会缩小Agent判定自身状态的可能范围。
2)环境不确定,但是部分可观察。Agent只能依赖当前感知信息,感知信息告知Agent某一行动的结果到底是什么。(我摔了杯子,感知信息告诉我杯子碎了这一结果。)
上面两种情况,对于Agent来说差不多,Agent都无法确定自己所在的确切状态,只能不断的行动,尝试,根据感知信息来反馈调节,产生应急规划(策略strategy)。
所谓的应急规划,本质上是一连串if else。
比如,在t-1时刻,根据感知信息得到一个stratefy,里面包含了内容{if 1 then do a , else if 2 then do b}。
到了B怎么办呢,又要算新的步骤。
显然,这是一个树结构,一路扩展下去。
书上是引入了“不确定动作,不稳定的吸尘器世界”这一节来说明的。
non-deterministic actions : the erratic vacuum world
这样就引入了 (And/Or Tree)与或树 ,这一概念。
在该树中,
同一条路径上的所有结点,由于后者是前者行动的结果,这些结点被称为与结点(And Node)
同一个结点的所有孩子,由于彼此是同一个parent node的分支,互相之间被称为或结点(Or Node)
根结点root被视为initial problem。
每一个结点被视为一个subproblem。
当该subproblem被解决时,就terminate。
否则,在该结点处继续expand分支。
从定义来看,就是对搜索树换了层皮......
与或搜索问题的解是一颗子树。
我们可以继续扩展,得到AND-OR Graph 与或图。
与或图的搜索算法很多,偷一张slide。
(src:https://www.ics.uci.edu/~kkask/Fall-2016 CS271/slides/03-InformedHeuristicSearch.pdf)
Agent感知不到任何信息的问题,称为无传感问题(sensorless problems),或相容问题(conformant problem)。
相容问题这个翻译有很大的偏差,还是看英文体会吧。
完全不可观察情况下,可以产生一些特别的解。
原书举例吸尘器问题中使用{Right,Suck,Left,Suck}这一策略,总能迫使世界达到状态7(coerce the world into state 7)。
解决无观察问题,我们在信念空间(space of belief states)中搜索,而不是实际状态空间(rather than physical states)中搜索。
后面的东西玄乎其玄......
脱机搜索:诸葛亮坐在大后方计算出完整的方案,然后交给其他人去执行。不涉及动作执行过程
联机搜索:计算和动作执行交替进行。 先采取某个行动,然后观察环境变化并且计算出下一行动。
联机搜索存在一个隐含条件,即状态之间的转移可逆。
毕竟联机搜索的本质是探索问题(这是个名词!!!exploration problem)
我从A来到B,这是一个action,然后发现B不好待,就要原路返回。不然我就算不出从A出发的其他路径的好坏。
如果某些活动是不可逆的(irreversable),就容易陷入死胡同(dead-end)。
再关注一下敌对论点(adversary argument)这个翻译。
北大mooc单独新增。
Altruism Algorithm 利他算法
Ant Colony Algorithm **蚁群算法**
Bee Colony Algorithm 蜂群算法
Artificial Immune System 人工免疫系统
Bat Algorithm 蝙蝠算法
Differential Evolution Algorithm 差分进化算法
Multi-swarm optimization **粒子群优化** https://en.wikipedia.org/wiki/Multi-swarm_optimization
整理中...
博弈论(Game Theory)是研究理性决策者之间的冲突与合作的数学模型。
一个可替换属于是交互式决策理论(interactive decision theory)。
零和博弈(Zero Sum Games),【为什么发音是灵狐博弈???文敏sensai???】
Two Players Game
博弈树 【为什么发音是波衣术???】
optimal decision in game
minmax value
使对手的最大收益最小。
使自己的最大损失最小。
pruning剪枝
一组变量,每个变量有自己的值。
当每个变量都有自己的赋值同时满足所有关于变量的约束时,问题就得到了解决。
这类问题就叫做约束满足问题 Constraint Satisfaction Problem,CSP。
CSP搜索算法利用了状态结构的优势,使用的是通用策略而不是问题专用启发式来求解复杂问题。
主要思想是通过识别违反约束的变量/值的组合迅速消除大规模的搜索空间。
形式化定义为三个成分X,D,C
X为变量。
D为值域。
C为约束集合。
一个不违反任何约束的赋值被称为相容的(conformant)或者合法的赋值。