Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open Source implementation of a Spaced Repetition Algorithm in Java [closed]

Tags:

java

algorithm

I work on a project where Spaced Repetition is essential, however I am not a specialist on the subject and I am afraid to reinvent the square wheel. My research pointed me two different systems, namely the Leitner system and the SM family of algorithms.
I haven't decided yet which system would best fit into my project. If I was to take a SM orientation, I guess I would try to implement something similar to what Anki uses.

My best option would be to use an existing Java library. It could be quite simple, all I need is to compute the time for the next repetition.
Has anyone heard of such an initiative ?

like image 499
Mikael Couzic Avatar asked Sep 30 '11 10:09

Mikael Couzic


2 Answers

I haven't looked at Anki's implementation but have you seen this one? quiz-me an SRS in Java.

Basically it goes like this

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);
}

If you really want Anki's algorithm, look through the source of Anki in Android available in Github. It is GPL though so you might need to buy a license.

like image 192
Eugene Ramirez Avatar answered Sep 18 '22 03:09

Eugene Ramirez


I did reinvent the square wheel in my own flashcard app. The algorithm is quite simple: The weight of an item is the product of an age component, a progress component, and an effort component.

Age component

The formula is A(x) = Cn^x, where

  • x is the time in days since the item was last tested,
  • C is the value you want when x is zero, and
  • n is a constant based on how fast you want the value to increase as x increases.

For example, if you want the value to double every five days, n = e^(ln(2/C)/5).

Progress component

The formula is P(x) = Cn^-x, where

  • x is a number that corresponds to how successful you've been with the item,
  • C is the value you want when x is zero, and
  • n is a constant based on how fast you want the value to decay as x increases.

For example, if you want the value to halve every five consecutive successes, n = e^(ln(1/2)/-5).

Effort component

This takes on one of two values:

  • 10 if you found your last recall of the item to be "hard", or
  • 1 otherwise.

The progress is adjusted thus:

  • New entries start with progress 0.
  • If you find an answer easy, the item's progress is increased by 1.
  • If you find an answer hard, the item's progress goes to min(int(previous / 2), previous - 1).
  • If you get an answer wrong, the item's progress goes to min(-1, previous - 1).

Yes, values can go negative. :)

The app selects the next item to test by making a random selection from all the items, with the probability of selection varying directly with an item's weight.

The specific numbers in the algorithm are tweakable. I've been using my current values for about a year, leading to great success in accumulating and retaining vocabulary for Spanish, German, and Latin.

(Sorry for potato quality of the math expressions. LaTeX isn't allowed here.)

like image 22
Tony Avatar answered Sep 22 '22 03:09

Tony