Java中的Spaced Repetition算法的开源实现

时间:2011-09-30 10:25:50

标签: java algorithm

我在一个Spaced Repetition必不可少的项目上工作,但我不是这个主题的专家,我害怕重新发明方形轮。我的研究指出了两个不同的系统,即Leitner系统和SM系列算法 我还没有确定哪个系统最适合我的项目。如果我采用SM方向,我想我会尝试实现与what Anki uses类似的东西。

我最好的选择是使用现有的Java库。它可能很简单,我只需要计算下一次重复的时间 有没有人听说过这样的倡议?

3 个答案:

答案 0 :(得分:10)

我没有看过Anki的实现,但你看过这个吗? quiz-me an SRS in Java

基本上它就像这样

public static void calcuateInterval(Card card) {
  if (card.getEFactor() < 3) {
      card.setCount(1);
  }
  int count = card.getCount();
  int interval = 1;
  if (count == 2) {
      interval = 6;
  } else if (count > 2) {
     interval =  Math.round(card.getInterval() * card.getEFactor());
  }
  card.setInterval(interval);
}

如果您真的想要Anki的算法,请查看Anki in Android available in Github的来源。虽然这是GPL,但您可能需要购买许可证。

答案 1 :(得分:10)

我在我自己的闪卡应用程序中重新发明了方形轮。该算法非常简单:项目的权重是年龄组件进度组件工作组件的乘积。< / p>

年龄组件

公式为A(x)= Cn ^ x,其中

  • x是自项目上次测试以来的天数,
  • C是x为零时所需的值,
  • n是一个常数,基于x值增加时您希望值增加的速度。

例如,如果您希望该值每五天翻一番,则n = e ^(ln(2 / C)/ 5)。

进度组件

公式为P(x)= Cn ^ -x,其中

  • x是一个数字,对应于您对该项目的成功程度,
  • C是x为零时所需的值,
  • n是一个常数,基于x值增加时您希望值衰减的速度。

例如,如果您希望值连续五次成功减半,则n = e ^(ln(1/2)/ - 5)。

努力成分

这取两个值中的一个:

  • 10,如果您发现上一次召回该项目为&#34; hard&#34;或
  • 1否则。

因此调整进度:

  • 新条目以进度0开始。
  • 如果您轻松找到答案,则该项目的进度会增加1。
  • 如果你找到答案很难,那么项目的进度会转到min(int(previous / 2),previous - 1)。
  • 如果您的回答错误,该项目的进度将转至min(-1,previous - 1)。

是的,价值观可能会消极。 :)

应用程序通过从所有项目中随机选择来选择要测试的下一个项目,选择的概率直接随项目的权重而变化。

算法中的具体数字是可调整的。我已经使用现有的价值观大约一年,在积累和保留西班牙语,德语和拉丁语词汇方面取得了巨大的成功。

(抱歉马铃薯的数学表达质量。这里不允许使用LaTeX。)

答案 2 :(得分:6)

Anki使用SM2算法。但是,该文章所描述的SM2存在许多严重缺陷。幸运的是,它们很容易修复。

解释如何这样做对于这篇文章来说太长了,所以我写了一篇关于它的博客文章here。没有必要使用开源库来实现这一点,因为实际的实现非常简单。

相关问题