为了在Android中制作词汇练习应用程序,我想在Java中实现SuperMemo(SM-2)算法。这是间隔重复软件的一种流行选择,据我所知,Anki甚至采用了它。由于缺少代码格式,并且因为它是用Delphi编写的,因此(对我而言)这里给出的源代码示例很难(对我而言)。
SuperMemo的作者指出:
将知识分解为最小的项目。 与所有项目相关联的电子因子等于2.5。 使用以下间隔重复项:I(1):= 1 I(2):= 6 ,n> 2:I(n):= I(n-1)* EF 其中: I(n)-重复第n次重复之后的间隔(以天为单位), EF-给定项目的E因子。 如果间隔是小数,则将其四舍五入到最接近的整数。 每次重复后,以0-5级量表评估重复响应的质量:5-完美响应 4-犹豫后正确的响应 3-严重困难时召回的正确响应 2-错误的响应;正确的人似乎容易被回忆的地方 1-错误的回答;正确的记忆 0-完全停电。 每次重复之后,根据以下公式修改最近重复的项目的E因子: EF’:= EF +(0.1-(5-q)(0.08+(5-q) 0.02)) 其中:EF’- 新电子因子的 值,EF- 电子因子的旧值, q-0-5等级量表的响应质量。 如果EF小于1.3,则令EF为1.3。 如果质量响应低于3,则从头开始重复该项目,而无需更改电子因子(即使用间隔I(1),I(2)等,就好像该项目是新存储的一样)。 在给定日期的每个重复会话之后,再次重复质量评估中得分低于4的所有项目。继续重复直到所有这些项目得分都至少为4。
您如何用Java实现呢?
(我最近一直在研究这个问题,我想我已经找到了答案,所以我将其作为问答集提交,以帮助其他人做同样的事情。)
这里有一些条款,我们会处理impementing的时候用的SuperMemo(SM-2)算法的间隔重复。
0
1
n
5
1.3
2.5
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