diff --git a/dynamic-programming/notes.md b/dynamic-programming/notes.md index dd6cfdbaab3bc541e13a950a315d1c5d4503691e..33d0f7d3739d7c68b972c6e4212aeb6fa7527d54 100644 --- a/dynamic-programming/notes.md +++ b/dynamic-programming/notes.md @@ -111,15 +111,15 @@ Problem: Wrap a paragraph to a line length, minimizing the sum of the squares of ## DAG * Edges (actions): - * … + * Place a line on the page * Vertices (situations): - * … + * The number of words placed so far * Edge weights: - * … + * The penalty for the line just placed * Topological order: - * … + * Increasing order: 0 → 1 → … → `wordCount` * Goal: - * … + * Find a shortest path from 0 to `wordCount` ## Backpointer Class diff --git a/dynamic-programming/src/features/knapsack/solver.js b/dynamic-programming/src/features/knapsack/solver.js index ff780b5e39ca74a1f413a71705830c265adfd043..da85c9710487034c266dfcdf5486f86056f70a46 100644 --- a/dynamic-programming/src/features/knapsack/solver.js +++ b/dynamic-programming/src/features/knapsack/solver.js @@ -1,5 +1,7 @@ import { Item } from './items.js'; +const KILOGRAM_OF_NOTHING = new Item(1, 0); + class Backpointer { constructor(item, totalValue) { this.item = item; @@ -9,7 +11,23 @@ class Backpointer { function chooseBackpointer(items, backpointers) { const currentWeight = backpointers.length; - // TODO: stub + let best = new Backpointer( + KILOGRAM_OF_NOTHING, + backpointers[currentWeight - 1].totalValue, + ); + for (const item of items) { + const previousWeight = currentWeight - item.weight; + if (previousWeight >= 0) { + const candidate = new Backpointer( + item, + item.value + backpointers[previousWeight].totalValue, + ); + if (candidate.totalValue > best.totalValue) { + best = candidate; + } + } + } + return best; } export function chooseItems(items, weightLimit) { @@ -20,7 +38,10 @@ export function chooseItems(items, weightLimit) { } const reversedPath = []; for (let weight = weightLimit; weight > 0; weight -= backpointers[weight].item.weight) { - reversedPath.push(…); + const item = backpointers[weight].item; + if (item !== KILOGRAM_OF_NOTHING) { + reversedPath.push(item); + } } return reversedPath.reverse(); }