小编典典

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

algorithm

为了在Android中制作词汇练习应用程序,我想在Java中实现SuperMemo(SM-2)算法。这是间隔重复软件的一种流行选择,据我所知,Anki甚至采用了它。由于缺少代码格式,并且因为它是用Delphi编写的,因此(对我而言)这里给出的源代码示例很难(对我而言)。

SuperMemo的作者指出

  1. 将知识分解为最小的项目。
  2. 与所有项目相关联的电子因子等于2.5。
  3. 使用以下间隔重复项:I(1):= 1
    I(2):= 6
    ,n> 2:I(n):= I(n-1)* EF
    其中:
    I(n)-重复第n次重复之后的间隔(以天为单位),
    EF-给定项目的E因子。
    如果间隔是小数,则将其四舍五入到最接近的整数。
  4. 每次重复后,以0-5级量表评估重复响应的质量:5-完美响应
    4-犹豫后正确的响应
    3-严重困难时召回的正确响应
    2-错误的响应;正确的人似乎容易被回忆的地方
    1-错误的回答;正确的记忆
    0-完全停电。
  5. 每次重复之后,根据以下公式修改最近重复的项目的E因子:
    EF’:= EF +(0.1-(5-q)(0.08+(5-q) 0.02))
    其中:EF’-
    新电子因子的
    值,EF- 电子因子的旧值,
    q-0-5等级量表的响应质量。
    如果EF小于1.3,则令EF为1.3。
  6. 如果质量响应低于3,则从头开始重复该项目,而无需更改电子因子(即使用间隔I(1),I(2)等,就好像该项目是新存储的一样)。
  7. 在给定日期的每个重复会话之后,再次重复质量评估中得分低于4的所有项目。继续重复直到所有这些项目得分都至少为4。

您如何用Java实现呢?

(我最近一直在研究这个问题,我想我已经找到了答案,所以我将其作为问答集提交,以帮助其他人做同样的事情。)


阅读 2078

收藏
2020-07-28

共1个答案

小编典典

SuperMemo算法

这里有一些条款,我们会处理impementing的时候用的SuperMemo(SM-2)算法间隔重复

  • 重复 -这是用户看到抽认卡的次数。0表示他们还没有研究过,1这是他们第一次学习,依此类推。n在某些文档中也将其称为。
  • 质量 -也称为评估质量。这是抽认卡(由用户定义)的难易程度。规模是从05
  • 易用性 -也称为易用性因子或EFactor或EF。它是用于增加间隔重复中“空间”的乘数。范围是从1.32.5
  • 时间间隔 -这是重复之间的时间长度(以天为单位)。它是间隔重复的“空间”。
  • nextPractice- 这是 抽认 卡再次审核的日期/时间。

默认值

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

我发现该Python实现SuperMemo示例源代码更容易遵循,所以我或多或少都遵循了。

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 millisecondsInDay = 60 * 60 * 24 * 1000;
    long now = System.currentTimeMillis();
    long nextPracticeDate = now + millisecondsInDay*interval;

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

笔记

  • 上面的代码未对设置上限easiness。应该是2.5吗?文档和源代码似乎相互矛盾。
  • 该文档还表明,如果质量评估小于3,则不应更新易用性因子,但这似乎与源代码相矛盾。在我看来,更新它(将其保持在1.3以上)更有意义。无论如何,我每次都在更新它。
  • Anki源代码在这里。不过,这是一个很大的项目,我还没有深入研究它的算法版本。
  • 这篇文章讨论了SM-2的一些问题以及这些问题的解决方案。
2020-07-28