SuperMemo(SM-2)的间隔重复算法

时间:2018-03-01 10:03:35

标签: java android algorithm

为了在Android中制作词汇练习应用程序,我想在Java中实现SuperMemo (SM-2) algorithm。这是间隔重复软件的流行选择,Anki甚至按照我的理解采用它。给定here的源代码示例很难(对我而言)因为缺少代码格式化而且因为它是用Delphi编写的。

SuperMemo的作者states

  
      
  1. 将知识分成尽可能小的项目。
  2.   
  3. 所有项目都将E-Factor关联为2.5。
  4.   
  5. 使用以下间隔重复项目:       I(1):= 1
          I(2):= 6
          对于n> 2:I(n):= I(n-1)* EF
          其中:
          I(n) - 第n次重复之后的重复间隔(以天为单位),
          EF - 给定项目的E因子
          如果interval是一个分数,则将其四舍五入到最接近的整数。
  6.   
  7. 每次重复后,评估0-5等级的重复反应质量:       5 - 完美的回应
          4 - 犹豫后的正确回答
          3 - 回答严重困难的正确答案
          2 - 不正确的回应;正确的一个似乎很容易回忆起来       1 - 不正确的回应;记得正确的人       0 - 完全停电。
  8.   
  9. 每次重复后,根据公式修改最近重复项目的E因子:
          EF':= EF +(0.1-(5-Q)*(0.08+(5-Q)* 0.02))
          其中:
          EF' - E因子的新值,
          EF - E因子的旧值,
          q - 0-5等级的响应质量       如果EF小于1.3,那么让EF为1.3。
  10.   
  11. 如果质量响应低于3,则从头开始重复项目而不更改E因子(即使用   间隔I(1),I(2)等,就像项目被重新记忆一样。)
  12.   
  13. 在给定日期的每次重复会话之后,再次重复质量评估中得分低于4的所有项目。继续   重复,直到所有这些项目得分至少为四。
  14.   

以下是Stack Overflow的一些相关(但不同)的问题:

如何在Java中实现它?

(我最近一直在研究这个问题,我想我有一个答案,所以我提交这个作为Q& A对来帮助其他人做同样的事情。)

1 个答案:

答案 0 :(得分:9)

SuperMemo算法

以下是我们在强制SuperMemo (SM-2) algorithmspaced repetition时要处理的一些术语。

  • 重复 - 这是用户看到闪卡的次数。 0表示他们尚未研究过,1表示这是他们的第一次,依此类推。在某些文档中,它也被称为n
  • 质量 - 也称为评估质量。这是闪存卡的难度(由用户定义)。比例从05
  • easyiness - 这也称为简易因子或EFactor或EF。它是用来增加空间的倍增器。间隔重复。范围从1.32.5
  • 间隔 - 这是重复之间的时间长度(以天为单位)。这是"空间"间隔重复。
  • nextPractice - 这是闪卡随后再次审核时的date/time

默认值

int repetitions = 0;
int interval = 1;
float easiness = 2.5;

代码

我发现this Python implementationSuperMemo example source code更容易理解,因此我或多或少地遵循这一点。

private void calculateSuperMemo2Algorithm(FlashCard card, int quality) {

    if (quality < 0 || quality > 5) {
        // throw error here or ensure elsewhere that quality is always within 0-5
    }

    // retrieve the stored values (default values if new cards)
    int repetitions = card.getRepetitions();
    float easiness = card.getEasinessFactor();
    int interval = card.getInterval();

    // easiness factor
    easiness = (float) Math.max(1.3, easiness + 0.1 - (5.0 - quality) * (0.08 + (5.0 - quality) * 0.02));

    // repetitions
    if (quality < 3) {
        repetitions = 0;
    } else {
        repetitions += 1;
    }

    // interval
    if (repetitions <= 1) {
        interval = 1;
    } else if (repetitions == 2) {
        interval = 6;
    } else {
        interval = Math.round(interval * easiness);
    }

    // next practice 
    int secondsInDay = 60 * 60 * 24;
    long now = System.currentTimeMillis();
    long nextPracticeDate = now + secondsInDay*interval;

    // Store the nextPracticeDate in the database
    // ...
}

备注

  • 上述代码未设置easiness的上限。它应该是2.5吗?文档和源代码似乎互相矛盾。
  • 如果质量评估小于3,文档也说得不容易更新容易因素,但这似乎与源代码相矛盾。在我看来,更新它更有意义(只要它保持在1.3以上)。无论如何,我每次都在更新它。
  • Anki源代码为here。不过,这是一个很大的项目,我还没有深入挖掘到他们的算法版本。
  • This post讨论了SM-2的一些问题以及解决这些问题的方法。