人工智能(第三版
人工智能(第三版)(24/1/15)
第一部分:
第一章:前言#起始:(24/1/15)
1.0引言
对于人工智能的理解存在争议——
一些人认为,人工智能等同于任何由非生命系统实现的智能。他们坚持认为,即使这类智能行为的实现与人类智能的依赖机制不同也无关紧要。而另一些人则认为,人工智能系统必须能够模仿人类智能。——《人工智能(第三版)》
(一些人认为:人工智能作为不同于现存各种智能生物的个体,没有必要模仿人类智能。而另有一些人认为人工智能的结果是创造类人思考的智械,所以认为人工智能必须能够模仿人类的智能。)
虽然双方在人工智能的结果上产生了分歧,但是对于研究人工智能的前提确实一致的
即研究人工智能或实现人工智能系统,首先应理解人类如何获得智能行为,这对我们大有裨益。也就是说,我们必须从智力、科学、心理和技术意义上理解被视为智能的活动。
(目的是实现通过研究人脑推广到机械脑。问题在于计算机的01语言如何能够实现类似于生物大脑的智能甚至是人类的智能。问题再次前推,生物的智能是如何实现。)
(如果单从算力来讲,计算机的算力相比于人类早已经是遥遥领先。但我们难以承认人工智能是成熟的智能,虽然对于可以轻易难倒人类的问题,人工智能通关自己算法的优势可以轻而易举的完成,但是对于一些人类比较容易做到的事情却会让人工智能难以理解,譬如一些语言游戏,如反问句,讽刺语气,三重肯定表否定)
“人工”
人工是指由人制造。人造物通常具有负面含义即“人造物体只是真实物体的次要形式”
(这里的真实物体是指现实中存在的物体,这里负面含义我认为应该是指人造物体的总是基于现实物体而形成的。虽然较纯正而言人造物品并不能与真实物体并论,但人造物品通常可以让人们生活更方便,人造花的装饰作用,其质感可能不及真正的花,但是它有不需要时时浇水,容易养活的特点。)
"思维与智能"
理解人的”智能“我们需要从智力,科学,心理和技术意义上理解被视为智能的活动。
对于智能,R.斯腾伯格(R. Sternberg)给出了如下有用的定义:
智能是个体从体验中学习,正确推理,记忆重要信息,以及应对日常生活需求的认知能力。
(在智能的定义中将短句拆分成几个部分,可以看到“体验中学习”,“正确‘推理’”等几个词语带有较强的标识性意义。拥有智能的实体能够实现这些,而能够实现这些也就是拥有了智能)
动物智能
(1)如何判定某个人或物是否有智能?
(2)动物是否有智能?
(3)如果动物有智能,那么如何评估它们的智能?
(书中1.0.2提出了以上问题,三个问题递进排布,由比较熟悉的人,到生活中无处不在的动物,但动物与人之间存在交流障碍,判断动物是否有智能和评估动物的智能可以延申为判断计算机是否有智能,以及智能的强弱,这本身也是利用了启发式方法吧)
1.1图灵测试
何为图灵测试:
举例说,一场测试需三名角色:
普通人,询问者,说谎者。(每个人之间用幕布围住)
普通人:诚实的回答,证明自己是个普通人
说谎者:用谎言将自己伪装成为一个普通的人
询问者:通过询问问题区分普通人和说谎者。
回到智能实现的步骤,我们不可否认剖析人的智能是重中之重的一步,因此,我们通过让人工智能充当说谎者的身份来伪装自己成为一个普通人,来进一步评估人工智能。
对于图灵测试,布洛克和塞尔提出的思考引人深思
布洛克:假设计算机有足够大的存储空间来记录每一个合理的答案(包括回答的时间,语言等等一系列)它不必理解这些词汇和拖时间的意义。(即用机械查表得方式而非智能的方式来回答问题)
塞尔:中文房间问题,假设询问者以中文发问,而普通人并不懂中文,他有一份潦草的翻译,他只需要将问题对照翻译,再将答案对照翻译写出符号,普通人也并不需要理解这些中文的意思,只需要处理字符而已。同样,对于计算机的回答也是如此,如果计算机也只是对照翻译 的字符表将询问者的问题转化成01语言再对照翻译表将01语言转化为人类语言。这种模式难道能称为智能么?
布洛克和塞尔的批评表现在如果只是通关观察计算机的外部,即便计算机做出了合理的回答仍无法判断计算机是否使用了有智能,即计算机是否对问题做出了相应的思考而不是打表。
(后续说明,卢瑟福的α粒子撞击金箔实验,卢瑟福仅通过观察外部结果推理出正确的原子内部结构)
1.2弱人工智能与强人工智能:
“弱人工智能”(与麻省理工大学相关)的观点
人造物是否使用与人类相同的方式执行任务无关紧要,唯一的标准就是程序能够正确执行。
弱人工智能以效率作为智能的标准,并不在乎解决问题的方式。
“强人工智能”(以卡内基·梅隆大学(CMU)为代表)的观点
当人造物展现出智能行为时,它的表现应该基于与人类相同的方法。
强人工智能认为人工智能解决问题的方式应该是基于人解决问题的方法,他们坚信完全依靠人工智能程序的启发式方法、算法和知识,计算机就可以获得意识和智能。
(不难看出弱人工智能与强人工智能的划分是对人工智能理解分歧的进一步延申。既然说延申,两者的分歧肯定不是完全相同的。讨论点仍然落在了对智能的讨论上,弱人工智能的观点更注重目的性,仍将人工智能视为工具,强人工智能则要求人工智能的表现基于人类解决问题的方法。)
1.3启发式方法:
启发式方法是解决问题的经验法则。
不同于算法,算法是预先设定的用于解决问题的一组规则,其输出是完全可预测的。
而启发式是经验的方法,当解决一个比较困难的问题时,我们可以通过解决相同类型比较简单的问题来学习解决此类推解决这道难题的方法,这个时候我们其实就是利用了启发式的方法。
(在这里算法可以指代解决某类问题的明确的公式,步骤。启发式方法则是通过现实中经验,学习后获得的知识,通过推理,举一反三等一系列操作后实现的。如果说算法是高数考试让你利用罗尔定理,那么启发式就是让你自己推证罗尔定理,并利用。可以看出很多算法是从启发式方法中获得灵感后创造出来的)
1.4 识别适用人工智能来求解的问题 :
专家系统:
1它拥有庞大的数据库,包含各个领域或专门领域的专业知识或者生活常识。
2专家系统意味着具有专家能力的系统,能够根据你所说出的现状给出专家的建议。(正确判断的能力)可以模拟专家判断的过程。
二人博弈:
通过下棋来评估人工智能的智能水平。
国际象棋比赛和跳棋比赛,国际象棋的数据量庞大,单纯的打表难以解决问题。
尽管人机比赛中机器获胜,但是不满足强人工智能的要求,人工智能无法解释每一步棋的推理过程,并没有将每步棋的意义考虑到决策之中。
1.5 应用和方法:
一个系统要展示智能,就必须与现实世界交互。(照应前文)
利用搜索算法可以预见某个棋子对后续的影响,因此**有很多研究都聚焦于高效搜索算法的发现和发展。 **(空间树)
拼图游戏中介绍了:
1.盲目搜索法(遍历):深度优先搜索(通常但不一定,向左支移动),广度优先搜索(首先访问靠近根节点的方向),之后讨论面对组合爆炸的问题(因为数据量的爆炸式增长导致的盲目搜索无法成功,这不仅仅是超时问题,不管未来计算机的计算速度有多快,这依然会是事实)
2.启发式搜索:在寻找之前先观察空间树,**这些算法可以使用启发式方法来估计到达目标状态的剩余距离。 **
二人博弈:
不同于拼图游戏,二人博弈为双人对抗性质,必须同时关注自身和对手的动态。(这种更具交互性质的游戏是人工智能研究的热门话题)
自动推理:对智能的定义中提到,人工智能需要有正确推理的能力。此处,人为给定一些相关信息,希望人工智能可以通过这些信息来推理出希望得到的信息。(此处给定的信息包含但不仅限于此,研究人员还希望它能明白并利用常识和世界知识)
细胞自动机:模拟生命从简单到复杂的过程。赋予人工智能简单的规则,通过规则的迭代使其获得复杂性
遗传算法:以计算机处理数据的速度优势,按照自然界中的遗传进话规律形成的进化计算。
为每个状态赋值名为适应度的参数,并使用适应度函数使与目标状态更接近的状态适应度更高。
知识表示:由传教士与野人问题引出绘图处理的方法,语义网络,框架等基于图的只是表示法。
1.59 不确定性推理
模糊集,给定的较为抽象的数值。
此处给例为员工的隶属度。从1.0到0.0不等,这些值无法明确表示,但是可以模糊表示,并且这些不确定性的数值可以作为我们某些推理的数据。
1.6人工智能的早期历史
亚里士多德建立逻辑前提论
乔治·布尔建立逻辑关系后被称之为布尔代数
雷蒙德·卢尔:可能是第一个尝试将人类思维机械化的人,建立了一个基于逻辑的系统
莱布尼茨:建立逻辑演算和通用代数几乎解决所有的逻辑论证
库尔特·戈德尔:认为总有些命题不能被判定为真或假。
雷内·笛卡儿:通过认知内省解决了物理现实的问题。
逻辑学家与逻辑机器:
第一台真正意义上的逻辑机器康斯坦普演示器
现代第一台原型的现代计算机名为差分机
差分机的下一代产品:分析机
克劳德·香农:继电器电路的应用上有开创性论文。
Nimotron是第一台可以完整发挥游戏技能的机器。
托雷斯·克韦多建立了第一个专家系统。
康拉德·楚泽发明了第一台使用电的计算机,楚泽认识到了工程和数学逻辑之间的关系并且认识到布尔代数中的计算与数学中的命题演算是等价的,他开发系统,在逻辑电路方面的工作比香农早了几年楚泽认识到需要一种高效和庞大的存储器,并基于真空管和机电存储器改进了计算机,他将这些计算机命名为 Z1、Z2 和 Z3。
人们普遍认可 Z3(1941 年 5 月 12 日)是世界上第一台基于浮点数的、可靠的、可自由编程的计算机。这台机器在第二次世界大战中被炸毁了,但是它的仿制品目前展示在慕尼黑的德意志博物馆。
1.7人工智能的近期历史到现在:
自第二次世界大战以后,计算机科学取得了巨大的进步,编程技术日渐成熟。
神经计算:
弗兰克·罗森布拉特开发了一种名为感知器学习规则的迭代算法,解决了人工神经网络(ANN)模型不包括学习机制的严重缺点。
20世纪80年代,这个领域迎来了第二次爆发,霍普菲尔德的异步网络模型
使用能量函数找到了NP问题的近似解。20世纪80年代中期,人工智能领域出现了方向传播算法——一种适合于多层网络的学习算法
自然语言处理(NLP):对于智能系统,具有理解自然语言的能力看起来是非常自然的事情
Eliza具有与人说话的能力(不是沟通或者交流)旨在模仿卡尔·罗杰斯(Carl Rogers)学派的精神病学家所担任的角色。
DOCTOR初步具备了感知情绪的能力
特里·威诺格拉德开发的SHRDLU可以 使用意义、语法、演绎推理来理解和响应英文命令,它的会话世界是一个桌面,上面放着各种形状、大小和颜色的积木
HEARSAY是一个雄心勃勃的语音识别程序,它采用黑板结构,该程序使用语法和语义信息来去除不太可能的单词组合。
改善:通过从宾州树库中获取相关概率实现增强上下文无关的语法,以赋予每条规则相关的概率。
1.8 新千年人工智能发展
人工智能的方法论已经被吸纳到计算机科学的标准技术中。比如,在人工智能研究中产生的搜索技术和专家系统现在都已经被嵌入许多控制系统、金融系统和基于 Web 的应用中
第一章讨论题:
1.从人工和智能两个角度讲。
“人工”的角度讲人工智能是人造物。
“智能”的角度讲人工智能具有从生活中获得经验,学习知识并应用解决问题的能力。
在图灵测试中,塞尔还强调了人工智能应该具备思考的能力。
2.弱人工智能针对于结果,他们的观点认为人造物是否具有基于人的智能无关紧要,侧重于人工智能是否能够正确运行高效的取得正确的结果
强人工智能要求人工智能的表现应该是基于人类解决问题的。
3.ALICE是一款安装在网络服务器上的聊天机器人,相比于早期的其他机器人,它具备更强的上下文联系能力。
4.图灵利用图灵测试评估人工智能的智能程度。
5.约翰·麦卡锡首次提出了“人工智能”,对于LISP编译语言做出了重大贡献,指出人工智能需要什么才能真正有效。
6.ATM机并不具备体验中学习,正确推理,即不具备智能。
7.人工智能可以基于过往的病例经分析推理确定或者的疾病和治疗问题,其次医疗诊断是一个复杂的过程,其中可能有很多有效的医疗方法,并且多数情况下并不存在可以识别潜在疾病或病症的确定性算法。专家的知识是离散分布且大量的,人工智能可以统合这些分散的信息
8.二人博弈与之前的拼图游戏有所不同,游戏需要两名参与者,人工智能不仅需要关注自身完成目标的进度还需要时刻关注对手的状况,更考验人工智能的分析推理学习的能力。
9.计算器象棋的可能性多,盲目搜索法无法实现,迫使算法以及启发式搜索法进步
评估人工智能的智能水平
10.专家系统将专家离散的知识与经验,提问者说明的条件整合,推理给出相对合理的建议。
11.语义网络,框架系统,描述逻辑
练习题:
1.通过逆图灵测试训练AI模型,实现判别是否是机器人和伪装自己两类人工智能的发展。通过此训练判别是否是人工智能的人工智能判定买票者是否是机器人。
2.通过伪装成为朋友或者亲人进行诈骗,冒名顶替他人进行违法行为。
3.大猩猩进行一了举一反三的行为,他通过手镯和手指两个词语来表示并未学到的戒指。
动物的智能是否只是对人类行为的理解,即是否只是简单的巴普洛夫反应 ,聪明的汉高通过分析推理人的表情和行为来获得数学问题的正确答案,这一点虽然已经表明这匹马具备智能,但是他还是不知道数学问题背后的意义。
测试方式:将戒指,手镯+其他小物品放在大猩猩面前,摆出手镯和手指的手语,让他选择。
判断他是否分析人类的意图。
判断他是否真正明白了戒指的意思。(而不是单纯看着像)
4.不能。根据布洛克和塞尔的批评为了完成指定的目标而没有思考背后意义并不能证明为人工智能,即判定大城市(智能)的标准应该包含但不仅限于这些标准。
5.将权重设为1.0阙值设为0.5。当输入的平均值大于0.5时执行真,小于0.5时执行非。
6.以平均收益作为策略成功与否的标准,取n次游戏收益的平均值,如果该策略可以长期获得高收益那么可以判定为成功的策略。
7.曼哈顿距离
8.搜寻过去高峰时期出租车上车下车的汇集地,根据城市高峰段的交通信息确定车辆较少的路段规定行车路线。
9.对地形的了解将猎物逼入死角。守水源处。在猎物睡觉或者猎物幼崽距群体远的时间。
10.家庭成员的组成,成员的年龄,经济条件,房屋大小,对干净的需求。
11.人类应该认识放下傲慢,应该尊重拥有智能的其他实体。即使人工智能由人类创造。
12.可以增加数据收集的速度。可以确保数据收集的多样性,可以整合分析去除错误数据。数量更多,可以避免安全性因素导致的失败。
13.Eliza可以被视为一种关系型人造物。Eliza的制作旨在通关交流互动的方式进行心理疏通,对精神问题的患者进行治疗。
14.翻译为,(我们是人类亦或者舞者?)我们是人类还是舞者?在了解到一定的背景故事之后我认为后者的翻译优于前者。舞者是人类的职业,在乐团的困境时以歌发问是继续前进还是放弃?是掌控命运还是受制于人。情感还是欲望?不够完美还是不受影响?维加斯的败犬还是大厦顶层的公子哥?在过去他们初出茅庐,风华正茂时无需考虑这种烦恼,他们轻浮愚蠢,并且对此毫无歉意,现如今他们困境重重,但是他们一本正经。歌唱时他们无需考虑这种烦恼,一心一意于自己的dancer人生。
对本门学科的意义:坚定向前的的信心不动摇。对人类的行为和性质进行哲学上的反思,避免过于轻浮。
15.机器学习,深度学习,专家系统,强化学习,自然语言处理。
16.人工智能和人一起打游戏,让另一个人工智能抓出来哪个是真人哪个是人工智能。
17.相比于习题2而言Lovelace 2的测试更注重测试AI的创造力。
第二部分:基础知识
本章的章首由AI的基础是什么来切入主题
观点1.AI的基础是搜索
观点2.AI的基础是逻辑
第二章:盲目搜索:
思考 盲目搜索法的盲目性:
盲目搜索需要在历经所有存在的路径之后才能判断出通往目的状态的最佳路径
使用盲目搜索一定可以找到结果,但是这也伴随着花费大量的空间和时间。并且随着节点的增多,复杂度的增大,花费的时间空间增长速度较快。
盲目搜索的盲目性体现在他忽略其他内在问题或者已知条件,将注意力完全放在解决问题上。其中,其所忽略的信息可能是一些限制条件,也可能是一些便利条件。这代表着,盲目搜索获得结果要花费更长的时间(一些已知错误的路径要撞到南墙才会回头,缺少随时判断当前状态是否能达到目标状态的能力,需要花费大量时间和空间)。
2.0 简介系统中的搜索:
简介介绍:
1.状态空间图——一种有助于形式化搜索过程的数学结构
2.生成-测试搜索范式
3.贪心算法和回溯法 : 这两种方法都首先将问题分成若干步骤。
4.盲目搜搜: 深度优先搜索(BFS) 和 广度优先搜索(DFS):如果一个问题存在解,那么BFS就一定能够找到它
缺点是:如果在每个时刻的可选项非常多,那么 BFS 可能会因为需要消耗太多的内存而变得不实用。
2.1状态空间图:
通过状态空间图进行搜索和分析,获得通往解的可能的可选路径。
假币问题:
将硬币分为2,2,2三组分别记作abc
随机抽取abc中的两组假设挑选的是ab两组
此时有两种情况
1.天平偏向一方:
表明假币在ab中,而c中全为真币
再将ab中一组与c比较,假设取出的为a
1.1天平偏向一方:
假币在a中,再从ac中各取出一个硬币放于天平
1.1.1天平偏向一方:
取出即为假币
1.1.2天平未偏移:
a中剩余为假币
1.2天平不倾斜:
假币在b中,从bc中各取一枚硬币放于天平结果见上1.1.1和1.1.2
2.天平不倾斜:
天平不倾斜则假币位于c中,具体操作见上文
十二枚硬币:
1.分4,4,4
44称取
1.如果不偏移,称取剩余的4
2.如果偏移,则假币在4+4中
2.1假设是左重右轻
将剩余的八个币进行分组,交换两个币(1组),拿出三个币(从一边)并用确定为真币的几个币补全(2组),剩余的三个币(3组)
接下来有三个平衡状态分别可以证明假币在三组中的哪一组
1.天平持平:2组
2.天平仍然表示左重右轻:3组
3.天平的表示右重左轻:1组
并且可以确定假币的轻重
在分为1+1或1+1+1称重可以确定假币
(解决这个问题要认清天平的三种状态,左倾右倾和持平分别会产生什么样的判断)
由假币问题,引出了我们正文状态空间树
状态空间树由 节点 和 分支 组成
起始节点表示问题的起始状态
目标状态搜索的结果
状态空间树包含了问题能够产生的所有可能状态,并包含所有可能的结果。
搜索始于起始节点,终于目标状态
这种方法不计较寻找解的代价代表这这种方法往往伴随着高昂的运行时间
在计算机中,解的代价指的是运行时间而不是软件的开发时间
节点不等于状态,每个问题的节点都处于某种状态中,但是多个不同的节点可能处在相同的问题状态下。
2.2.0生成--测试范式:
生成器:一个可靠的生成器必须生成所有可能符合条件的解,如果这个生成器给出了每个可能满足条件的解,我们就称这个生成器为完备的。
一个好的生成器还应该该是非冗余的,即相同的解不会给出两次
如果生成器有一些信息,允许其对产生的解做出限制,那么这个生成器就是知情的。
{While没有找到解,但仍有候选方案
[生成可能的解 测试其是否满足所有的问题约束条件]
End While}
IF找到某个解,则宣布成功,并输出此解
Else宣布没有找到解
(生成器知情可以在生成时避免一些已知错误的通往解的路径,从而降低搜索的成本。)
2.2.1回溯法:
回溯法是对完全枚举法的改进。
完全枚举法:获得所有可能的结果,无论结果是否是解,在搜索过程中,即便已经到达无法获得正确解的地步,也会继续枚举下去。
为了避免上述问题造成的时间和空间的浪费,要求我们在完成一步以后,检测当前状态是否已经违反了限制条件(即当前状态是否还能够找到解)
改良以后的方法即为回溯法:
针对某个问题,将解决问题的过程划分步骤,在完成每个步骤之后,检测能否达成目标状态。若不能,返回上一步并继续尝试该节点的下一个状态。
2.2.2贪心算法:
利用贪心算法(greedy algorithm),我们可以得到另外一种搜索方法。这种搜索方法也是先将一个问题分成几个步骤进行求解,其中每次只考虑一个输入。
贪心算法总是包含一个必须优化(将问题大化小 或 小化大),典型用法是解决旅行距离、开销或持续时间问题。寻找最佳解这一类的问题。
贪心算法从局部看待最佳。总是做出当前状态的最佳选择,把每个节点的最佳选择联系起来,组成可能是最佳的解(其中“局部”的改变并不是局部的移动,而是局部的放缩,动态变化的局部)。
利用书本的例子来讲。
1.从v1到最近的v5
2.从v1到第二近的v2,到达v2的路径包含了前几步的部分,拿来做比较。
3.从v1到v4,包含了前几步的部分,即v5-v4,v2-v4,v1-v4三部分,比较大小。
4.从v1到v3,包含前几步的部分,即v2-v3,v4-v3。拿来比较。
每一步的选择都建立在前一步最佳选择的基础上。利用v2-v4举例而言,若通过v2到v4这个路径最短(指经过v2-v4路径的由v1到v4的路程),那么前提是v1到v2的路程是最短的。
Dijkstra 短路径算法:用于解决贪心算法范式无法解决的问题
分支定界算法是广度优先搜索的一种变体,又称为统一代价搜索
2.3盲目搜索:
盲目搜索主要分为以下三种:
深度优先搜索(DFS)、广度优先搜索(BFS)和迭代加深的深度优先搜索
这些搜索具备以下的性质:
(1):他们不使用启发式估计
(2):他们的目标是找出给定目标的某个解。寻找是不定项的,不能定向找出最佳解。只能通过找出所有可能的解进行比较。
深度优先搜索:
在每个节点做出选择时优先选择向左,总是试图深入树中进行搜索。
拼图问题:利用盲目搜索,随时记忆已经出现过的状态。
广度优先搜索:
按照层级从左到右逐层访问,访问过程中记录节点的状态,跳过已经具备已经出现过的状态的节点,记录未出现的状态减少搜索成本。
2.4盲目搜索法的实现和比较
搜索法的实现一般有一个共同点,那就是要维护两张表,一张开放表(open list)和一张封闭表(closed list)
开放表包含树中所有待探索的节点(或扩展的节点)
封闭表包含所有已探索或不必探索的点。
栈:一种后进先出的数据结构。即最后进栈的先出去。对数据的操作仅在栈的一端,我们称为栈顶
列:一种先进先出的数据结构。
2.4.3问题求解性能的衡量指标 :
四种衡量指标:
完备性:如果搜索法可以保证获得一个结果,就说这个算法是完备的。
最优性:搜索法所获得的解是否是最优解
时间复杂度:时间复杂度关注的是找到解所需要的时间,这里可以根据搜索过程中生成(或扩展)的节点的个数
空间复杂度:空间复杂度关注的是内存的开销。
特别的对于AI而言用如下三个参数表示:
(1):节点的分支因子(branching factor,记为 b),指的是从节点出发的分支数
(2):节点的分支因子(branching factor,记为 b),指的是从节点出发的分支数
(3):参数 m 给出的是状态空间中所有路径的 大长度。
深度优先搜索和广度优先搜索的比较:
两种搜索在适合解决不同的问题。
深度优先搜索(DFS):
树很深。
分支因子不太大,并且 解出现在树中的位置相对较深。
广度优先搜索(BFS):
搜索树的分支因子不太大(一个适度的 b 值)。当整棵树的分支因子实际上很大时,
BFS 会因为有过多的路径需要探索而不堪重负。 解出现在树中的位置在合理的深度(一个适度的 d 值),并且 所有路径都不是特别深。
BFS利于寻找浅的目标结果,如果每个节点都有b个新的节点,那么时间复杂度会随着层数的递增指数增长。
在经过对广度优先搜索和深度优先选择的思考之后,一种新的搜索迭代加深的DFS即DFS-ID(DFS With Iterative Deepening)诞生了。
DFS-ID 执行一个 DFS 算法,其状态空间的深度的界为 0。
如果没有找到目标,就执行另一个 DFS 算法,此时深度的界为 1。
以此往复,每次迭代深度的界+1。
在每次迭代中,一个完备的 DFS 都要执行到当前深度。在每次迭代中,搜索都要重新开始。
DFS-ID 的时间复杂度是 O(bd),这比 BFS 稍好。在 坏的情况下,所有的盲目搜索算法,包括 DFS、BFS 和 DFS-ID,都会表现出指数级的时间复杂度。DFS-ID 每次只需要在内存中存储一条路径,因此它的空间复杂度为 O(b*d),这与 DFS 相同。
(盲目搜索的搜索成本会随着问题的复杂度加深而变得不合时宜)
第二章讨论题:
1.搜索为什么是 AI 系统的重要组成部分?
搜索串联起始状态和目标状态,通过搜索可以获得目标信息和有效信息。
2.状态空间图是什么?
状态空间是问题的一种表示方法,某个具体问题的解将对应状态空间图中的一条路径。
3.描述生成-测试范式。
分为生成和测试两部分,生成负责生成所有可能的解,测试部分筛选出符合题意得解。
4.生成器有什么属性?
完备的,非冗余的,知情的
5.回溯法如何对完全枚举法进行改进?
回溯法能够判断当前节点能否找到解,若不能则回溯到上一节点。
6.用一两句话描述贪心算法。
贪心算法将问题分步骤进行,将每一步的最佳建立在上一步最佳的基础上。
7.陈述旅行商问题。
给定 n 个顶点的加权图(即每条边上带有开销值),求从某个顶点 Vi 出发经过加权图中的所有顶点(每个顶点只经过一次),然后返回到 Vi 的 短路径。
8.简述 3 种盲目搜索算法。
DFS深度优先搜索:在每个节点优先向左,即优先选择深入树的路径。
BFS广度优先搜索:每层由左到右探索,逐层深入。
DFS-ID迭代加深的深度优先搜索:限制一定的深度进行深度优先算法,若在限制内未得到解,则降低限制进行深度优先搜索,以此往复。
9.在何种意义上,盲目搜索算法是盲目的?
搜索过程中无法确定该节点能否通向目标状态。
不考虑问题的特定信息,仅通过穷举的方式获得解
10.按照完备性、 优性和时空复杂性,比较本章描述的 3 种盲目搜索算法。
完备性:
若某条路的长度是无限的DFS不完备。
若某个节点的分支是无限的BFS不完备。
如果给定无限大空间或者是达到了难以遍历所有节点的结果,迭代加深的DFS不完备
优性:
盲目搜索一般不具备最优性。
时空复杂度:与上无法实现完备性的缺陷基本一致。(当问题复杂繁琐时,盲目搜索的完备性,时空复杂性可能会严重受损)
11.在什么情况下,DFS 比 BFS 好?
解位于树的深层,每个节点的分支较多。
12.在什么情况下,BFS 比 DFS 好?
解出现在较浅层,并且分支因子不太大。
13.在什么意义上,可以说 DFS-ID 是 BFS 和 DFS 的折中?
DFS-ID的时间复杂度介于两者之间,空间复杂度则与DFS相同
练习题:
1.在只允许称重 3 次的情况下,求解 12 枚硬币的假币问题。回忆一下,天平可以返回以下 3 种结果之一:相等、左侧轻或左侧重。
将12枚硬币编号为1,2,3……11,12
第一次称取:将1,2,3,4和5,6,7,8分别放在两端。
若平衡:将1,2和9,10分别放在两别称取
若平衡:将1和11称取
若平衡:12为假币
若不平衡:11为假币
若不平衡:将1和9称取
若平衡:10为假币
若不平衡:9为假币
若不平衡:记此时为右倾。将1,2,3,8和9,10,11,4分别称取。
若右倾:称取1,2
若右倾:1为假币
若左倾:2为假币
若平衡:3为假币
若左倾:称取1,4
若平衡:8为假币
若倾斜:4为假币
若平衡:称取5,6
若左倾:5为假币
若右倾:6为假币
若平衡:7为假币
(在一种假设且自身不知情的情况下,每枚硬币都有可能为假币,找到每枚硬币为假币的搜索路径才算成功)
2.在只称重两次的情况下,求解微型假币问题或证明这是不可能的。
在假币问题中,每次称取可能出现的结果有三种,即左右倾和平衡,即每个节点最多只有三个分支,两次称重最多可以产生9个结果,即在已知只有一枚假币的前提下,最多只能证明9枚硬币是假币的可能,无法证明12枚硬币。
3.非确定性搜索(nondeterministic search)是本章未讨论的一种盲目搜索方法。在这种搜索中,刚刚扩展的子节点以随机顺序放在开放表中。请判断非确定性搜索是否完备以及是否 优。
不是完备的,无法保证在有限的步骤中寻找到解
不是最优的,节点的扩展顺序是随机的,无法保证在最短的时间寻找到解
4.n 皇后问题的另一个生成器如下:第一个皇后放在第一行,第二个皇后不放在受第一个皇后攻击的任何方格中。在状态 i,将第 i 列的皇后放在未受前面(i−1)个皇后攻击的方格中,如图 2.34 所示。

(a)使用这个生成器求解 4 皇后问题。
[横,纵]
[[1,3],[2,1],[3,4],[4,2]]
[[1,2],[2,0],[3,1],[4,3]]
(b)证明这个生成器比文中使用的两个生成器拥有更多的信息。
文中使用的生成器需要遍历所有可能摆放的结果。
而这个生成器会将不能摆放棋子的格子标记出来。
(c)画出搜索第一个解时在搜索树中展开的部分。
[1,4] [1,3] [2,3] [2,4](要至少考虑其中的1/4)
5.思考下列 4 皇后问题的生成器:从 i=1 到 i=4,随机地分配皇后 i 到某一行。这个生成器完备吗?非冗余吗?解释你的答案。
不完备也不是非冗余。
不断的随机的结果并一定能够找到正确答案,随机性可能产生两个相同的解,所以不是非冗余的。
6.如果一个数等于其因数(不包括这个数本身)的和,则称这个数是完美数。例如,6 是完美数,因为 6 = 1 + 2 + 3,其中整数 1、2 和 3 都是 6 的因数。给出你所能想到的拥有 多信息的生成器,使用这个生成器,可以找到 1 和 100 之间(包括 1 和 100 在内)的所有完美数。
生成(2n-1)×2(n-1)查看是否在1-100之间,超过100则退出循环。
(奇数的因数也一定为奇数,而奇数与奇数的和为偶数,即在前提条件上要添加一条:因数的个数也为奇数。而此类奇数的因子的性质皆来自比自身小的奇数,后者的因数和未有大于自身的情况,至少在0-100之间奇数没有完美数)
7.使用 Dijkstra 算法找到从源顶点 V0 到所有其他顶点的 短路径,如图 2.35 所示。

图 2.35 使用 Dijkstra 算法的标记图
节点 | 距离出发点的距离 | 前面点 |
---|---|---|
0 | 0 | 无 |
1 | 4 | 0 |
2 | 7 | 1 |
3 | 6 | 1 |
4 | 7 | 3 |
8.创建拼图(如 15 拼图)的表示以适合检查重复状态。
建立3维列表,第一维作为标号,剩余二维列表用于记录位置。
9.使用广度优先搜索求解传教士与野人问题。
10.在河的西岸,一个农夫带着一匹狼、一只山羊和一篮子卷心菜(参见图 2.0)。河上有一艘船,可以装下农夫以及狼、山羊、卷心菜三者中的一个。如果留下狼与羊单独在一起,那么狼会吃掉羊。如果留下羊与卷心菜单独在一起,那么羊会吃掉卷心菜。现在的目标是将它们都安全地转移到河的对岸。请分别使用以下搜索算法解决上述问题:
(a)深度优先搜索;
(b)广度优先搜索。
11.首先使用 BFS,然后使用 DFS,从图 2.36(a)和图 2.36(b)的起始节点 S 开始,终到达目标节点 G。其中每一步都按照字母表顺序浏览节点。
12.标记图 2.37 所示的迷宫。
13.对于图 2.37 所示的迷宫,先使用 BFS,再使用 DFS,从起点处开始走到目标处。
BFS属于多线程操作,相当于在每个分路口同时选择所有可能的方向进行探索到下一个分路口,直到找到目标,
类似如此的迷宫有一种必定能找到目标的走法就是贴着左墙,或右墙走(还可以防止迷路)就是利用深度优先搜索的原理,将每个路口走到头。
  图 2.36 使用 BFS 和 DFS 到达目标节点 图 2.37 迷宫
14.我们已经确定,12 枚硬币的假币问题需要对 3 组硬币进行称重才能确定假币。那么在 15 枚硬币中,需要称重多少次才可以确定假币?20 枚硬币时又会怎么样?请开发出一种算法来证明自己的结论。
按照之前题目的回答,无论15还是20都可以在4此内称出。
提示:可以先考虑 2~5 枚硬币所需的基本称量次数,从而开发出事实知识库,自底向上得到这个问题的解。
15.我们讨论了传教士与野人问题。假定“移动”或“转移”是强行(受迫)的,找出这个问题的一个解。确定问题解决状态的“子目标状态”,我们必须获得这个状态,才能解决这个问题。
编程题:
1.编写程序来解决 15 拼图的实例,首先检查目标状态是否可达。你的程序应该利用下列搜索算法。
(a)深度优先搜索。
(b)广度优先搜索。
(c)迭代加深的深度优先搜索。
#关键在于超看目标状态和起始状态的逆序数奇偶性是否相同
dic=[]
#nums是正确排布的列表
nums=list[list[int]]
#nums1是当前状态
nums1=
def ex(一维数组):
求逆序数
def dfs(nums,deep):
if nums==nums1
return True
for#各个分支:
if dfs(nums,deep+1):
return True
return False
def bfs(li):
li1=li.coppy()
while li1:
num=li1.pop(0)
if ==:
return True
for #遍历节点:
return False
def ids(nums, max_depth):
for depth in range(max_depth):
if dfs(nums, 0, depth):
return True
return False
2.编写程序,使用贪心算法找到图的 小生成树。图 G 的生成树 T 是其顶点集和图 G 的顶点集相同的树。考虑图 2.38(a),图 2.38(b)给出了一棵生成树。可以看到,图 2.38(c)中的生成树具有 小的代价,这棵树被称为最小生成树(minimum spanning tree)。要求编写的程序能够找到图 2.38(d)中的 小生成树。
#由v3开始寻找
串联v3和v2
串齐v3和v4
v5对比v2,v3,v4距离选择v3.
v1对比v2和v5的距离选择v5
v6对比v1,v2,v5的距离选择v2
3.编写程序,使用回溯法来解决 8 皇后问题,然后回答以下问题。
(a)有多少个解?
import numpy as np
def dfs(dic1,dic2,dic3,n):
if n>8:
return 1
ans=0
for i in range(8):
if i not in dic1 and i not in dic2 and i not in dic3:
ans+=dfs((dic1+[i]),(dic2+[i])+1,(dic3+[i])-1,n+1)
return ans
print(dfs([],[],[],))
(b)这些解中有多少个是有区别的?(可通过阅读第 4 章的习题 5 来获得提示)
所有解都是有区别的
(c)使用哪种生成器?
 图 2.38 查找图的 小生成树
(a)图 G (b)图 G 的生成树 (c)图 G 的 小生成树 (d)需要找到 小生成树的图
4.编写程序,采用习题 5 中建议的生成器解决 8 皇后问题。
5.在国际象棋中,马有以下 8 种不同的走子方式:
(1)从上一个方格,到右两个方格;
(2)从上一个方格,到左两个方格;
(3)从上两个方格,到右一个方格;
(4)从上两个方格,到左一个方格;
(5)从下一个方格,到右二个方格;
(6)从下一个方格,到左两个方格;
(7)从下两个方格,到右一个方格;(8)从下两个方格,到左一个方格。
所谓 n×n 棋盘上的马踏棋盘问题(a knight’s tour,又称马周游、骑士漫游或骑士之旅问题),是指马从任何棋格出发,遍历剩下的 n2−1 个棋格,并且每个棋格只访问一次。显然整个过程是 n2−1 步走子的序列。
编写程序,实现 n 等于 3~5 时的马踏棋盘问题。采用随机数生成器随机选择起始棋格并报告程序的运行结果。
在5*5时出现一个结果(3,3) (4,1) (2,0) (0,1) (2,2) (1,4) (0,2) (1,0) (3,1) (4,3) (2,4) (0,3) (1,1) (3,0) (4,2) (3,4) (1,3) (2,1) (0,0) (1,2) (0,4) (2,3) (4,4) (3,2) (4,0)
(2,4) (0,3) (1,1) (3,0) (4,2) (3,4) (1,3) (0,1) (2,0) (4,1) (3,3) (1,4) (0,2) (1,0) (2,2) (4,3) (3,1) (2,3) (4,4) (3,2) (4,0) (2,1) (0,0) (1,2) (0,4)
6.在为图着色时,将颜色分配给图中的节点,使得任何两个相邻节点的颜色都不同。例如,在图 2.39 中,如果节点 V1 被着色为红色,则节点 V2、V3 或 V4 都不能被着色为红色。然而,因为节点 V1 和 V5 不相邻,所以节点 V5 可以用红色着色。
 图 2.39 待着色的图
图的着色数是对图着色所需的 小颜色数目。各种图的着色数如图 2.40 所示。

图 2.40 各种图的着色数
编写回溯程序,对图 2.41 中的图进行着色(采用你可以想到的拥有 多信息的生成器)。

#先从节点最多的点入手。,节点最多的点对周围的影响大,利于排除,之后颜色按照一定次序并判断是否符合条件即可
v=[]
col=[]
#要把相邻的记录下来。
for i in v:
if 相邻:
col加一个数字
else:
不变
最后输出col的个数
不存通过影响周围的数形成的扩散影响。
回溯:
def dfs(ans,dic,n):
if n>:
return len(ans)
for i in col:
for j in 相邻:
有相等break
else:
如果没有相等,那他就在剩余颜色中选择
for 这些颜色:
return dfs()
ans里面加颜色
return dfs()
最后返回的是包含颜色的数组。求长度
第三章:知情搜索:
第二章中我们了解了盲目搜索,盲目搜索的盲目性使得其在解决问题使执着于找出通往解的路而忽略思考如何找这条道路的方法,在第三章中,我们会了解到知情搜索,不同于盲目搜索,知情搜索正注意利用启发式搜索降低搜索成本。
启发式方法有助于在搜索空间中引导前进的路线。3.2 节~3.4 节将描述 3 种“永不回头看”的搜索算法,它们分别是爬山法(hill climbing)、最佳优先搜索(best- first search)和集束搜索(beam search)。在状态空间中,它们的路径完全由到目标的剩余距离的启发式评估值(近似值)来引导。
启发式方法具备一些性质,比如:
可容许性(或可采纳性):如果想要某个启发式方法有用的话,就应该低估(underestimate)剩余距离。在上一段中,很显然直线距离通常小于或等于实际距离
单调性:这个性质要求在向前搜索时,剩余距离的启发式评估值应该持续减小。
根据启发式算法能够避免的不必要的搜索的能力对启发式方法进行分级。
3.1启发式启发式方法:
启发式方法能够大幅减少寻找目标结果需要考虑的节点数目,这使其非常适合解决一些组合复杂程度高快速增长的问题。
heuristic作为新的形容词被确认,意为:“启发式的”。
这个述语有两种用法:
(1) 描述了一种学习方法,这种学习方法的尝试不需要一个安排好的假设,也不需要证明结果是否符合这个假设。也就是说,这是一种“凭经验”或基于“试错”的学习方式。
(2) 与通过经验获得的一般性知识的使用有关,有时候表达为“使用经验法则”(但是,启发式知识既可以应用于复杂问题,也可以应用于简单的日常问题。人类棋手使用的就是启发式方法)。
同时,heuristic具有名词的意思,意为某条具体的经验法则或来自经验的论证。启发式知识在某个问题上的应用有时候被称为启发式方法。
书中描述给出了启发式搜索的一些定义:
它是提高复杂问题求解效果的一种实用策略。
它引导程序沿着一条 可能的路径到达 终解,而忽略那些 没有希望的路径。
它应该能够避免去检查“死路径”,并且只使用已收集到的数据[15]。
我们可以将启发式信息以如下方式添加到搜索中。
决定接下来要扩展的节点,而不是严格按照广度优先或深度优先的方式进行扩展。
在生成节点的过程中,决定生成哪个或哪些后继节点,而不是一次性生成所有可能的后继节点。
确定哪些节点应该从搜索树中丢弃或裁剪[2]。
博尔克和西斯基[3]补充说:“……在构建解的过程中,使用启发式信息增加了获得结果的不确定性……这是由非正式知识(规则、规律、直觉等)的使用造成的,而这些知识的有用性从未得到充分证明。因此,应在算法给出不满意的结果或不能保证给出任何结果的情况下采用启发式方法。在求解非常复杂的问题时,特别是在语音和图像识别、机器人和博弈策略问题中,启发式方法特别重要(此时精确的算法失效)。”
3.2知情搜索第一部分:
下面介绍最基本的三种算法:
”爬山法“
”最陡爬山法“
”最佳优先搜索法“
爬山法:在爬山法中,爬山者会接近一个目标状态(但可能无法到达目的状态)。
简单形式的爬山法是一种贪心算法,因为它没有历史意识,也没有能力从错误或错误路径中恢复。它会使用某种衡量指标(不管是 大化还是 小化这种衡量指标)来引导自己到达目标并确定下一步的选择。(只能够确定自己选择的道路是否是在接近目标,但不能确定选择的道路能够达到目标,即像爬山一样,海拔的提升表明在接近目标,但是不能确定所爬的山峰是最高峰)
最陡爬山法:该搜索法是爬山法的进阶形式,在爬山法的基础上,爬山法的指标是选择的下一步状态是否优于当前的状态,此处的优指的是是否靠近目标状态。而陡爬山法的选择指标是在所有给定的可能状态集合中选择“ 优”的一步(此时选择的是得分 高的一步)。
最佳优先搜索:
最佳优先搜索是我们讨论的第一个为达到目标而考虑探索哪些节点以及探索多少个节点的 智能算法。
最佳优先搜索优于爬山法的地方在于,它可以在通过回溯到开放列表的节点,从错误,假线索,死胡同中恢复。如果按照相反的顺序追踪封闭节点列表,并忽略到达死胡同的状态,则可以用来表示所找到的 优解。
用好的启发式度量方法将会很快找到一个解,甚至可能找到 优解。而糟糕的启发式度量方法有时会找到一个解,但即使找到了,这个解通常也不是 优解。
3.4集束搜索:
在集束搜索中,探索通过搜索树逐层扩展,但是每层只有 好的 W 个节点才会得到扩展。
W 被称为集束宽度(beam width)。 (在每一层规定探索的范围)
(如果说ID-DFS是对DFS利用BFS的特性进行改进,那么集束搜索就是BFS根据DFS的特点进行改进。集束搜索中,搜索树的每层将会挑选出一定数量的节点进行接下来的步骤)
福西(Furcy)和柯尼希(Koenig)研究了关于集束搜索的“差异化”变体,发现通过使用更大的集束可以发现更短的路径,而不会耗尽内存。在这里,差异化指的是对后继节点的选择,这时并不会从左到右返回 优启发值。
3.5 搜索算法的其他指标 :
标准搜索 | 广度优先搜索 | 统一开销搜索 | 深度优先搜索 | ID-DFS | 有限深度搜索 | 双向搜索 |
---|---|---|---|---|---|---|
时间复杂度 | b**d | b**d | b**m | b**l | b**d | bd/2 |
空间复杂度 | b**d | b**d | b**m | b**l | b**d | bd/2 |
优的? | 是 | 是 | 否 | 否 | 是 | 是 |
完备的? | 是 | 是 | 否 | 是,前提:l>=d | 是 | 是 |
b:分支因子
d:解的深度
m:搜索树的大深度
l:深度限制
3.6知情搜索--找到最优解:
对于找到最优解的问题,书中给出了以下思路
3.6.1分支定界法:
在文献中通常称为统一开销搜索或统一代价搜索。该算法会按照递增的开销—更精确地说,是按照非递减的开销来寻找路径
3.6.2使用低估计启发值的分支定界法。
本节使用剩余距离的低估计启发值来增强分支定界法
3.6.3采用动态规划的分支定界法:
这个算法给出的建议如下:如果两条或更多的路径到达一个公共节点,那么只有到达该公共节点且具有 小开销的路径才应该被存储(删除其他路径!)。我们在 3 拼图实例上实现了这个搜索过程,并考虑了一棵类似于广度优先搜索的搜索树上的结果。只保留到达每个拼图状态的 短路径,有助于禁止环路的出现。
3.6.4 A*搜索:
采用曼哈顿距离作为启发式估计值。
3.7知情搜索-高级搜索算法
3.7.1约束满足搜索
在对更大或更复杂的问题进行求解时,可以识别出其中更小的可处理的子问题,这些子问题通过较少的步骤就可以解决。--问题简化
3.7.2与或树:
这里的目标是,通过应用以下规则,在给定的树中找到解的路径,如果满足以下条件,那么节点是可解的。
(1)它是一个终止节点(一个基元问题)。
(2)它是一个非终止节点,并且其后继节点都是可解的与(AND)节点。或者
(3)它是一个非终止节点,后继节点是或(OR)节点,在这些或节点中,至少有一个可解。
类似地,在下列条件下,节点是不可解的。
(1) 它是一个没有后继节点的非终止节点(没有运算符可应用的非基元问题)。
(2) 它是一个非终止节点,后继节点是与(AND)节点,在这些与节点中,至少有一个不可解。或者
(3) 它是一个非终止节点,后继节点是或(OR)节点,并且这些或节点都是不可解的。
3.7.3 双向搜索
双向搜索的想法是在向前搜索目标状态的同时,从已知的目标状态向后搜索到起始状态,以找到解的路径。
只需要有限的存储空间,双向搜索就可以非常高效 地执行,而标准方法对存储空间的需求是其已知的不足。
波形规整算法:通过以下措施优化BS*算法(由 Kwa[14]开发,它克服了 BHPA 效率低下的问题)
(1) 小化搜索方向切换的次数(周界搜索的一种版本)。
(2) 在反搜索方向的前端到末端评估中,将动态特征添加到搜索启发式函数中,这是由波尔 先提出的思想。
讨论题:
1.启发式搜索方法与第 2 章讨论的搜索方法有什么区别?
(a)给出启发式搜索的 3 种定义。
它是提高复杂问题求解效果的一种实用策略。
它引导程序沿着一条 可能的路径到达 终解,而忽略那些 没有希望的路径。
它应该能够避免去检查“死路径”,并且只使用已收集到的数据。
(b)给出将启发式信息添加到搜索中的 3 种方式。
决定接下来要扩展的节点,而不是严格按照广度优先或深度优先的方式进行扩展。
在生成节点的过程中,决定生成哪个或哪些后继节点,而不是一次性生成所有可能的后继节点。
确定哪些节点应该从搜索树中丢弃或裁剪
2.为什么爬山法可以归类为贪心算法?
贪心算法为局部最优解,而爬山法是在每一步选择“上升海拔数”最大的选择。即符合局部最优解的特性
3. 陡爬山法如何提供 优解?
计算下一步解在当前解中的梯度或斜率,沿着梯度或斜率最大的方向移动。
4.为什么 佳优先搜索比爬山法更有效?
不同于爬山法,最陡爬山法的选择是给定所有状态集合中最优的一步。这里的最优是陡峭程度,而不仅仅是海拔提升最大。
5.解释集束搜索的工作原理。
集束搜索按层数遍历搜索树,但是在每层只从某些节点继续进行。
6.启发式方法的可接受性(admissible)是什么意思?
(a)可接受性与单调性有什么关系?
可接受性指启发式方法能够找到一个可行的解,且该可行解可以被接受,即给予足够的时间,程序至少可以找到可行的解,改解不一定是最优解,但是符合所有约束条件。
单调性:随着时间投入的增加找到的解的质量会有所提高。
具备单调性的搜索法通常也具备可接受性,因为随着时间投入的增加,解的质量提高会得到符合约束条件的。
(b)可以只有单调性,而不需要可接受性吗?解释原因。
单调性解的质量会随着时间投入增多而提高,但并不代表最后的结果会是一个符合条件的解。因此,如果只具备单调性而不具备可接受性,在实际应用中可能并不可靠。
7.一种启发式方法比另一种启发式方法具有更多的信息,这句话的意思是什么?
从结果来看,具有更多信息的启发式方法可以避免更多不必要的节点。
8.分支定界法背后的思想是什么?
将复杂的问题分成若干个简单的问题。
9.请解释低估可能会得到更好的解的原因。
低估可能会得到更好的解的原因是因为在分支定界法中,我们通过将问题分解为较小的子问题来缩小搜索范围。在定界的过程中,我们为每个子问题估算对应的目标值的界限。如果某个子问题的界限被低估了,即该子问题的最优解的目标值小于所估算的界限,那么我们可以确定该子问题的最优解一定不会超过估算的界限
10.关于动态规划:
(a)动态规划的概念是什么?
将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。
(b)描述 优性原理。
原问题的最优解由组成大问题的所有小问题的最优解组成。
11.为什么 A*算法比使用低估计启发值的分支定界法或使用动态规划的分支定界法更好?
该算法利用优先队列等方法避免陷入局部最优解中。
它利用更准确的启发式函数,有利于快速找到更优解。
适用范围广
灵活性:创作者运训根据问题来调整函数,从而更好地适应解决问题
12.解释约束满足搜索背后的思想,以及它是如何应用于“驴滑块”拼图问题的。
约束满足是一种基于搜索的算法用于解决约束满足问题,核心思想是使用搜索树枚举所有可能的变量赋值组合,并使用回溯法或其他策略来逐步构建满足所有约束的解。
解决“驴滑块”拼图问题的基本思想
- 定义问题:首先,将“驴滑块”拼图问题定义为约束满足问题。这包括定义变量(拼图块的位置)和约束(拼图块之间的相对位置关系)。
- 初始化搜索树:搜索树的每个节点表示一种可能的拼图布局。每个节点包含所有拼图块的位置信息,以及是否满足所有约束的信息。
- 搜索解空间:通过搜索树,算法会尝试各种可能的拼图布局,并使用回溯法或其他策略来逐步构建满足所有约束的解。在搜索过程中,算法可能会遇到不满足约束的情况,这时需要回溯到前一步并尝试其他可能的解。
- 启发式搜索:为了加速搜索过程,可以使用启发式函数来指导搜索的方向。启发式函数可以基于当前解与目标解的距离、变量的权重等。
- 找到解或确定无解:如果搜索成功找到了一个满足所有约束的解,那么问题得到解决;如果搜索完整个解空间仍未找到满足所有约束的解,那么可以确定该问题是无解的。
13.解释如何用与或树来划分搜索问题。
与或树的划分是将一个复杂问题划分为一系列子问题,每个子问题都包含原始问题的一部分约束将这些问题进一步划分为更小的子问题直到最终问题可以直接求解。
14.描述,双向搜索的工作原理。
双向搜索的工作原理
- 定义搜索空间:首先,确定搜索空间的上下界,即问题解的最大值和最小值。
- 同时进行两个方向的搜索:在给定的上下界之间,同时从上限和下限开始进行搜索。
- 逐步逼近最优解:在每个阶段,算法会评估当前两个搜索点的质量。如果从上限出发的搜索点质量高于从下限出发的搜索点,则将上限缩小为该点的值;反之,如果从下限出发的搜索点质量更高,则将下限提升为该点的值。
- 收敛:通过不断地缩小上下界,算法最终会找到一个足够接近最优解的区间,并在这个区间内找到最优解。
(a)它与本章中讨论的其他技术有什么不同?
“双向”搜索是将由问题的两端开始求解向中间靠拢,而不是从一端探索。
(b)描述边界问题和导弹隐喻的含义。
边界问题是指目标函数在搜索空间的边界处取得最优解的问题。在这种情况下,搜索应该特别关注边界附近的区域,因为最优解很可能位于这些区域。导弹隐喻则是指将算法视为导弹,目标是击中(或接近)最优解的目标。这个隐喻强调了算法的精确性和导向性。
(c)什么是波形规整算法?
波形规整算法是一种用于处理信号或数据序列的方法。它的目的是将不规则或非线性的数据波形规整化为更平滑、更易于分析的形式。在优化问题中,波形规整算法可以用于处理目标函数值随变量变化呈现出的不规则或剧烈波动的情况,从而帮助算法更好地逼近最优解。
练习题:
1.给出 3 个启发式方法的例子,解释它们如何在以下情景中发挥重要作用。
- 贪心算法(Greedy Algorithm):
贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。例如,在一个旅行商问题中,贪心算法会选择最近的点作为下一步,而不考虑全局的最优路径。虽然这种方法不一定能找到全局最优解,但在许多情况下可以提供一个相当接近的解。 - 模拟退火(Simulated Annealing):
模拟退火是一种受物理退火过程启发的启发式优化算法。它通过接受一个小的负能量变化来避免陷入局部最优解。这使得算法在搜索过程中能够探索更多的解空间,并最终找到全局最优解。例如,在物流和运输优化问题中,模拟退火可以用来找到最低成本的路线安排,同时考虑到各种限制和需求。 - 遗传算法(Genetic Algorithms):
遗传算法模拟了生物进化中的自然选择和遗传机制。它通过不断迭代和交叉(组合)种群中的个体来寻找问题的解。遗传算法特别适合于处理大规模、高维度和复杂的问题,因为它能够并行处理多个解,并使用自然选择来淘汰不良解。例如,在机器学习和数据挖掘中,遗传算法可以用于特征选择和模型优化。
(a)在日常生活中。
启发式是一种经验法则,我们在日常生活中使用过往经验解决某些问题,其次通过简单问题来理解与之原理相近的复杂化难题也是启发式方法的一种表现
(b)在面对某种挑战时的问题求解过程中。
我们可以通过将问题简化,先解决一个与之类似的简单问题来获得解决这类问题的经验。
2.解释爬山法被归类为“贪心算法”的原因。
爬山法的每一步选择都是当前位置最佳,符合贪心算法局部最佳的条件。
(a) 描述你知道的其他一些“贪心”算法。
01背包问题:将问题分割成从0-目标状态的局部问题,每一步的最优建立在前一步最优的基础上。
(b) 陡爬山法是如何改进爬山法的? 佳优先搜索是如何改进爬山法的? 3.给出一个未在本章中提及的可接受的启发式方法,解决 3 拼图问题。
不同于爬山法仅从当前位置看下一步位置海拔最大,最陡爬山法会计算选择的坡度或者陡度,并选择坡度或者陡度最大的值作为选择。
(a)采用启发式方法执行 A*搜索,求解本章中提出的拼图实例。
通过计算每一步的优先级确定选择。
(b)你提出的启发式方法是否比本章提出的两种启发式方法拥有更多的信息?
4.关于启发式方法,请完成以下练习。
(a) 为传教士与野人问题建议一个可接受的启发值,这个启发值应该足够健壮,从而避免不安全的状态。
传教士与野人的差+当前位置与目标位置的差
(b) 你的启发式方法能够提供足够的信息,以明显地减少 A*算法所要探索的库吗?
是的,一个有效的启发式方法应该能够提供足够的信息,以明显减少A算法需要探索的状态数量。这正是启发式方法的优势之一。通过使用启发式函数,A算法可以在搜索过程中优先探索那些更有可能接近目标状态的节点。这有助于缩小搜索范围,从而显著减少不必要的搜索和计算成本。因此,一个好的启发式方法能够显著提高A*算法的效率和性能。
5.关于启发值,请完成以下练习。
(a)提供适用于图形着色的启发值。
一个节点的邻居之间的颜色冲突数
(b)采用你的启发值找到图 2.41 中的着色数。
根据这个冲突数和其他相关信息,采用A*搜索或其他相应的算法进行着色。具体着色数需要根据实际计算结果来确定。由于缺乏具体图形的着色要求和约束条件,无法给出准确的答案。
6.思考下列 n 皇后问题的变体。
在一个 n×n 的棋盘上,如果一些会被皇后攻击的方块受到兵的阻碍,有超过 n 个皇后可以放在除去“兵”之外剩余的部分棋盘中吗?例如,如果 5 个兵被添加到一个 3×3 的棋盘上,那么这个棋盘上可以摆放 4 个互相不攻击的皇后吗?(见图 3.30)

图 3.30 有策略地将 4 个皇后和 5 个兵摆放在棋盘上。如果有 3 个兵可供我们使用,那么可以将多少个互相不攻击的皇后放在一个 5×5 的棋盘上?[18]
3个
7.在图 3.31 中,用“普通”分支定界法和动态规划的分支定界法,从起始节点 S 行进到目标节点 G。当所有其他条件都一样时,按照字母顺序探索节点。
 图 3.31 使用分支定界法来到达目标
- 将根节点S加入优先队列中,并设置其优先级为0。
- 进入循环,当优先队列不为空时,执行以下步骤:
a. 从优先队列中取出优先级最高的节点,记为node。
b. 如果node等于目标节点G,则找到了一个可行解,将其加入可行解集合中。
c. 否则,将node的子节点加入优先队列中。对于每个子节点,我们需要计算它的优先级。根据题目要求,按照字母顺序探索节点,因此我们可以将每个子节点的优先级设置为node的优先级加上该子节点的字母在所有子节点中的排名。如果某个子节点的优先级高于node的优先级,则说明该子节点有可能包含最优解,将其加入优先队列中。
d. 将node从优先队列中移除。 - 循环结束后,如果可行解集合中包含多个解,则返回最优解;否则,返回空。
8.关于启发式方法,请完成以下练习。
(a)制定可接受的启发式方法来解决第 2 章(见练习 13)中的迷宫问题。
- 定义起点和终点在迷宫中的位置。
- 定义一个启发式函数,计算当前位置与目标位置之间的曼哈顿距离。
- 使用启发式函数作为代价估计,引导搜索过程从起点开始,探索迷宫中的路径。
- 在搜索过程中,根据实际走过的步数和启发式函数的估计值来更新代价。
- 当找到目标位置或搜索达到一定深度时,停止搜索。
(b)采用你的启发式方法执行 A*搜索,解决这个问题。
- 定义起点和终点在迷宫中的位置。
- 创建一个优先队列,用于存储待搜索的位置。
- 将起点加入优先队列中,并将其标记为已访问。
- 进入循环,当优先队列不为空时,执行以下步骤:
a. 从优先队列中取出代价最小的位置,记为当前位置。
b. 检查当前位置是否为目标位置,如果是,则找到了路径,结束搜索。
c. 遍历当前位置的所有相邻位置。
d. 对于每个相邻位置,如果该位置未被访问过,则计算从起点到该位置的实际代价和启发式函数的估计值之和,并将其加入优先队列中。
e. 将当前位置标记为已访问。 - 如果循环结束仍未找到目标位置,则说明没有可行路径,结束搜索。
- 返回找到的路径或空(表示无解)。
9.关于启发式方法,请完成以下操作。
(a)为水壶问题提出一个可接受的启发式方法。
- 起始位置到目标位置的距离:计算水壶从起始位置到目标位置的直线距离或路径距离。
- 目标位置的容量限制:考虑到目标容器可能有一个最大容量,启发式函数可以考虑到这一点,给予超过目标容量的距离一个较大的代价。
- 水壶的容量:考虑到水壶的容量,如果一个路径需要多次装水才能达到目标,那么这个路径可能不是最优的。
(b)采用你的启发式方法执行 A*搜索,解决第 1 章中提出的问题实例。
-
初始化:设定起始位置、目标位置、水壶的容量和目标容器的容量。
-
定义启发式函数:根据上述启发式方法,定义一个启发式函数,综合考虑距离、目标容器的容量限制和水壶的容量。
-
执行A*搜索
:
创建一个优先队列,用于存储待搜索的位置。
将起始位置加入优先队列中,并标记为已访问。
进入循环,当优先队列不为空时,执行以下步骤:
从优先队列中取出代价最小的位置,记为当前位置。
检查当前位置是否为目标位置,如果是,则找到了满足容量限制的路径,结束搜索。
遍历当前位置的所有相邻位置。
对于每个相邻位置,如果该位置未被访问过,则根据启发式函数计算从起始位置到该位置的代价。如果该代价加上水壶当前剩余容量不超过目标容器的容量,则将该位置加入优先队列中。
将当前位置标记为已访问。
如果循环结束仍未找到满足容量限制的路径,则说明没有可行路径,结束搜索。
-
返回结果:如果找到满足容量限制的路径,则返回该路径;否则返回空(表示无解)。
10.在第 2 章中,我们提出了骑士之旅问题。其中,棋盘上的马访问了 n×n 棋盘上的每一个方块。这个挑战一开始会在完整的 8×8 棋盘上给定一个源方块[比如方块(1,1)],目标是找到移动序列,该序列会访问棋盘上的每个方块,每个方块都会被访问且仅仅被访问一次,在后一次移动中,马回到源方块。
(a) 从方块(1,1)开始,尝试解决骑士之旅问题。(提示:对于这个版本的骑士之旅问题,你可能会发现需要大量内存来解决。因此,你可能需要确定一个启发式方法,以帮助引导搜索过程。)
一种启发式方法是将问题分解为较小的子问题。我们可以将棋盘划分为多个小矩形区域,然后分别解决每个区域内的马骑士之旅问题。首先,我们解决包含起始方块的小区域内的骑士之旅问题,并记录下马在每个方块上的移动序列。然后,我们将这个小区域作为参考,解决相邻的较大区域内的骑士之旅问题。在解决每个子问题时,我们可以使用回溯法或广度优先搜索(BFS)来搜索所有可能的移动序列。
(b) 尝试找到一种启发式方法,它能帮助初次求解器找到正确解。
对于骑士之旅问题,一种有效的启发式方法是使用“最远未访问方块”启发式。该启发式方法基于以下观察:为了最小化移动次数,马应该首先访问最远的未访问方块。因此,我们可以按照从起始方块到最远未访问方块的路径进行移动,并记录下这个路径上的所有方块。然后,我们以这个路径为基础,逐步向起始方块靠近,每次选择未访问的最近方块进行访问。
11.编写一个程序,在图 3.17 中应用本章描述的主要启发式搜索算法,比如爬山法、集束搜索、 佳优先搜索、带有或不带有低估计值的分支定界法以及 A*算法等等。
12.在第 2 章中,我们提出了 n 皇后问题。编写一个程序来解决 8 皇后问题,在这个问题中,一旦放置某个皇后,就考虑应用移除任何受到攻击的行和列的约束条件。
def solve_n_queens(n):
def can_place(board, row, col):
for i in range(col):
if board[row][i] == 1:
return False
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
for i, j in zip(range(row, n, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def place_queens(board, col):
if col >= n:
return True
for i in range(n):
if can_place(board, i, col):
board[i][col] = 1
if place_queens(board, col + 1) == True:
return True
board[i][col] = 0
return False
board = [[0]*n for _ in range(n)]
if place_queens(board, 0) == False:
print("Solution does not exist")
return []
result = []
for i in range(n):
result.append("."*(board[i].count(1)) + "Q" + "."*(8-board[i].count(1)))
return result
13.对于骑士之旅问题的 64 次移动的解,在某一点上,必须放弃你在练习 10.b 中所要确定的启发式方法。尝试确定该点。
14.求解“驴滑块”拼图问题(见图 3.26),至少需要 81 次移动。考虑可以应用的子目标来求这个解。
从某个角的1*1格子开始,逐渐扩大棋盘格子到目标值。利用动态规划的思想
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期