package info.opencards.learnstrats.ltm; import info.opencards.Utils; import info.opencards.core.Item; import info.opencards.core.ItemValuater; import info.opencards.ui.preferences.GlobLearnSettings; import java.util.ArrayList; import java.util.List; /** * An improved version of SM2 which also incoporates a kind of ultra-short-term history into the scheduling process. * * @author Holger Brandl */ public class UltraShortSM2 extends SM2 { /** * The in-session re-scheduler to be used to find an optimal next recall-point still unknown items. */ private final USTMScheduler ustmScheduler; public UltraShortSM2(ItemValuater itemValuater) { super(itemValuater); long ustmDelay = 1000 * Utils.getPrefs().getInt(GlobLearnSettings.USTM_DELAY, GlobLearnSettings.USTM_DELAY_DEFAULT); ustmScheduler = new USTMScheduler(ustmDelay); } protected void scoreNextItem() { // try to recall the latest ustm-item (which timed out while the last shown item was evaluated). if (ustmScheduler.hasScheduledItems()) { Item item = ustmScheduler.getScheduledItem(); assert scheduledItems.contains(item); valuater.score(item); } else { // handle the case that // test whether there are still some not-ustm-rescheduled items to be tested before interrupting test-threads //are all scheduled already ustm-rescheduled if (ustmScheduler.getAllCurrentItems().containsAll(scheduledItems)) { // all remaining cards are in rescheduled. --> select the one with lowest timeout-value valuater.score(ustmScheduler.cancelNextTask()); } else { // score an arbitrary item which is not yet ustm-rescheduled (there is at least one because of the last 'if') List<Item> ustmReducedItems = new ArrayList<Item>(scheduledItems); ustmReducedItems.removeAll(ustmScheduler.getAllCurrentItems()); assert ustmReducedItems.size() > 0; // Utils.log("ustm reduced items size" + ustmReducedItems.size()); Item nextItem = ustmReducedItems.get(Utils.getRandGen().nextInt(ustmReducedItems.size())); // Utils.log("next item " + nextItem); valuater.score(nextItem); } } } protected boolean applyLTMFeedback(Item item, Integer feedback) { boolean isScheduledForToday = !super.applyLTMFeedback(item, feedback); if (isScheduledForToday) { // register the item to the ust-scheduler ustmScheduler.reschedule(item); return false; } return !isScheduledForToday; } protected boolean isFinished() { boolean isFinished = super.isFinished(); if (isFinished) ustmScheduler.stop(); return isFinished; } }