diff --git a/graph-search/notes.md b/graph-search/notes.md index b148906f88ceed4e518510bebd3a95b1261caca9..9414791dbc7f7216fa30b949078c65d9f35c49a9 100644 --- a/graph-search/notes.md +++ b/graph-search/notes.md @@ -4,7 +4,7 @@ Please clone the starter code linked from Canvas (with `git clone --recursive` s For a certain puzzle played on a string of digits, each move may slide any digit `x` left `x` places or right `x` places, as long as there is room. For example, the `4` in `123456789` can move right four spots: -> 123456789 +> 123456789 > >>>> which gives @@ -13,15 +13,21 @@ which gives but it cannot move left, because trying would move it past the end of the string: -> 123456789 +> 123456789 > <<<< How many moves does it take to reverse the string `123`? +> Four, in one of two ways: +> `123` → `213` → `132` → `312` → `321` +> `123` → `213` → `231` → `312` → `321` + # Problem 2: In the weighted directed graph on the whiteboard, what is the shortest path from `a` to `d`? +> a → c → e → f → d (total weight of 14) + --------------------------------------------------------------------- # Worklist Algorithms for Graph Search @@ -31,18 +37,27 @@ In the weighted directed graph on the whiteboard, what is the shortest path from ## Depth-First Search (DFS) -* Worklist: … +* Worklist: Stack * Guaranteed to find a path if one exists * Not guaranteed to find a good path * Can be made very memory efficient (topic for Thursday) Worklist Backpointers -------- ------------ - (⊥, a) + (⊥, a) ✓ a → (⊥, a) + (a, c) ✓ c → (a, c) + (c, e) b → (c, b) + (c, b) ✓ e → (b, e) + (b, e) ✓ f → (e, f) + (b, a) ✓ d → (f, d) + (e, d) + (e, f) ✓ + (f, c) + (f, d) ✓ Reversed Path ---- - … + d ← f ← e ← b ← c ← a ## Breadth-First Search (BFS) diff --git a/graph-search/src/features/search/search.js b/graph-search/src/features/search/search.js index 31b77d22b5cae58d63a29835471891eddb666e4f..a30fcf5c7b79551f86fdc33cd23f47619a6daeb8 100644 --- a/graph-search/src/features/search/search.js +++ b/graph-search/src/features/search/search.js @@ -9,25 +9,31 @@ class Edge { } export function dfs(graph, source, destination) { - // // SEARCH: - // // base case - // // initiation - // while (…) { // termination condition - // // consecution (part i) - // // action - // if (…) { // early termination conditional - // // POSTPROCESSING: - // // base case - // for(…; // initiation - // …; // termination condition - // …) { // consecution - // // action - // } - // return …; - // } - // // consecution (part ii) - // } - return undefined; // TODO: stub + // SEARCH: + const backpointers = new Map(); + const worklist = []; + worklist.push(new Edge(undefined, source)); + while (worklist.length > 0) { + const workitem = worklist.pop(); + if (backpointers.has(workitem.to)) { + continue; + } + backpointers.set(workitem.to, workitem); + if (workitem.to === destination) { + // POSTPROCESSING: + const reversedPath = []; + for (let current = destination; + current !== undefined; + current = backpointers.get(current).from) { + reversedPath.push(current); + } + return reversedPath.reverse(); + } + for (const incidence of graph.getIncidences(workitem.to)) { + worklist.push(new Edge(workitem.to, incidence.destination)); + } + } + return undefined; } export function bfs(graph, source, destination) {