Java中的Spaced重复算法的开源实现
我在一个Spaced Repetition必不可少的项目上工作,但是我不是这个主题的专家,我害怕重新发明方形轮。 我的研究指出了两个不同的系统,即Leitner系统和SM系列算法。
我还没有确定哪个系统最适合我的项目。 如果我要采用SM方向,我想我会尝试实现类似于Anki使用的东西。
我最好的选择是使用现有的Java库。 它可能非常简单,我只需要计算下一次重复的时间。
有没有人听说过这样的倡议?
我没有看过Anki的实现,但你看过这个吗? 测验我是Java的SRS 。
基本上就是这样的
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的算法,请查看Github中提供的Anki in Android的来源。 虽然它是GPL,但您可能需要购买许可证。
我在我自己的闪卡应用程序中重新制作了方形轮。 该算法非常简单:项目的权重是年龄组件 , 进度组件和工作组件的乘积。
年龄成分
公式为A(x)= Cn ^ x,其中
- x是自项目上次测试以来的天数,
- 当x为零时,C是你想要的值,和
- n是一个常数,基于x值增加时希望值增加的速度。
例如,如果您希望值每五天加倍一次,则n = e ^(ln(2 / C)/ 5)。
进度组件
公式为P(x)= Cn ^ -x,其中
- x是一个数字,对应于您对该项目的成功程度,
- 当x为零时,C是你想要的值,和
- n是一个常数,基于x值增加时您希望值衰减的速度。
例如,如果您希望每五次连续成功减半,则n = e ^(ln(1/2)/ – 5)。
努力组件
这取两个值之一:
- 10,如果你发现你最后一次回忆该项目是“硬”,或者
- 否则为1。
因此调整进度:
- 新条目以进度0开头。
- 如果您轻松找到答案,则项目的进度会增加1。
- 如果你找到答案很难,那么项目的进度将转到min(int(previous / 2),previous – 1)。
- 如果你的答案有问题,那么项目的进度将转到min(-1,previous – 1)。
是的,价值观可能会消极。 🙂
应用程序通过从所有项目中随机选择来选择要测试的下一个项目,选择的概率直接随项目的权重而变化。
算法中的具体数字是可调整的。 我一直使用现有的价值观大约一年,在积累和保留西class牙语,德语和拉丁语词汇方面取得了巨大成功。
(对不起马铃薯质量的数学表达式。这里不允许使用LaTeX。)
Anki使用SM2算法。 但是,该文章所描述的SM2存在许多严重缺陷。 幸运的是,它们很容易修复。
解释如何这样做对于这篇文章来说太长了,所以我在这里写了一篇关于它的博客文章。 没有必要使用开源库来实现这一点,因为实际的实现非常简单。