基于遗忘曲线的智能刷题计划:间隔重复是效率的核心杠杆

发布时间:2026/9/29 17:37:46

基于遗忘曲线的智能刷题计划:间隔重复是效率的核心杠杆
基于遗忘曲线的智能刷题计划间隔重复是效率的核心杠杆一、刷 100 道题不如把 20 道题刷三遍大多数刷题计划的逻辑是线性的按标签分类逐个攻克。数组刷完刷链表链表刷完刷树树刷完刷 DP。平均下来每道题只过一遍几天后基本忘光。这不是记忆差的问题是复习策略的问题。认知心理学的研究表明信息遗忘遵循指数衰减曲线但通过间隔重复Spaced Repetition可以在遗忘临界点介入大幅降低遗忘率。这篇文章讨论如何将遗忘曲线理论应用到刷题计划中实现智能化的复习调度。二、遗忘曲线与间隔重复graph LR subgraph 不复习的情况 A1[初次学习: 记忆强度 100%] --|1天后| B1[记忆强度 40%] B1 --|3天后| C1[记忆强度 20%] C1 --|7天后| D1[记忆强度 5%] end subgraph 间隔重复的情况 A2[初次学习] --|1天后复习| B2[记忆强度回升至 90%] B2 --|3天后复习| C2[记忆强度回升至 95%] C2 --|7天后复习| D2[记忆强度稳定在 98%] end艾宾浩斯遗忘曲线的核心发现是遗忘在学完后立即开始前期速度很快。每次复习都能减缓遗忘速度且复习间隔可以逐次拉长。在记忆即将遗忘时进行复习效果最好即「合意困难」。三、实现基于 SM-2 的智能调度器from dataclasses import dataclass from datetime import datetime, timedelta from typing import Optional import heapq dataclass class ProblemRecord: 单道题目的学习记录 problem_id: int problem_name: str tags: list[str] # SM-2 算法的核心参数 easiness_factor: float 2.5 # 难度因子越高 越容易 interval_days: int 0 # 当前复习间隔天 repetitions: int 0 # 连续正确次数 next_review_at: Optional[datetime] None # 下次复习时间 last_review_at: Optional[datetime] None # 上次复习时间 class SpacedRepetitionScheduler: 基于 SM-2 算法的复习调度器 SM-2 是 SuperMemo 第二版算法由 Piotr Wozniak 设计。 核心思想根据每次答题的质量0-5 分动态调整复习间隔。 # 答题质量对应的间隔倍数 # quality: 0完全忘记, 3正确但有困难, 5完美作答 QUALITY_MULTIPLIER { 0: 0.0, # 完全忘记 → 重置 1: 0.0, # 错误但正确答案看起来熟悉 2: 0.0, # 错误但记得曾经会做 3: 0.8, # 正确但很困难 4: 1.0, # 正确稍有犹豫 5: 1.2, # 完美作答 } def schedule_review( self, record: ProblemRecord, quality: int ) - ProblemRecord: 根据答题质量安排下次复习 Args: record: 当前题目的学习记录 quality: 答题质量评分 0-5 Returns: 更新后的学习记录 # 1. 更新难度因子 # EF EF (0.1 - (5-q) * (0.08 (5-q) * 0.02)) # 这个公式的意义低质量降低 EF高质量提升 EF old_ef record.easiness_factor record.easiness_factor max(1.3, old_ef ( 0.1 - (5 - quality) * (0.08 (5 - quality) * 0.02) )) # 2. 根据质量决定间隔 if quality 3: # 答题不理想重置学习进度 record.repetitions 0 record.interval_days 1 # 明天再来 else: # 答题通过增加间隔 if record.repetitions 0: record.interval_days 1 elif record.repetitions 1: record.interval_days 3 # 第 2 次正确后 3 天复习 else: # interval 上次 interval × easiness_factor record.interval_days int( record.interval_days * record.easiness_factor ) record.repetitions 1 # 3. 计算下次复习时间 now datetime.now() record.last_review_at now record.next_review_at now timedelta(daysrecord.interval_days) return record class ReviewQueue: 复习队列按紧急程度排序的优先队列 使用最小堆next_review_at 最早的排在堆顶。 def __init__(self): self._heap: list[tuple[float, int, ProblemRecord]] [] def push(self, record: ProblemRecord) - None: 加入复习队列 if record.next_review_at is None: return priority record.next_review_at.timestamp() # 使用 id 作为二级排序避免 ProblemRecord 不可比较的问题 heapq.heappush( self._heap, (priority, id(record), record), ) def pop_due(self) - list[ProblemRecord]: 弹出所有到期的复习任务 due [] now datetime.now().timestamp() while self._heap and self._heap[0][0] now: _, _, record heapq.heappop(self._heap) due.append(record) return due def get_daily_plan(self) - list[ProblemRecord]: 获取今日复习计划 return self.pop_due() # ---- 使用示例 ---- if __name__ __main__: scheduler SpacedRepetitionScheduler() queue ReviewQueue() # 学习 3 道题 problems [ ProblemRecord(problem_id1, problem_name两数之和, tags[数组, 哈希表]), ProblemRecord(problem_id2, problem_name反转链表, tags[链表]), ProblemRecord(problem_id3, problem_name爬楼梯, tags[DP]), ] # 模拟第一轮学习后的评价 qualities [4, 3, 5] # 分别是正确稍有犹豫、正确但困难、完美 for prob, q in zip(problems, qualities): updated scheduler.schedule_review(prob, q) queue.push(updated) print( f{prob.problem_name}: fEF{prob.easiness_factor:.1f}, f间隔{prob.interval_days}天, f下次复习{prob.next_review_at.strftime(%m-%d)} ) # 输出示例 # 两数之和: EF2.4, 间隔1天, 下次复习07-08 # 反转链表: EF2.4, 间隔1天, 下次复习07-08 # 爬楼梯: EF2.6, 间隔1天, 下次复习07-08 # 获取今日计划 today_plan queue.get_daily_plan() print(f\n今日复习: {len(today_plan)} 道题)四、边界与优化4.1 SM-2 的局限性SM-2 是 1987 年的算法设计时主要针对单词记忆。对于算法刷题需要额外考虑题目之间有依赖关系先掌握链表再学树的遍历更容易同类题目的迁移效应做会一道 DP 题可能让你对同类题更有信心4.2 冷启动问题新题目的初始难度因子默认为 2.5。如果题目对你来说特别简单或特别难前几次的调度会不准确。解决方案是根据题目的难度标签Easy/Medium/Hard预设初始 EF 值。4.3 计划容量控制如果每天的复习任务过多比如之前欠了很多题会导致「复习债」积压。需要有容量的上限控制——当每日计划超过合理数量时优先安排最紧急最接近遗忘临界点的题目。4.4 扩展动态难度调整将 SM-2 的 0-5 质量评分扩展为更细粒度的指标独立完成时间是否需要提示边界用例是否一次性通过这些指标的加权可以给出更准确的质量评分。五、总结刷题的效率不取决于总量取决于每道题在长期记忆中的留存率。基于遗忘曲线的调度系统核心价值在于在你即将忘记一道题之前精准地提醒你复习。SM-2 算法虽然简单但背后的思想——用数学方法量化「什么时候该复习」——是构建任何学习系统的基础。

