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

基于遗忘曲线的智能刷题计划:间隔重复是效率的核心杠杆 基于遗忘曲线的智能刷题计划间隔重复是效率的核心杠杆一、刷 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 算法虽然简单但背后的思想——用数学方法量化「什么时候该复习」——是构建任何学习系统的基础。