人工智能课后习题答案怎么用:从题型拆解到高分复习模板
简介:这是一份由清华大学出版社出版的《人工智能》教材配套课后习题答案Word文档,面向高校计算机、人工智能及相关专业学生,用于课后作业校验、考试复习与自学参考。文档包含全书各章节习题的详细解答,覆盖解图与规则顺序定义、启发函数在8数码问题中的应用、归结原理与合一算法、逻辑命题的归结证明、动物特征分类等经典知识点,能够帮助读者系统梳理状态空间搜索、自动定理证明、知识表示与推理等核心模块,尤其对搜索策略的选择和逻辑推理的步骤有清晰示范。资源以单个doc文件形式提供,包体大小约1009KB,排版清晰,可直接查看或打印使用,适合作为纸质教材之外的便携复习资料。目前已有59人浏览学习,适合正在学习人工智能导论或准备考研复试的读者。文档中对8数码问题的搜索过程、归结证明步骤等均给出了逐步推导,结合教材对照学习可有效查漏补缺。
1. 完整word版人工智能课后习题答案:为什么抄完还是会挂科
期末前两周,班群置顶消息永远是同一句:谁有完整word版人工智能课后习题答案,清华大学出版社那本的?这类文档我见过不下五个整理版本,文件名末尾的(1)大多是下载器自动追加的同名后缀,内容大同小异,核心是教材每章后的概念题与计算题答案。问题在于,对着答案抄一遍,合上文档,考试换两个数字照样手生。这篇笔记不打算复读文档里的题号,而是把课后题拆成题型、推导模板、翻车点和验证方法四块,覆盖《人工智能导论》期末考试和大作业里出现频率最高的搜索、知识表示、机器学习计算题。新手能按步骤练,复习过的人能拿来查漏。
2. 从「找答案」到「会做题」:课后题五类题型的识别方法与推导模板
2.1 状态空间搜索题:A*手算表格与Python核验脚本
搜索类题目是课后题的第一座山,常见问法有三种:画出搜索树、写出open表和closed表的变化过程、用A*求最优路径。手算的第一步永远是定义状态表示。八数码用一个3×3矩阵表示棋盘,传教士过河用(左岸传教士数, 左岸野人数, 船在哪一岸)这样的三元组表示,而图的路径搜索问题则退化成节点字符串。状态表示没写清楚,后面全部白算,这是阅卷时最冤枉的扣分点。
第二步列操作符。八数码是空格向四个方向移动,传教士问题是有哪些合法渡河组合,图搜索则是每条有向边本身。第三步才轮到算法主体:手算时我习惯画一张三列表格,分别是节点、g值、h值和f值,g值永远是从起点出发的累计代价,不是父节点到当前节点的单步边权。最后一步写路径和总代价,缺了路径只写f表,阅卷老师仍然会给一半分。
下面用一个五节点有向图走一遍完整手算。图结构是A→B代价1、A→C代价3、B→D代价1、C→D代价2、D→E代价2,目标节点E。启发函数取h(A)=3、h(B)=2、h(C)=3、h(D)=1、h(E)=0,这个h满足可采纳性条件h(n)≤h*(n),A*能保证返回最优解。初始open表为[A(0,3,f=3)],弹出A后扩展出B(1,2,f=3)和C(3,3,f=6),open表变成[(B,f=3),(C,f=6)]。弹出B扩展出D(2,1,f=3),open表为[(D,f=3),(C,f=6)]。弹出D扩展出E(4,0,f=4),open表为[(E,f=4),(C,f=6)]。弹出E即到达目标,最优路径A-B-D-E,总代价4。
import heapq def a_star(graph, start, goal, heuristic): # graph: 邻接表,每个节点形如 [(邻居, 代价), ...] # heuristic: 每个节点到目标节点的启发值 h(n) open_set = [(heuristic[start], start)] # 小顶堆元素为 (f, 节点),f = g + h g_score = {start: 0} # 起点到该节点的累计代价 came_from = {} # 记录父节点,用于回溯路径 while open_set: f, current = heapq.heappop(open_set) if current == goal: path = [current] while current in came_from: current = came_from[current] path.append(current) return path[::-1], g_score[goal] for nxt, cost in graph.get(current, []): tentative = g_score[current] + cost # 走这条边的临时 g 值 if tentative < g_score.get(nxt, float('inf')): g_score[nxt] = tentative came_from[nxt] = current heapq.heappush(open_set, (tentative + heuristic.get(nxt, 0), nxt)) return None, -1 graph = { 'A': [('B', 1), ('C', 3)], 'B': [('D', 1)], 'C': [('D', 2)], 'D': [('E', 2)], } heuristic = {'A': 3, 'B': 2, 'C': 3, 'D': 1, 'E': 0} path, cost = a_star(graph, 'A', 'E', heuristic) print("最优路径:", path, "总代价:", cost)这段代码的逻辑核心是heapq小顶堆永远弹出当前f最小的节点,g_score字典记录已确认的最小代价,tentative和旧值比较那一步防止重复扩展。参数需要注意两点:一是边权不等时把neighbor的cost换成真实值,二是启发函数必须满足可采纳性,否则A*会退化成可能丢最优解的算法。手算和脚本结果对照时,重点看open表弹出顺序是否一致,不一致往往意味着g值累计错了。
2.2 知识表示题:产生式、框架、语义网络的三种落笔模板
知识表示题的特征很直白,题目给一段常识性描述,要求用指定表示方法写出来。选型原则先记住:产生式系统适合「如果……那么……」的规则型知识,比如医疗诊断规则、动物识别规则;框架表示适合具有类层级和默认值的对象知识,比如学生信息、课程信息;语义网络适合强调关系和属性的知识,比如「鸟会飞」「麻雀是鸟」。选错表示方法,即使内容对也要扣分。
产生式系统的标准落笔顺序是:先写规则库,每条规则写成「规则名:IF 前提 THEN 结论」,再写综合数据库(事实集合),最后写控制策略。控制策略是多数人丢分的地方,题目如果没指定,至少要说明采用正向推理还是反向推理,以及冲突消解策略,比如按规则次序优先。
框架表示则要按三层结构写:框架名、槽、侧面。以学生信息为例,框架名是「学生」,槽有「姓名」「学号」「专业」,每个槽下可以挂「值」「默认值」「限制」这些侧面。语义网络题除了画节点和带标签的有向弧,还要在答案里补一句文字说明,把图里的三元组关系翻译成句子,很多老师按这一句给采分点。
2.3 机器学习计算题:决策树信息增益和朴素贝叶斯的推导模板
机器学习计算题集中在决策树和朴素贝叶斯两类。决策树的核心是信息增益计算,先说手算步骤:第一步统计标签分布并计算数据集总熵,第二步对候选特征的每个取值划分数据子集、计算条件熵,第三步用总熵减条件熵得到信息增益,增益最大的特征优先分裂。我见过大量答案在第二步忘记乘子集占比的权重,导致条件熵偏小、增益虚高,排序直接出错。
用一个五行小数据集演示。数据是「天气」和「温度」两个特征,标签是「是否出去玩」:晴-高-否,晴-低-是,阴-高-是,雨-高-否,雨-低-是。总熵为-3/5·log₂(3/5)-2/5·log₂(2/5)≈0.971。按天气划分,晴子集是「否,是」熵为1,阴子集「是」熵为0,雨子集「否,是」熵为1,加权条件熵为2/5×1+1/5×0+2/5×1=0.8,信息增益约0.171。按温度划分,高子集是「否,是,否」熵为0.918,低子集「是,是」熵为0,加权条件熵为3/5×0.918≈0.551,增益约0.420。温度增益更大,所以第一层按温度分裂。
import math from collections import Counter def entropy(labels): """计算熵,labels 是标签列表,如 ['否','是','否']""" total = len(labels) if total == 0: return 0.0 counts = Counter(labels) return -sum((c / total) * math.log2(c / total) for c in counts.values()) def info_gain(data, feature_idx): """data 每行是 [特征1, 特征2, ..., 标签],feature_idx 是特征列下标""" base = entropy([row[-1] for row in data]) values = set(row[feature_idx] for row in data) weighted = 0.0 for v in values: subset = [row for row in data if row[feature_idx] == v] weighted += len(subset) / len(data) * entropy([row[-1] for row in subset]) return base - weighted data = [ ['晴', '高', '否'], ['晴', '低', '是'], ['阴', '高', '是'], ['雨', '高', '否'], ['雨', '低', '是'], ] print("天气的信息增益:", round(info_gain(data, 0), 4)) print("温度的信息增益:", round(info_gain(data, 1), 4))这段代码的输出结果分别是0.171和0.4199,和手算一致。逻辑上base熵先算一次,然后按特征取值划分子集,weighted变量累加各子集占比乘以子集熵。参数说明里最值得强调的是feature_idx,不同教材数据集的特征列位置不一样,核对时先确认传入的是第几列。朴素贝叶斯题则套贝叶斯公式P(类别|特征)=P(特征|类别)P(类别)/P(特征),沿用上面数据算P(是|晴)=(1/3×3/5)/(2/5)=0.5,零概率时记得加一平滑,这也是常被忽略的采分点。
3. 按章节过《人工智能导论》:搜索、推理、神经网络的采分点与答题范式
3.1 搜索策略章节:DFS、BFS、A*的对比表与阅卷采分点
搜索策略是教材前半部分的重头戏,也是课后题计算量最大的章节。复习时先背熟三种算法的对比关系,这是选择题和分析题的直接题源。
| 算法 | 是否完备 | 是否最优 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|---|
| DFS | 图搜索下不完备 | 否 | O(b^m) | O(b·m) |
| BFS | 状态空间有限时完备 | 是(每条边代价相同时) | O(b^d) | O(b^d) |
| A* | 完备 | 是(h可采纳时) | 取决于h质量 | 最坏O(b^d) |
其中b是分支因子,m是搜索树最大深度,d是最优解所在深度。阅卷时的大题采分点集中在四个位置:状态表示是否规范、操作符是否完整覆盖所有合法动作、open表和closed表是否按算法规则变化、最终是否明确写出路径和代价。我见过不少答卷把搜索树画对了但没写open表,直接扣掉一半分,因为open表是评判算法执行过程是否规范的核心证据,只画树无法证明你走的不是贪心路径。
答题顺序建议固定成五步:写状态表示、写初始和目标状态、写操作符、列open/closed表、输出路径。最后一步的路径要和第四步的弹出顺序一致,否则老师会认定前后矛盾。复习时手算一道八数码题,再对照第2章的Python脚本核验弹出顺序,基本就能覆盖这个章节90%的考点。
3.2 知识表示与不确定性推理:可信度方法计算模板
不确定性推理是期末大题的另一个常驻考点,其中可信度方法最常考。核心公式是两条规则的合成:CF(H)=CF₁+CF₂−CF₁·CF₂(两个正可信度合成),同号规则合成后可信度大于其中任意一个,这个直觉反过来也提醒你,异号的时候要转成差分公式。答题模板固定为三步:先列出每条规则的可信度,再判断合成方向,最后套公式算结果并说明可信度的含义。
主观贝叶斯方法则主要考P(H|E)=P(E|H)P(H)/P(E)的代入计算,注意区分P(E|H)和P(H|E)哪个是题目直接给的,哪个要推导。这一章的得分点很实在:公式写对就给一半分,代入数值错一个只扣代入分。所以复习时反而要刻意背公式而不要太纠结数值精度,很多人翻车不是因为算错,而是因为把CF合成公式和贝叶斯公式的位置记混了。
知识表示部分则要和第2章的三种模板结合训练。框架题常考「用框架表示一个具体对象」,语义网络题常考「把一段话转成网络结构」,产生式题常考「规则库整理与冲突消解」。三种题型用同一套落笔逻辑:先审题明确要求的表示方法,再抽取实体和关系,最后按标准格式组织,这一步在考场上是拿分效率最高的操作。
3.3 机器学习与神经网络章节:感知机迭代和BP反向传播的落笔顺序
凡是用到公式的章节,答题顺序可以直接决定得分率。感知机题给一组样本和初始权重,要求迭代若干轮。标准落笔是:写更新公式wᵢ←wᵢ+η(t−y)xᵢ,初始化权重和阈值,然后每轮每样本依次计算输出、判断是否更新、记录更新后的权重向量。用OR逻辑门验证:样本(0,0)→0、(0,1)→1、(1,0)→1、(1,1)→1,初始权重[0,0],学习率0.1。第一轮(0,1)时输出0而期望1,权重更新为[0,0.1];轮到(1,0)时更新为[0.1,0.1];第二轮所有样本都正确分类,迭代结束。
BP反向传播的手算题则固定四步:前向计算各层输出、计算输出层误差项、误差反向传播到隐层、更新全部权重。记忆口诀是「误差从输出端往回流,谁接收了谁的贡献谁承担误差」。输出层误差项和隐层误差项的下标不要混,输出层用期望值减实际输出,隐层用输出层误差的加权和乘隐层激活函数导数。神经网络题目的给分点通常是公式是否正确、误差项方向是否合理、权重更新是否朝向损失下降的方向,数值算到最后对不上,只要推导链完整也能拿过程分。
4. 对答案时常见问题排查:五个翻车点的现象、原因、解决
4.1 翻车点一:A*手算时丢g列,f=h退化成贪心
现象:自己的open表弹出顺序和标准答案差很远,最后得到的路径明显绕路,却被自己标成最优。原因:手算只在节点旁边写了h值,没有单独列g值,把f=h当作启发式优先,这本质上是贪婪最佳优先搜索,不是A*。另一个常见原因是把g算成父节点到当前节点的单步边权,而不是从起点累计的代价。解决:手算一律用「节点、g、h、f」四列表格,每扩展一个节点先把g值累计完整再算f。对照第2章的脚本跑一遍,如果脚本输出的路径和手算一致,说明表格没列错。
4.2 翻车点二:信息增益的对数底数在ln和log2之间反复横跳
现象:决策树信息增益算出来和答案差一个固定比例,有时特征排序恰好没变,有时排序直接错了。原因:熵的定义是−Σp·log₂p,计算器默认的ln键按顺手了,或者python里用了math.log()而不是math.log2()。解决:统一用底数2,所有中间计算保持同一底数。写答案时把熵的计算过程展开写清楚,老师按步骤给分,即使最终数值有偏差也能看出方法正确。用第2章的info_gain函数把数据丢进去跑一遍,数值对不上时逐项检查每个子集的占比权重。
4.3 翻车点三:归结反演时把存在量词直接删掉
现象:谓词逻辑归结题做了两页纸,始终归不出空子句,翻答案发现对方引入了一个函数符号。原因:消去存在量词需要Skolem化,但很多人习惯直接把∃x去掉,忽略了前面是否有全称量词约束。规则是:若存在量词前面没有任何全称量词,用一个新的常数替换该变量;若存在量词位于某个全称量词辖域内,则必须用Skolem函数替换,函数参数就是那个全称量词约束的变量。解决:拿到谓词公式先写前束范式,把量词全部提到最前面,再按顺序判断每个存在量词应该引入常数还是函数。这个细节通常是归结题的分水岭,函数符号出现的那一刻就说明题做对了。
4.4 翻车点四:BP反向传播误差项符号反了,权重越改越错
现象:手算BP时每一轮权重更新方向和标准答案恰好相反,误差不仅没降反而变大。原因:损失函数取E=1/2(t−y)²时,对权重求导会产生负号,推导结果是w:=w+η·(t−y)·φ′(net)·x。很多人把更新式记成w:=w−η·(t−y)·φ′(net)·x,符号一反,权重朝损失上升的方向走。解决:先固定损失函数形式再推导符号,不要跨教材混用。写成统一约定:δ_out=(t−y)·φ′(net_out),隐层误差δ_h=φ′(net_h)·Σ(w_k·δ_k),权重更新一律是w:=w+η·δ·输入。拿单个神经元先用第5章的验证脚本算一遍,符号对了再上多层手算。
4.5 翻车点五:把答案文档当学习大纲,背完还是不会迁移
现象:文档翻得很熟,甚至能把某些大题的答案复述出来,但考试换了两组数据、换了个场景就完全动不了笔。原因:课后习题答案文档是「结果快照」,不是「推导过程」,它按教材题号排列,没有给你标注各章节的重难点权重和题型归纳。而且清华大学出版社的人工智能教材有多个版次,章节顺序和题号经常对不上,照着旧版题号找新版内容是常态。解决:先用第3章的考点清单过一遍教材目录,把每章高频题型标注出来,再针对薄弱题型去答案文档里看对应题号的具体推导步骤,最后用代码或自测验证,让文档从背诵材料变成核对工具。
5. 把答案文档变成验证工具:三天突击方案和脚本自查法
5.1 三天突击方案:按题型分配时间
如果离考试只剩三天,别再从头背答案文档了,按下面这个节奏走。第一天集中攻克搜索题和知识表示题,上午手算两道A*,下午把第2章的脚本跑起来核验open表顺序,晚上背产生式和框架的答题模板。第二天主攻机器学习计算题,上午算决策树信息增益和朴素贝叶斯,下午训练感知机和手推一轮BP,晚上用脚本把当天手算结果全部重算一遍。第三天收尾不确定性推理和论述题,上午练可信度合成,下午做一套包含选择、计算、简答的模拟自测,晚上只查错题对应的题型模板,不再重抄整篇答案。
论述题也有固定模板:先给定义,再写方法或分类,然后说优缺点,最后补一个应用场景。字数控制在两三百字,定义占三成、方法占四成、优缺点和应用占三成,这个比例最稳妥。这套突击方案本身也就是一条被验证过的人工智能学习路径,从题型到模板再到验证,比盯着答案文档啃要高效得多。
5.2 手算验证脚本:五分钟写一个答案自检程序
无论突击还是长线复习,我强烈建议保留一个小习惯:手算完后,花五分钟写一段几十行的脚本核对答案。下面这段通用的路径代价核对函数,适用于所有图搜索题,把你手算的路径填进去,边权对不对立刻见分晓。
def check_path_cost(graph, path): """核对 A* 手算路径的实际代价:依次累加路径上每条边的权""" total = 0 for i in range(len(path) - 1): for nxt, cost in graph[path[i]]: if nxt == path[i + 1]: total += cost break else: raise ValueError(f"路径 {path[i]} -> {path[i+1]} 不存在") return total graph = { 'A': [('B', 1), ('C', 3)], 'B': [('D', 1)], 'C': [('D', 2)], 'D': [('E', 2)], } print(check_path_cost(graph, ['A', 'B', 'D', 'E'])) # 期望输出 4核验逻辑很简单:从第一个节点开始,挨个在当前节点的邻居里找下一个节点,找到就累加代价,找不到就报错。这套做法的价值不在脚本本身,而在于强迫你把算法从「纸面推演」变成「可执行逻辑」,动手写一遍比背十遍公式都管用。笔试之外的技能考核也一样能迁移,比如人工智能训练师这类职业认证里的计算分析题,核验思路完全相同。带课这些年我见过太多学生卡在计算题上,最值钱的一条血泪经验就是:手算决定你懂不懂,脚本决定你对不对,两个都做了,计算题基本没有失分空间。这份答案文档谁都找得到,但能不能把文档里的死答案变成自己能推出来的活方法,靠的就是这个循环——识别题型、套模板、踩过坑、再验证。希望帮到你。
本文还有配套的精品资源,点击获取