From 820423ad5f87263b0f1f076b7b755646e57b91ed Mon Sep 17 00:00:00 2001
From: "Brady J. Garvin" <bgarvin@cse.unl.edu>
Date: Mon, 2 Oct 2023 10:45:31 -0500
Subject: [PATCH] Recorded work from Friday.

---
 dynamic-programming/notes.md                  | 50 +++++++++----------
 .../src/features/knapsack/solver.js           | 15 ++++--
 2 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/dynamic-programming/notes.md b/dynamic-programming/notes.md
index 857c51c..dd6cfdb 100644
--- a/dynamic-programming/notes.md
+++ b/dynamic-programming/notes.md
@@ -36,8 +36,8 @@ so that every line is at most seven characters long, including spaces.  The pena
 Example: The wrapping
 
 > x x x x
-> xxxx   
-> xxxx   
+> xxxx
+> xxxx
 
 has a total penalty of `(7 - 7)² + (7 - 4)² + (7 - 4)² = 0 + 9 + 9 = 18`.  But there is a wrapping with a lower total penalty.
 
@@ -50,35 +50,35 @@ Problem: Subject to an integer weight limit, what choice of items (allowing repe
 ## DAG
 
 *   Edges (actions):
-    *   … or
-    *   …
+    *   Take one of the items or
+    *   Take one kg of nothing.
 *   Vertices (situations):
-    *   …
+    *   How much weight have we put into the backpack?
 *   Edge weights:
-    *   …
+    *   The value of the item being taken
 *   Topological order:
-    *   …
+    *   0 → 1 → … `weightLimit`
 *   Goal:
-    *   …
+    *   Compute a longest path from 0 to `weightLimit`
 
 ## Backpointer Class
 
 *   Information for the final result:
-    *   …
+    *   What item did we take?
 *   Information to go back:
-    *   …
+    *   What was the weight of the item just taken?  (redundant with the item taken)
 *   Information to compare quality:
-    *   …
+    *   What is the *total* value of all of the items taken so far?
 
 ## Choosing a Backpointer
 
 *   Exhaustive search:
-    *   Generate ….
-    *   Check that ….
+    *   Generate items from the list or else 1 kg of nothing, but make sure that we don't try to go back to a negative total weight.
+    *   Check that the item maximizes total value (the previous total value plus the value of the item used to go back).
 
 ## Example
 
-*   Item Z ….
+*   Item Z weighs 1 kg and is worth $0.
 *   Item A weighs 3 kg and is worth $10.
 *   Item B weighs 4 kg and is worth $14.
 
@@ -87,20 +87,20 @@ Problem: Subject to an integer weight limit, what choice of items (allowing repe
     Weight (kg)   Item   Total Value  (Back to Weight)
     -----------  ------  -----------  ----------------
               0  [none]           $0  ⊥
-              1  Item …            …  …
-              2  Item …            …  …
-              3  Item …            …  …
-              4  Item …            …  …
-              5  Item …            …  …
-              6  Item …            …  …
-              7  Item …            …  …
-              8  Item …            …  …
-              9  Item …            …  …
-             10  Item …            …  …
+              1  Item Z            0  0
+              2  Item Z            0  1
+              3  Item A           10  0
+              4  Item B           14  0
+              5  Item Z           14  4
+              6  Item A           20  3
+              7  Item A           24  4
+              8  Item B           28  4
+              9  Item A           30  6
+             10  Item A           34  7
 
     Reversed Path
     ----
-    10 ← (Item …) ← …
+    10 ← (Item A) ← 7 ← (Item A) ← 4 ← (Item B) ← 0
 
 --------------------------------------------------------------------------------
 
diff --git a/dynamic-programming/src/features/knapsack/solver.js b/dynamic-programming/src/features/knapsack/solver.js
index 495b9e1..ff780b5 100644
--- a/dynamic-programming/src/features/knapsack/solver.js
+++ b/dynamic-programming/src/features/knapsack/solver.js
@@ -1,8 +1,9 @@
 import { Item } from './items.js';
 
 class Backpointer {
-  constructor() {
-    // TODO: stub
+  constructor(item, totalValue) {
+    this.item = item;
+    this.totalValue = totalValue;
   }
 }
 
@@ -13,5 +14,13 @@ function chooseBackpointer(items, backpointers) {
 
 export function chooseItems(items, weightLimit) {
   console.assert(Number.isInteger(weightLimit), `Tried to choose items with a noninteger weight limit ${weightLimit}.`);
-  return []; // TODO: stub
+  const backpointers = [new Backpointer(undefined, 0)];
+  while (backpointers.length <= weightLimit) {
+    backpointers.push(chooseBackpointer(items, backpointers));
+  }
+  const reversedPath = [];
+  for (let weight = weightLimit; weight > 0; weight -= backpointers[weight].item.weight) {
+    reversedPath.push(…);
+  }
+  return reversedPath.reverse();
 }
-- 
GitLab