相关新闻

如何高效使用pyodbc:企业级数据库连接终极指南

如何高效使用pyodbc:企业级数据库连接终极指南

2026/9/26 20:49:15

如何高效使用pyodbc:企业级数据库连接终极指南 【免费下载链接】pyodbc Python ODBC bridge 项目地址: https://gitcode.com/gh_mirrors/py/pyodbc 在当今数据驱动的商业环境中,企业级数据库连接已成为现代应用开发的核心需求。pyodbc作为一款强大…

STM32与CMT-8540S音频模块开发实战

STM32与CMT-8540S音频模块开发实战

2026/9/24 0:34:36

1. STM32F107VC与CMT-8540S-SMT的硬件组合解析在嵌入式音频开发领域,STM32F107VC微控制器与CMT-8540S-SMT音频模块的组合堪称黄金搭档。STM32F107VC基于ARM Cortex-M3内核,主频72MHz,内置256KB Flash和64KB SRAM,其丰富的外设接口…

【复现】面向新能源消纳能力评估的年负荷序列建模及场景生成方法(Matlab代码实现)

【复现】面向新能源消纳能力评估的年负荷序列建模及场景生成方法(Matlab代码实现)

2026/9/24 17:21:10

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/28 4:08:17

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/28 16:01:49

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/28 2:15:29

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/28 3:14:54

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/28 3:58:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/28 3:47:14

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/28 16:01:48

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/28 5:05:21

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/28 16:01:48

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…