首页 / 资讯中心 / 文章详情

人工智能经典习题集与期末复习:知识表示、归结推理与搜索策略

人工智能经典习题集与期末复习:知识表示、归结推理与搜索策略 ★ FEATURED ARTICLE
简介这份人工智能经典习题集及各章总结面向准备期末考试的高校学生与自学者聚焦人工智能理论体系中的概念梳理、发展历程、研究学派、知识表示、推理方法与典型研究领域帮助读者在复习阶段快速定位重点并检验理解。压缩包内含1个doc文件约2.19MB按章节组织绪论、知识与知识表示、推理等内容既有各章小结也配有习题及解答适合课堂同步复习和考前查漏补缺。目前已有101人学习。读者可借助其中的问题求解、产生式规则、语义网络、归结演绎推理等例题理解知识表示与推理过程并通过章节总结串联搜索技术、专家系统、机器学习、神经网络等知识点对需要从习题反推考点、建立复习框架的学习者较有参考价值。1. 期末前一周翻这份习题集先看清它到底能补哪几块期末前一周教材翻到第三章人工智能的定义、五个发展阶段、三大学派、十八个研究领域全混在一起这是很多人打开这份《人工智能经典习题集及各章总结》的真实场景。它更像一份按章压缩的复习骨架绪论把概念收成问答知识表示把谓词、产生式、框架、语义网络四种写法摆在一起推理部分用归结演绎把两道经典题从头推到尾搜索策略把代价树、与或树、α-β剪枝的推演步骤落到纸上最后还附了一个 PROLOG 亲属关系程序。适合期末冲刺的本科生、考研专业课第一轮打底的人也适合已经写代码但逻辑推导手生的工程师。它解决的是“拿到题能不能按步骤写出来”而不是“懂不懂人工智能”这种宽泛问题。2. 绪论与知识表示把三大学派和四种表示法压成可检索的答题骨架2.1 五阶段与三学派先记“入口”再记结论绪论部分最容易背串。这份材料把发展历程切成五段40 年代中到 50 年代末的神经元网络时代50 年代中到 60 年代中的通用方法时代60 年代中到 80 年代初的知识工程时代80 年代中到 90 年代初的新的神经元网络时代90 年代初到现在海量信息处理与网络时代。光背名字不够考试常问“每个阶段的标志性技术是什么”复习时要把阶段名和代表性技术绑在一起神经元网络阶段对应感知机模型通用方法阶段对应启发式搜索和符号处理语言知识工程阶段对应专家系统新的神经元网络阶段对应反向传播训练的多层网络海量信息阶段对应数据驱动的大规模学习。这样串起来简答题才不会只写一句“发展很快”。三大学派的问法更直接给一个方法判断它属于哪个学派。符号主义走心理学和数理逻辑路线认为智能的基本元素是符号智能行为是符号运算的结果连接主义走生理学路线认为基本元素是神经元智能产生于大量神经元的并行分布式联结行为主义走生物演化和控制论路线认为智能取决于感知和行为取决于对外界复杂环境的适应。复习时不要只背定义要会归类专家系统、定理证明、产生式系统归符号主义神经网络、深度学习归连接主义机器人行为控制、感知-动作系统归行为主义。材料里还列了问题求解、逻辑推理与定理证明、自然语言理解、自动程序设计、专家系统、机器学习、神经网络、机器人学、模式识别、机器视觉、智能控制、智能检索、智能调度与指挥、分布式人工智能与 Agent、计算智能与进化计算、数据挖掘与知识发现、人工生命、系统与语言工具等研究领域。背的时候按“感知、推理、学习、行动、系统”五类分组比按序号硬背更稳。2.2 产生式规则表示旅行商综合数据库、规则集、控制系统三件套材料里用五城市旅行商问题演示产生式规则。题目设定是五个城市 A、B、C、D、E 相互可直达且距离已知某人从 A 出发去其余四个城市各参观一次后回到 A找最短路线。产生式表示分四步写综合数据库、初始状态、目标状态、规则集。材料给出的写法是综合数据库为(x)x可以是一个字母也可以是一个字符串初始状态(A)目标状态(Ax1x2x3x4A)规则集为r1: IF L(S)5 THEN GOTO(A) r2: IF L(S)5 THEN GOTO(B) r3: IF L(S)5 THEN GOTO(C) r4: IF L(S)5 THEN GOTO(D) r5: IF L(S)5 THEN GOTO(E)其中L(S)是走过的城市数GOTO(x)是走向城市x。这套规则能表达“走满五个城市后回起点”和“没走满时可以走向某个城市”但它有一个明显的缺口没有约束“不能走已经走过的城市”。如果直接按这套规则做产生式推理综合数据库里会出现A-B-B-...这种重复路径搜索空间会无谓地膨胀。考试答题时如果只抄这五条规则老师一眼就能看出你没考虑约束。更稳妥的写法是补一条匹配条件r2: IF L(S)5 AND B ∉ S THEN GOTO(B) r3: IF L(S)5 AND C ∉ S THEN GOTO(C) r4: IF L(S)5 AND D ∉ S THEN GOTO(D) r5: IF L(S)5 AND E ∉ S THEN GOTO(E) r1: IF L(S)5 THEN GOTO(A)这样规则集才完整。材料最后给出的最短路线是A-C-D-E-B-A总距离56810736。这条路线可以直接用来验证你的规则集从A出发依次匹配到C、D、E、B此时L(S)5触发r1回到A路径合法。如果想把这段规则跑起来可以用一个很小的 Python 脚本模拟产生式系统的“识别-动作”循环。下面这段代码只做规则匹配和路径枚举不计算最短距离因为材料只给了最优路线各段代价没有给完整距离矩阵硬编造其余边权没有意义# 产生式规则匹配的最小演示只枚举合法路径不比较代价 cities ABCDE def applicable(path): path 是已经走过的城市字符串返回当前可用的规则和目标城市 rules [] n len(path) if n 5: # r1走满五个城市后回起点 rules.append((r1, A)) elif n 5: # r2-r5没走满时只能去还没访问过的城市 for c in BCDE: if c not in path: rules.append((fr{c}, c)) return rules def dfs(path, results): if len(path) 6: # A 四个城市 回到 A if path[-1] A: results.append(path) return for rule, nxt in applicable(path): # 回起点只允许在最后一步触发 if nxt A and len(path) ! 5: continue dfs(path nxt, results) results [] dfs(A, results) print(合法回路数量:, len(results)) for p in results[:5]: print(p)这段代码里applicable对应规则集dfs对应控制系统path对应综合数据库。关键参数是n len(path)初始pathA时n1表示已经走过一个城市走到A-C-D-E-B时n5触发回起点的规则。if nxt A and len(path) ! 5这一行是补上的约束防止中途回起点。运行后能枚举出所有合法回路再拿材料给的五段代价去核对最优路线比死背答案扎实。2.3 谓词、产生式、框架、语义网络四种表示法的选择边界材料把知识表示分成谓词表示法、产生式表示法、框架表示法、语义网络表示法。考试里常问“什么场景选哪种表示”可以用一张表把边界定住表示法基本单元适合表达典型考题易错点谓词逻辑谓词、量词、连接词精确关系、定理证明、可归结的规则把自然语言转成谓词公式再化子句集量词辖域写错、Skolem 函数和常量混用产生式IF-THEN 规则、综合数据库、控制系统过程性知识、状态搜索、启发式规则旅行商、走迷宫、猴子摘香蕉规则缺约束导致重复访问或死循环框架槽、侧面、值结构化对象、默认值、场景描述描述一个房间、一台设备、一个事件槽和侧面的层级混淆语义网络节点、弧、关系标签概念关联、分类、隶属关系篮球赛比分、亲属关系、动物分类弧方向反了、关系标签缺失这张表不是让你背而是让你在答题时先判断“知识是过程性的还是结构性的”。有明确 IF-THEN 动作的产生式更自然有对象属性和默认值的框架更自然强调概念之间联系的语义网络更自然需要严格推理和归结的谓词逻辑更自然。材料里还提到谓词表示法要先定义谓词指出每个谓词的确切含义再用连接词把谓词连成公式产生式系统由规则库、综合数据库、控制系统三部分组成框架由槽组成槽有侧面侧面有值语义网络由节点和弧组成节点表示物体、概念或状态弧表示节点间关系。这些定义要能默写但更要能在具体题里选对。2.4 语义网络画法节点、弧、关系标签三要素材料里有一道题甲校和乙校两校篮球队在乙校进行一场比赛结局比分是 85:89用语义网络表示。画语义网络最容易犯的错是只画节点不写关系标签或者把弧的方向画反。稳妥画法是先列三元组再连弧主语关系宾语比赛 M参赛队甲校比赛 M参赛队乙校比赛 M得分8585所属队甲校比赛 M得分8989所属队乙校比赛 M比赛结果乙校胜这样节点和弧都有明确语义。如果题目只要求表达比分不要求判胜负最后一行可以省掉但前六行必须齐。考试时用方框表示节点、箭头表示弧、箭头旁边写关系名比只画两个圈连一条线更得分。材料里还提到语义网络常用于表示概念、物体、状态和它们之间的关系亲属关系题也会用到这一点在最后一章用 PROLOG 验证时还会碰到。3. 归结演绎推理从谓词公式到 ANSWER 谓词的完整手推链路3.1 子句集化的五步消蕴涵、移否定、标准化、Skolem 化、消全称归结演绎推理的第一步不是归结而是把谓词公式化成子句集。材料里的两道题都默认你已经会化子句集但考试时这恰恰是最容易丢分的地方。标准步骤是消去蕴涵和等价连接词把否定符号移到原子谓词前面对变量标准化让不同量词用不同变量名消去存在量词如果存在量词在全称量词辖域内用 Skolem 函数代替否则用 Skolem 常量代替最后消去全称量词用分配律把公式化成子句的合取每个子句写成文字的析取。这五步里最容易错的是第四步。比如(∀x)(∃y)Father(x,y)消去∃y时要用 Skolem 函数f(x)得到Father(x,f(x))不能写成Father(x,a)因为a是常量表达的是同一个人是所有 x 的父亲语义变了。如果存在量词不在任何全称量词辖域内比如(∃y)Father(y,Tom)才可以用 Skolem 常量a得到Father(a,Tom)。考试时把这两类分开写能避免大半错误。3.2 盗窃犯问题六条子句与两条 ANSWER 归结材料里的盗窃犯题是经典归结题。原题用四个姓氏这里为了书写方便换成甲、乙、丙、丁逻辑完全一样。五句话分别是甲与乙中至少有一人作案乙与丙中至少有一人作案丙与丁中至少有一人作案甲与丙中至少有一人与案无关乙与丁中至少有一人与案无关。设P(x)表示x作案五句话写成子句(1) P(甲) ∨ P(乙) (2) P(乙) ∨ P(丙) (3) P(丙) ∨ P(丁) (4) ¬P(甲) ∨ ¬P(丙) (5) ¬P(乙) ∨ ¬P(丁)待求解的问题是“谁是盗窃犯”设y是盗窃犯把P(y)否定后与ANSWER(y)做析取得到(6) ¬P(y) ∨ ANSWER(y)然后做归结。材料给出的归结步骤是(7) P(乙) ∨ ¬P(丙) (1)与(4)归结 (8) P(甲) ∨ ¬P(丁) (1)与(5)归结 (9) P(乙) ∨ ¬P(甲) (2)与(4)归结 (10) P(丙) ∨ ¬P(丁) (2)与(5)归结 (11) P(丙) ∨ ¬P(甲) (3)与(4)归结 (12) P(丙) ∨ ¬P(乙) (3)与(5)归结 (13) P(乙) (2)与(7)归结 (14) P(丙) (2)与(12)归结 (15) ANSWER(乙) (6)与(13)归结σ{乙/y} (16) ANSWER(丙) (6)与(14)归结σ{丙/y}最终得到ANSWER(乙)和ANSWER(丙)所以盗窃犯是乙和丙两个人。手推时每一步都要写清楚“哪两条子句归结”和“置换是什么”只写结果不写来源答卷上会被扣过程分。材料里还提醒每个侦察员的话都是一个子句待求解问题的否定与ANSWER做析取是为了让归结结果直接带出答案这个技巧要记住。3.3 兄弟与父亲一阶归结里的置换怎么写第二道题是任何兄弟都有同一个父亲甲和乙是兄弟且甲的父亲是丙问乙的父亲是谁。先定义谓词Father(x,y)表示x是y的父亲Brother(x,y)表示x和y是兄弟。已知事实写成F1: (∀x)(∀y)(∀z)(Brother(x,y) ∧ Father(z,x) → Father(z,y)) F2: Brother(甲,乙) F3: Father(丙,甲)化成子句集(1) ¬Brother(x,y) ∨ ¬Father(z,x) ∨ Father(z,y) (2) Brother(甲,乙) (3) Father(丙,甲)问题“乙的父亲是谁”写成Father(u,乙)否定后与ANSWER(u)析取(4) ¬Father(u,乙) ∨ ANSWER(u)归结过程(5) ¬Brother(甲,y) ∨ Father(丙,y) (1)与(3)归结σ{丙/z, 甲/x} (6) Father(丙,乙) (5)与(2)归结σ{乙/y} (7) ANSWER(丙) (4)与(6)归结σ{丙/u}所以乙的父亲是丙。这道题的关键是一阶归结的合一第 (5) 步用丙替换z、甲替换x第 (6) 步用乙替换y第 (7) 步用丙替换u。考试时把置换写在归结式右边格式清楚老师找得分点也快。3.4 用 Python 验证命题子句的归结闭包手推完之后可以用一段小程序验证命题部分的归结闭包检查自己有没有漏掉可归结的子句对。下面这段代码处理盗窃犯题的命题版本把候选答案逐个实例化然后做二元归结看哪个ANSWER能出现from itertools import combinations def neg(lit): 返回文字的反面P - ~P~P - P return lit[1:] if lit.startswith(~) else ~ lit def resolve(c1, c2): 对两个子句做一次二元归结找不到互补文字就返回 None for lit in c1: if neg(lit) in c2: new (c1 - {lit}) | (c2 - {neg(lit)}) # 如果新子句包含互补文字就是重言式直接丢掉 if any(neg(x) in new for x in new): return None return frozenset(new) return None base [ frozenset({P甲, P乙}), frozenset({P乙, P丙}), frozenset({P丙, P丁}), frozenset({~P甲, ~P丙}), frozenset({~P乙, ~P丁}), ] def closure(clauses, max_round10): 反复做二元归结直到没有新子句或达到轮数上限 clauses set(clauses) for _ in range(max_round): new set() for c1, c2 in combinations(clauses, 2): r resolve(c1, c2) if r is not None and r not in clauses: new.add(r) if not new: break clauses | new return clauses for person in [甲, 乙, 丙, 丁]: # 把 ANSWER(y) 实例化成具体人选再做命题归结 test base [frozenset({f~P{person}, fANSWER({person})})] result closure(test) hit any(fANSWER({person}) in c for c in result) print(person, 能推出 ANSWER:, hit)代码里resolve只做命题归结不涉及一阶合一closure反复组合子句最多跑 10 轮防止子句数量膨胀。base是五条前提子句test每次加入一条候选答案子句¬P(某人) ∨ ANSWER(某人)。运行后甲、丁输出False乙、丙输出True和手推结果一致。这个程序的价值是帮你检查归结闭包有没有漏不是替代手推过程考试写答卷时仍然要按“父子句编号 置换”的格式写。4. 代价树与与或树OPEN/CLOSED 表在纸上怎么推才不丢步骤分4.1 代价树广度优先按 g(n) 排序 OPEN 表代价树搜索是搜索策略里最容易“看懂但写不对”的部分。材料里的例题是五城市交通图A 是出发地E 是目的地边上的数字是交通费用求从 A 到 E 的最小费用路线。解题第一步是把交通图转换成代价树避免图中环路干扰。用g(x)表示从初始节点到节点x的代价c(x1,x2)表示从父节点到子节点的代价则g(x2)g(x1)c(x1,x2)。代价树广度优先搜索的规则是扩展节点n把它的子节点放入 OPEN 表计算各子节点代价并按代价从小到大对 OPEN 表全部节点排序每次从 OPEN 表取代价最小的节点扩展放入 CLOSED 表。材料里的推演结果是E为目标节点最优路径A-C-D-E。手推时 OPEN 表和 CLOSED 表要一步一步写不能只写最终路径。一个合格的答卷格式是步骤扩展节点OPEN 表按 g 排序CLOSED 表1AC1(5), B1(7)A2C1B1(7), D1(11)A, C13B1D1(11), ...A, C1, B14D1E1(19), ...A, C1, B1, D15E1......具体数字要以题面边权为准但格式就是这样每扩展一个节点就把它的子节点按g值插入 OPEN 表保持升序CLOSED 表记录已经扩展过的节点防止重复扩展。材料里还提醒代价树的深度优先搜索与广度优先搜索在某些图上结果相同但这只是巧合一般情况下两种方法结果不一定相同。4.2 代价树深度优先同一个图为什么可能得到非最优解代价树深度优先搜索的规则是扩展节点n把它的子节点按代价从小到大的顺序放到 OPEN 表的首部也就是用栈每次从栈顶取节点扩展。材料里特别指出虽然某个节点代价大于另一个节点但按照深度优先策略可能先扩展代价较大的那个因为栈是后进先出。材料中的结论是深度优先搜索有可能进入无穷分支因此是不完备的即使问题有解也不一定能求得解得到的解也不一定是最优解因为是局部优先搜索。这一点在答题时经常被忽略。题目如果问“代价树深度优先搜索得到的路径是否最优”不能只看路径长短要先判断搜索策略。深度优先只保证按当前栈顶一路走到底不保证全局最小。材料里有一道题明确说代价树深度优先搜索得到的路径A-B-D-E代价为 17不是最优解而广度优先得到A-C-E代价为 15。这个对比要记住同一个图换搜索策略结果可能不同。下面这段 Python 代码用一个小图演示两种策略的差别图是演示用的最小结构不是原题数据目的是看清 OPEN 表的行为import heapq # 演示用小图A 出发E 目标 edges { (A, B): 2, (A, C): 1, (B, D): 3, (C, D): 1, (D, E): 4, } def children(node): return [(b, w) for (a, b), w in edges.items() if a node] def bfs_cost(start, goal): 代价树广度优先OPEN 表按 g 升序 open_list [(0, start, [start])] closed set() while open_list: g, node, path heapq.heappop(open_list) if node in closed: continue closed.add(node) if node goal: return g, path for nxt, w in children(node): if nxt not in closed: heapq.heappush(open_list, (g w, nxt, path [nxt])) return None def dfs_cost(start, goal): 代价树深度优先子节点按代价升序压栈弹出栈顶 stack [(0, start, [start])] closed set() while stack: g, node, path stack.pop() if node in closed: continue closed.add(node) if node goal: return g, path # 按代价升序依次压栈代价大的最后入栈会先弹出 for nxt, w in sorted(children(node), keylambda x: x[1]): if nxt not in closed: stack.append((g w, nxt, path [nxt])) return None print(广度优先:, bfs_cost(A, E)) print(深度优先:, dfs_cost(A, E))bfs_cost用最小堆维护 OPEN 表每次取g最小的节点dfs_cost用栈子节点按代价升序压栈导致代价大的节点在栈顶先被扩展。运行后广度优先得到A-C-D-E代价 6深度优先得到A-B-D-E代价 9。这个结果说明深度优先不是按全局代价排序局部先走到底可能错过更便宜的路径。考试时如果题目要求“最优解”优先写广度优先或 A*写深度优先要注明“不一定最优”。4.3 与或树可解性与节点全可解、或节点一可解与或树是搜索策略里另一个高频考点。材料里的定义是一棵树中的弧线表示所连树枝为“与”关系不带弧线的树枝为“或”关系这棵树中既有与关系又有或关系因此称为与或树。可解节点的判定条件是终止节点是可解节点一个与节点可解当且仅当其子节点全都可解一个或节点可解只要其子节点至少有一个可解。解树是由可解节点形成的一棵子树根为初始节点叶为终止节点且这棵子树一定是与树。这三句话要能直接用在解题上。题目给一棵与或树问“用广度优先搜索求解释树”步骤是先扩展根节点得到子节点如果子节点里有终止节点标记为可解然后自底向上判断父节点是否可解与节点要等所有子节点都可解才标记可解或节点只要一个子节点可解就标记可解直到根节点可解解树就是由这些可解节点连成的子树。材料里有一道题先扩展 A 得到 B 和 C再扩展 B 得到 t1、t2t1、t2 可解所以 B 可解从而 A 可解深度优先则先扩展 C得到 D 和 t5再扩展 D 得到 t3、t4逐步标记可解。手推时把“可解”标记写在节点旁边比只在脑子里想清楚更不容易错。与或树的代价计算分两种和代价法和最大代价法。和代价法把子节点的代价相加再加上边代价最大代价法取子节点代价的最大值再加上边代价。材料里的例子是h(B)7, h(C)3按和代价法h(A)735621按最大代价法h(B)5, h(C)2h(A)5510。具体数字以题面为准但规则要记牢与节点用和代价或最大代价取决于题目要求或节点取子节点中代价最小的那个。答题时先写公式再代数别直接甩一个数字。4.4 α-β 剪枝α 是下界、β 是上界的检查表α-β 剪枝是博弈树搜索的重点。材料里的定义是对于一个与节点它取当前子节点中的最小倒推值作为倒推值的上界称为 β 值对于一个或节点它取当前子节点中的最大倒推值作为倒推值的下界称为 α 值。剪枝规律有两条任何或节点x的 α 值如果不能降低其父节点的 β 值则对节点x以下的分枝可停止搜索并使x的倒推值为 α这种剪枝称为 β 剪枝任何与节点x的 β 值如果不能升高其父节点的 α 值则对节点x以下的分枝可停止搜索并使x的倒推值为 β这种剪枝称为 α 剪枝。这两句话容易记反。一个实用的检查表是节点类型当前值剪枝条件剪枝名称或节点MAXαα ≥ 父节点的 ββ 剪枝与节点MINβ本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站