间隔重复记忆之SM-2

最近读了一篇彼得·沃兹尼亚克博士(Dr Piotr Wozniak)写的文章,介绍间隔重复记忆法的历史,文章地址:The true history of spaced repetition。我还没有读完,读到了Algorithm SM-2。

SM-2算法

SM-2是间隔重复记忆的第一代算法,目前还有很多软件在使用,内容如下:

  1. 将知识点拆分成最小单元。

  2. 将每个知识点分配一个E-Factor,初始值2.5。

  3. 使用以下公式重复记忆知识点:

    I(1):=1

    I(2):=6

    for n>2: I(n):=I(n-1)*EF

    其中:

    I(n) 代表第n次重复记忆时的间隔

    EF 代表每个知识点关联的E-Factor。

    如果计算出来的间隔时间是小数,四舍五入取整。

  4. 每次重复一个知识点后,给出一个记忆质量值,取值范围在0-5:

    • 5 - 知识点完全记住。
    • 4 - 能回忆起来,略有迟疑。
    • 3 - 能回忆起来,但是有难度。
    • 2 - 回忆错误,但是正确答案好像很容易能记起来。
    • 1 - 回忆错误,但是正确答案记住了。
    • 0 - 回忆不起来。
  5. 每次重复一个知识点后,更新其关联的E-Factor值,新的E-Factor计算公式如下:

    EF’:=EF+(0.1-(5-q)*(0.08+(5-q)*0.02))

    其中:

    EF’ 代表新的E-Factor值。

    EF 代表就得E-Factor值。

    q 代表步骤4中给出的记忆质量值。

    如果EF’ 值小于1.3,则EF’=1.3

  6. 如果第4步中的记忆质量值小于3,则该知识点按新知识重新计算间隔记忆。

  7. 每一天的重复记忆中记忆质量小于4的知识点需要再次重复,直到记忆质量大于等于4再结束当天的重复记忆过程。

TypeScript实现

export interface SM2Item {interval?: number,count?: number,efactor?: number,quality: number,
}export interface SM2Result {item: SM2Item,needRepeat: boolean,
}/*** Calculates the E-factor of a given quality.** @param {number} efactor - The E-factor to calculate.* @param {number} quality - The quality to use in the calculation.* @return {number} The calculated E-factor.*/
function calculateEFactor(efactor: number, quality: number): number {let nextEFactor = efactor + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02));if (nextEFactor > 2.5) return 2.5;else if (nextEFactor < 1.3) return 1.3;else return Number(nextEFactor.toFixed(3));
}/*** Calculates the result of multiplying an interval by an efactor.** @param {number} interval - The interval to be multiplied.* @param {number} efactor - The efactor to multiply the interval by.* @return {number} The result of the multiplication.*/
function calculateInterval(interval: number, efactor: number): number {return Math.round(interval * efactor);
}/*** Calculates the next interval and other values for a given SM2Item, based on its* current values. If the quality is less than 4, the item is marked for repetition.** @param {SM2Item} item - the SM2Item to calculate the next interval for* @return {SM2Result} an object with the next SM2Item and a boolean indicating if the item needs to be repeated*/
function sm2(item: SM2Item): SM2Result {let { interval = 1, count = 1, efactor = 2.5, quality } = item;if (interval < 1) interval = 1;if (count < 1) count = 1;if (efactor < 1.3) efactor = 1.3;if (efactor > 2.5) efactor = 2.5;if (quality < 0) quality = 0;if (quality > 5) quality = 5;const needRepeat: boolean = quality < 4;const nextItem: SM2Item = {interval,count,efactor,quality,};if (quality < 3) {nextItem.interval = 1;nextItem.count = 1;nextItem.efactor = 2.5;} else {switch (count) {case 1:nextItem.interval = 1;break;case 2:nextItem.interval = 6;break;default:nextItem.interval = calculateInterval(interval, efactor);break;}nextItem.count = count + 1;nextItem.efactor = calculateEFactor(efactor, quality);}return { item: nextItem, needRepeat }
}export default sm2;

使用实例:

import sm2, { SM2Item } from '../src/sm2';interface Card {question: string,answer: string,interval?: number,count?: number,efactor?: number,
};function getCardsFromSomewhere(): Card[] {const cards: Card[] = [{ question: 'a', answer: 'A' },{ question: 'b', answer: 'B', interval: 1, count: 1, efactor: 2.5 },{ question: 'c', answer: 'C', interval: 6, count: 2, efactor: 1.8 },{ question: 'd', answer: 'D', interval: 8, count: 3, efactor: 1.3 },{ question: 'e', answer: 'E', interval: 16, count: 4, efactor: 2.1 },];return cards;
}function getQualityFromUserResponse(card: Card): number {return Math.round(Math.random() * 5);
}function updateCard(card: Card, item: SM2Item) {const { interval, count, efactor } = item;const cardUpdated: Card = { ...card, interval, count, efactor };console.log('card with new sm info', cardUpdated);
}function main() {const cards = getCardsFromSomewhere();for (const card of cards) {const { interval, count, efactor } = card;const quality = getQualityFromUserResponse(card);const {item, needRepeat} = sm2({ interval, count, efactor, quality });updateCard(card, item);if(needRepeat) {console.log('Card need to remember again today until quality >= 4.', card);}}
}main();

NPM

已经发布到了npm,可以直接安装使用:

npm install spaced-repetition.js

GITHUB

Github仓库地址:spaced-repetition.js


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部