为了在Android中制作词汇练习应用程序,我想在Java中实现SuperMemo (SM-2) algorithm。这是间隔重复软件的流行选择,Anki甚至按照我的理解采用它。给定here的源代码示例很难(对我而言)因为缺少代码格式化而且因为它是用Delphi编写的。
SuperMemo的作者states:
- 将知识分成尽可能小的项目。
- 所有项目都将E-Factor关联为2.5。
- 使用以下间隔重复项目: I(1):= 1
I(2):= 6
对于n> 2:I(n):= I(n-1)* EF
其中:
I(n) - 第n次重复之后的重复间隔(以天为单位),
EF - 给定项目的E因子
如果interval是一个分数,则将其四舍五入到最接近的整数。- 每次重复后,评估0-5等级的重复反应质量: 5 - 完美的回应
4 - 犹豫后的正确回答
3 - 回答严重困难的正确答案
2 - 不正确的回应;正确的一个似乎很容易回忆起来 1 - 不正确的回应;记得正确的人 0 - 完全停电。- 每次重复后,根据公式修改最近重复项目的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。- 如果质量响应低于3,则从头开始重复项目而不更改E因子(即使用 间隔I(1),I(2)等,就像项目被重新记忆一样。)
- 在给定日期的每次重复会话之后,再次重复质量评估中得分低于4的所有项目。继续 重复,直到所有这些项目得分至少为四。
醇>
以下是Stack Overflow的一些相关(但不同)的问题:
如何在Java中实现它?
(我最近一直在研究这个问题,我想我有一个答案,所以我提交这个作为Q& A对来帮助其他人做同样的事情。)
答案 0 :(得分:9)
以下是我们在强制SuperMemo (SM-2) algorithm的spaced repetition时要处理的一些术语。
0
表示他们尚未研究过,1
表示这是他们的第一次,依此类推。在某些文档中,它也被称为n
。0
到5
。1.3
到2.5
。int repetitions = 0;
int interval = 1;
float easiness = 2.5;
我发现this Python implementation比SuperMemo 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
// ...
}