8.4 KiB
8.4 KiB
複習算法簡化說明
🎯 核心問題
當前的 下次複習時間 = 2^成功複習次數 增長太快,只需9次就達到365天。
📐 新算法設計(簡化版)
基本公式
新間隔 = 舊間隔 × 增長係數 × 表現係數
1. 增長係數表
根據當前間隔決定增長速度:
| 當前間隔範圍 | 增長係數 | 說明 |
|---|---|---|
| 1-7天 | 1.8 | 初期較快增長 |
| 8-30天 | 1.4 | 中期穩定增長 |
| 31-90天 | 1.2 | 後期緩慢增長 |
| 91天以上 | 1.1 | 維持長期記憶 |
2. 表現係數表
翻卡題(用戶自評)
| 用戶選擇 | 係數 | 說明 |
|---|---|---|
| 完全不記得 | 0.5 | 大幅縮短間隔 |
| 有印象但不確定 | 0.7 | 稍微縮短 |
| 記得但需思考 | 1.0 | 維持原間隔 |
| 清楚記得 | 1.2 | 稍微延長 |
| 非常熟悉 | 1.4 | 明顯延長 |
客觀題(對錯判斷)
| 結果 | 反應時間 | 係數 | 說明 |
|---|---|---|---|
| 答對 | < 3秒 | 1.2 | 很熟悉 |
| 答對 | 3-8秒 | 1.1 | 正常 |
| 答對 | > 8秒 | 1.0 | 緩慢 |
| 答錯 | 任何 | 0.6 | 需練習 |
🆕 初始間隔設計
新增詞卡的預設值
當用戶新增詞卡時,系統自動設定:
- IntervalDays: 1天(資料庫預設值)
- NextReviewDate: 今天(立即可復習)
- Repetitions: 0(尚未復習)
第一次復習的間隔計算
當用戶第一次復習新詞卡時,使用相同的公式:
| 表現 | 計算過程 | 結果 |
|---|---|---|
| 答對 | 1天 × 1.8 × 1.1 = 1.98天 | 2天後復習 |
| 答錯 | 1天 × 1.8 × 0.6 = 1.08天 | 1天後復習 |
為什麼初始間隔是1天?
- 符合直覺: 新學的詞彙需要快速復習
- 避免遺忘: 短間隔確保新記憶得到鞏固
- 資料庫一致: 與現有的
IntervalDays = 1預設值保持一致
🔢 實際計算範例
範例:詞彙 "sophisticated" 的完整學習歷程
| 階段 | 當前間隔 | 表現 | 增長係數 | 表現係數 | 計算過程 | 新間隔 | 說明 |
|---|---|---|---|---|---|---|---|
| 新增 | - | - | - | - | - | 1天 | 系統預設初始間隔 |
| 第1次 | 1天 | 答對(正常) | 1.8 | 1.1 | 1×1.8×1.1 | 2天 | 第一次復習成功 |
| 第2次 | 2天 | 答對(快速) | 1.8 | 1.2 | 2×1.8×1.2 | 4天 | 反應快速,獎勵 |
| 第3次 | 4天 | 答錯 | 1.8 | 0.6 | 4×1.8×0.6 | 4天 | 答錯,間隔未增加 |
| 第4次 | 4天 | 答對(正常) | 1.8 | 1.1 | 4×1.8×1.1 | 8天 | 重新開始增長 |
| 第5次 | 8天 | 答對(正常) | 1.4 | 1.1 | 8×1.4×1.1 | 12天 | 進入中期階段 |
| 第6次 | 12天 | 答對(快速) | 1.4 | 1.2 | 12×1.4×1.2 | 20天 | 反應快速,獎勵 |
| 第7次 | 20天 | 答對(正常) | 1.4 | 1.1 | 20×1.4×1.1 | 31天 | 穩定增長 |
| 第8次 | 31天 | 答對(正常) | 1.2 | 1.1 | 31×1.2×1.1 | 41天 | 進入後期階段 |
| 第9次 | 41天 | 答對(正常) | 1.2 | 1.1 | 41×1.2×1.1 | 54天 | 緩慢增長 |
| 第10次 | 54天 | 答對(正常) | 1.2 | 1.1 | 54×1.2×1.1 | 71天 | 長期記憶階段 |
📊 算法對比圖表
時間增長對比
天數
400 |
| ●─── 現有算法 (2^n)
300 | ╱
| ╱
200 |╱
|
100 | ╭──●──●──●─── 新算法 (漸進式)
| ╱
50 |╱
|
0 +────────────────────→
1 3 5 7 9 復習次數
現有算法: 1→2→4→8→16→32→64→128→256天
新算法: 1→2→4→8→12→20→31→41→54天
🎯 關鍵優勢
1. 更合理的學習曲線
- 現有: 9次復習就達到256天
- 新版: 10次復習才71天,需要更多次數達到長間隔
2. 錯誤恢復機制
- 現有: 錯誤後直接 ×0.6,可能重置太多進度
- 新版: 錯誤後根據當前階段調整,避免過度懲罰
3. 階段性增長
- 初期: 快速建立基礎記憶
- 中期: 穩定鞏固
- 後期: 維持長期記憶
🛠️ 實作的 C# 代碼
public class SpacedRepetitionService
{
/// <summary>
/// 計算下次復習間隔
/// </summary>
/// <param name="flashcard">詞卡實體(包含 IntervalDays 等欄位)</param>
/// <param name="isCorrect">是否答對</param>
/// <param name="confidenceLevel">信心程度(1-5,僅翻卡題使用)</param>
/// <returns>新的間隔天數</returns>
public int CalculateNextInterval(Flashcard flashcard, bool isCorrect, double? confidenceLevel = null)
{
// 1. 取得當前間隔(新詞卡預設為1天)
int currentInterval = flashcard.IntervalDays; // 資料庫欄位,預設值 = 1
// 2. 決定增長係數(根據當前間隔階段)
double growthFactor = currentInterval switch
{
<= 7 => 1.8, // 初期階段(包含第一次復習)
<= 30 => 1.4, // 中期階段
<= 90 => 1.2, // 後期階段
_ => 1.1 // 維持期
};
// 3. 決定表現係數
double performanceFactor;
if (confidenceLevel.HasValue) // 翻卡題(主觀評估)
{
performanceFactor = confidenceLevel.Value switch
{
1 => 0.5, // 完全不記得
2 => 0.7, // 有印象但不確定
3 => 1.0, // 記得但需思考
4 => 1.2, // 清楚記得
5 => 1.4, // 非常熟悉
_ => 1.0
};
}
else // 客觀題(對錯判斷)
{
performanceFactor = isCorrect ? 1.1 : 0.6;
}
// 4. 計算新間隔
double newInterval = currentInterval * growthFactor * performanceFactor;
// 5. 限制範圍並四捨五入
int result = Math.Max(1, Math.Min(365, (int)Math.Round(newInterval)));
return result;
}
/// <summary>
/// 更新詞卡的復習資訊
/// </summary>
public void UpdateFlashcardAfterReview(Flashcard flashcard, int newInterval, bool isCorrect)
{
// 更新間隔天數
flashcard.IntervalDays = newInterval;
// 更新下次復習日期
flashcard.NextReviewDate = DateTime.Today.AddDays(newInterval);
// 更新統計資料
flashcard.TimesReviewed++;
if (isCorrect)
{
flashcard.TimesCorrect++;
}
// 更新熟悉程度(簡化版)
flashcard.MasteryLevel = Math.Min(100,
(flashcard.TimesCorrect * 10) + (newInterval * 365 / 100));
}
}
與現有資料庫的整合
// 在 FlashcardsController 中的使用範例
[HttpPost("{id}/review")]
public async Task<IActionResult> ReviewFlashcard(Guid id, ReviewRequest request)
{
var flashcard = await _context.Flashcards.FindAsync(id);
if (flashcard == null) return NotFound();
// 使用新算法計算間隔
var spacedRepetition = new SpacedRepetitionService();
int newInterval = spacedRepetition.CalculateNextInterval(
flashcard,
request.IsCorrect,
request.ConfidenceLevel
);
// 更新詞卡資訊
spacedRepetition.UpdateFlashcardAfterReview(flashcard, newInterval, request.IsCorrect);
await _context.SaveChangesAsync();
return Ok(new {
newInterval,
nextReviewDate = flashcard.NextReviewDate,
masteryLevel = flashcard.MasteryLevel
});
}
🤔 為什麼這樣設計?
階段性增長的科學依據
- 初期 (1.8倍): 新記憶需要頻繁鞏固
- 中期 (1.4倍): 記憶開始穩定,可適度延長
- 後期 (1.2倍): 長期記憶,緩慢增長避免遺忘
- 維持期 (1.1倍): 微調保持長期記憶
表現係數的心理學依據
- 主觀評估: 反映學習者真實感受,5個等級提供細緻調整
- 客觀測試: 簡單的對錯判斷,避免過度複雜化
- 快速獎勵: 快速正確答題獲得額外係數獎勵
這個算法的核心思想:根據當前學習階段和表現,智能調整復習頻率,既避免遺忘,也不浪費時間。