mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
refactor optimal retention to minimize workload per memorization & fix progress goes backwards (#3065)
* Feat/optimal retention for minimal workload per memorization * ./ninja fix:minilints * update to FSRS-rs 0.5.2 * update to FSRS-rs 0.5.3 * ./ninja fix:minilints * 'estimated retention' -> 'predicted optimal retention'; add warning (dae)
This commit is contained in:
parent
04fe3655e2
commit
8c9d7d64d9
7 changed files with 22 additions and 35 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1792,9 +1792,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fsrs"
|
||||
version = "0.5.0"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c7e6a1986cc2b7a64445d84e2c453ecd8d95dcf90b797205c54573697e10b17"
|
||||
checksum = "50f8d2ba5394c6e36fa01d88df181206bcae8b7a4ef3c5653eb4d635e3f595e4"
|
||||
dependencies = [
|
||||
"burn",
|
||||
"itertools 0.12.1",
|
||||
|
|
|
@ -35,7 +35,7 @@ git = "https://github.com/ankitects/linkcheck.git"
|
|||
rev = "184b2ca50ed39ca43da13f0b830a463861adb9ca"
|
||||
|
||||
[workspace.dependencies.fsrs]
|
||||
version = "0.5.0"
|
||||
version = "0.5.3"
|
||||
# git = "https://github.com/open-spaced-repetition/fsrs-rs.git"
|
||||
# rev = "58ca25ed2bc4bb1dc376208bbcaed7f5a501b941"
|
||||
# path = "../open-spaced-repetition/fsrs-rs"
|
||||
|
|
|
@ -1198,7 +1198,7 @@
|
|||
},
|
||||
{
|
||||
"name": "fsrs",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.3",
|
||||
"authors": "Open Spaced Repetition",
|
||||
"repository": "https://github.com/open-spaced-repetition/fsrs-rs",
|
||||
"license": "BSD-3-Clause",
|
||||
|
|
|
@ -357,7 +357,7 @@ deck-config-get-params = Get Params
|
|||
deck-config-fsrs-on-all-clients =
|
||||
Please ensure all of your Anki clients are Anki(Mobile) 23.10+ or AnkiDroid 2.17+. FSRS will
|
||||
not work correctly if one of your clients is older.
|
||||
deck-config-estimated-retention = Estimated retention: { $num }
|
||||
deck-config-predicted-optimal-retention = Predicted optimal retention: { $num }
|
||||
deck-config-complete = { $num }% complete.
|
||||
deck-config-iterations = Iteration: { $count }...
|
||||
deck-config-reschedule-cards-on-change = Reschedule cards on change
|
||||
|
|
|
@ -373,12 +373,10 @@ message FsrsReview {
|
|||
|
||||
message ComputeOptimalRetentionRequest {
|
||||
repeated float weights = 1;
|
||||
uint32 deck_size = 2;
|
||||
uint32 days_to_simulate = 3;
|
||||
uint32 max_minutes_of_study_per_day = 4;
|
||||
uint32 max_interval = 5;
|
||||
string search = 6;
|
||||
double loss_aversion = 7;
|
||||
uint32 days_to_simulate = 2;
|
||||
uint32 max_interval = 3;
|
||||
string search = 4;
|
||||
double loss_aversion = 5;
|
||||
}
|
||||
|
||||
message ComputeOptimalRetentionResponse {
|
||||
|
|
|
@ -28,12 +28,15 @@ impl Collection {
|
|||
invalid_input!("no days to simulate")
|
||||
}
|
||||
let p = self.get_optimal_retention_parameters(&req.search)?;
|
||||
let learn_span = req.days_to_simulate as usize;
|
||||
let learn_limit = 10;
|
||||
let deck_size = learn_span * learn_limit;
|
||||
Ok(fsrs
|
||||
.optimal_retention(
|
||||
&SimulatorConfig {
|
||||
deck_size: req.deck_size as usize,
|
||||
deck_size,
|
||||
learn_span: req.days_to_simulate as usize,
|
||||
max_cost_perday: req.max_minutes_of_study_per_day as f64 * 60.0,
|
||||
max_cost_perday: f64::MAX,
|
||||
max_ivl: req.max_interval as f64,
|
||||
recall_costs: [p.recall_secs_hard, p.recall_secs_good, p.recall_secs_easy],
|
||||
forget_cost: p.forget_secs,
|
||||
|
@ -50,7 +53,7 @@ impl Collection {
|
|||
p.review_rating_probability_easy,
|
||||
],
|
||||
loss_aversion: req.loss_aversion,
|
||||
learn_limit: usize::MAX,
|
||||
learn_limit,
|
||||
review_limit: usize::MAX,
|
||||
},
|
||||
&req.weights,
|
||||
|
|
|
@ -55,9 +55,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
| undefined;
|
||||
|
||||
const optimalRetentionRequest = new ComputeOptimalRetentionRequest({
|
||||
deckSize: 10000,
|
||||
daysToSimulate: 365,
|
||||
maxMinutesOfStudyPerDay: 30,
|
||||
lossAversion: 2.5,
|
||||
});
|
||||
$: if (optimalRetentionRequest.daysToSimulate > 3650) {
|
||||
|
@ -249,7 +247,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
if (!retention) {
|
||||
return "";
|
||||
}
|
||||
return tr.deckConfigEstimatedRetention({ num: retention.toFixed(2) });
|
||||
return tr.deckConfigPredictedOptimalRetention({ num: retention.toFixed(2) });
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -348,15 +346,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<details>
|
||||
<summary>{tr.deckConfigComputeOptimalRetention()} (experimental)</summary>
|
||||
|
||||
<SpinBoxRow
|
||||
bind:value={optimalRetentionRequest.deckSize}
|
||||
defaultValue={10000}
|
||||
min={100}
|
||||
max={99999}
|
||||
>
|
||||
<SettingTitle>Deck size</SettingTitle>
|
||||
</SpinBoxRow>
|
||||
|
||||
<SpinBoxRow
|
||||
bind:value={optimalRetentionRequest.daysToSimulate}
|
||||
defaultValue={365}
|
||||
|
@ -366,15 +355,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<SettingTitle>Days to simulate</SettingTitle>
|
||||
</SpinBoxRow>
|
||||
|
||||
<SpinBoxRow
|
||||
bind:value={optimalRetentionRequest.maxMinutesOfStudyPerDay}
|
||||
defaultValue={30}
|
||||
min={1}
|
||||
max={1800}
|
||||
>
|
||||
<SettingTitle>Minutes study/day</SettingTitle>
|
||||
</SpinBoxRow>
|
||||
|
||||
<button
|
||||
class="btn {computingRetention ? 'btn-warning' : 'btn-primary'}"
|
||||
disabled={!computingRetention && computing}
|
||||
|
@ -389,6 +369,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
{#if optimalRetention}
|
||||
{estimatedRetention(optimalRetention)}
|
||||
{#if optimalRetention > $config.desiredRetention}
|
||||
<Warning
|
||||
warning="Your desired retention is below optimal. Increasing it is recommended."
|
||||
className="alert-warning"
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
<div>{computeRetentionProgressString}</div>
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue