From 5a97824681b6619d69410fcb741c6d2b28c987cf Mon Sep 17 00:00:00 2001 From: Nathan Howard Date: Wed, 31 Dec 2025 11:02:44 -0800 Subject: [PATCH] sorting and searching --- .../Workspace/Lab11_TopoSort/.classpath | 11 + .../Workspace/Lab11_TopoSort/.project | 17 ++ .../org.eclipse.core.resources.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 11 + .../Lab11_TopoSort/src/CurricExamples.java | 92 +++++++ .../Lab11_TopoSort/src/Curriculum.java | 73 ++++++ .../Workspace/Lect30_Graphs/.classpath | 11 + .../Workspace/Lect30_Graphs/.project | 17 ++ .../org.eclipse.core.resources.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 11 + .../Lect30_Graphs/src/Collections.java | 45 ++++ .../Workspace/Lect30_Graphs/src/Graph.java | 162 ++++++++++++ .../Lect30_Graphs/src/GraphExamples.java | 113 +++++++++ .../Lect31_DijkstrasAlgorithm/.classpath | 11 + .../Lect31_DijkstrasAlgorithm/.project | 17 ++ .../org.eclipse.core.resources.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 11 + .../src/Collections.java | 126 ++++++++++ .../src/Comparator.java | 51 ++++ .../Lect31_DijkstrasAlgorithm/src/Graph.java | 230 ++++++++++++++++++ .../src/GraphExamples.java | 153 ++++++++++++ .../src/PQExamples.java | 142 +++++++++++ .../Workspace/Lect32_SpanningTrees/.classpath | 11 + .../Workspace/Lect32_SpanningTrees/.project | 17 ++ .../org.eclipse.core.resources.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 11 + .../Lect32_SpanningTrees/src/Collections.java | 126 ++++++++++ .../Lect32_SpanningTrees/src/Comparator.java | 44 ++++ .../Lect32_SpanningTrees/src/PQExamples.java | 142 +++++++++++ .../src/SpanningTrees.java | 160 ++++++++++++ .../src/TreeExamples.java | 59 +++++ 31 files changed, 1882 insertions(+) create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java create mode 100644 completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/TreeExamples.java diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project new file mode 100644 index 0000000..0632975 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project @@ -0,0 +1,17 @@ + + + Lab11_TopoSort + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java new file mode 100644 index 0000000..94cb17a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java @@ -0,0 +1,92 @@ +import java.util.Arrays; +import java.util.ArrayList; +import tester.Tester; + +class Examples { + Course algo = new Course("Algorithms and Data"); + Course compilers = new Course("Compilers"); + Course compSys = new Course("Computer Systems"); + Course database = new Course("Database Design"); + Course fundies2 = new Course("Fundies 2"); + Course fundies1 = new Course("Fundies 1"); + Course parallelProcessing = new Course("Large-Scale Parallel Data Processing"); + Course ooDesign = new Course("Object-Oriented Design"); + Course languages = new Course("Programming Languages"); + Course compTheory = new Course("Theory of Computation"); + + ArrayList schedule0 = new ArrayList(); + ArrayList scheduleFull = new ArrayList( + Arrays.asList(fundies1, fundies2, database, + compSys, algo, parallelProcessing, ooDesign, + compTheory, languages, compilers)); + ArrayList schedulePartial = new ArrayList( + Arrays.asList(fundies1, fundies2, database, + compSys, algo)); + ArrayList scheduleMissing = new ArrayList( + Arrays.asList(fundies2, database, + compSys, algo, parallelProcessing, ooDesign, + compTheory, languages, compilers)); + ArrayList scheduleWrongOrder = new ArrayList( + Arrays.asList(fundies1, fundies2, database, + compSys, parallelProcessing, algo, ooDesign, + compTheory, languages, compilers)); + + Curriculum curri0; + Curriculum curri1; + + void init() { + // fundies1 + this.database.addPrereq(fundies1); + this.fundies2.addPrereq(fundies1); + this.algo.addPrereq(fundies2); + this.compSys.addPrereq(fundies2); + this.ooDesign.addPrereq(fundies2); + this.compTheory.addPrereq(fundies2); + this.parallelProcessing.addPrereq(algo); + this.parallelProcessing.addPrereq(compSys); + this.languages.addPrereq(compTheory); + this.languages.addPrereq(ooDesign); + this.compilers.addPrereq(languages); + + this.curri0 = new Curriculum(); + this.curri1 = new Curriculum(new ArrayList(Arrays.asList( + algo, compilers, compSys, database, fundies1, fundies2, + parallelProcessing, ooDesign, languages, compTheory))); + } + void testProcess(Tester t) { + init(); + t.checkExpect(curri1.process(new ArrayList(), fundies1), + new ArrayList(Arrays.asList(fundies1))); + t.checkExpect(curri1.process(new ArrayList(), fundies2), + new ArrayList(Arrays.asList(fundies1, fundies2))); + t.checkExpect(curri1.process(new ArrayList(), parallelProcessing), + new ArrayList(Arrays.asList(fundies1, fundies2, algo, compSys, + parallelProcessing))); + t.checkExpect(curri1.process(new ArrayList(), compilers), + new ArrayList(Arrays.asList(fundies1, fundies2, compTheory, + ooDesign, languages, compilers))); + } + void testComesAfterPrereq(Tester t) { + init(); + t.checkExpect(curri1.comesAfterPrereqs(scheduleFull, fundies1), true); + t.checkExpect(curri1.comesAfterPrereqs(scheduleFull, compilers), true); + t.checkExpect(curri1.comesAfterPrereqs(scheduleMissing, fundies2), false); + t.checkExpect(curri1.comesAfterPrereqs(scheduleWrongOrder, fundies1), true); + t.checkExpect(curri1.comesAfterPrereqs(scheduleWrongOrder, parallelProcessing), true); + } + void testValidSchedule(Tester t) { + init(); + t.checkExpect(curri1.validSchedule(schedule0), true); + t.checkExpect(curri1.validSchedule(scheduleFull), true); + t.checkExpect(curri1.validSchedule(schedulePartial), true); + t.checkExpect(curri1.validSchedule(scheduleMissing), false); + t.checkExpect(curri1.validSchedule(scheduleWrongOrder), true); + } + void testTopologicalSort(Tester t) { + init(); + t.checkExpect(curri0.topSort(), new ArrayList()); + t.checkExpect(curri1.topSort(), new ArrayList(Arrays.asList( + fundies1, fundies2, algo, compTheory, ooDesign, languages, + compilers, compSys, database, parallelProcessing))); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java new file mode 100644 index 0000000..c8d6d26 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java @@ -0,0 +1,73 @@ +import java.util.ArrayList; + +class Curriculum { + ArrayList courses; + Curriculum(ArrayList courses) { + this.courses = courses; + } + Curriculum() { + this(new ArrayList()); + } + // EFFECT: adds another course to the set of known courses + void addCourse(Course c) { + this.courses.add(c); + } + + // If this course is in processed, then do nothing; + // otherwise, process this course’s prereqs, then + // add it to processed + ArrayList process(ArrayList processed, Course c) { + if (!processed.contains(c)) { + // process this course’s prereqs + for (Course prereq : c.prereqs) { + this.process(processed, prereq); + } + // add only after all prereqs are processed + processed.add(c); + } + return processed; + } + // returns true if the provided Course appears in the schedule + // after all of its prerequisites are satisfied + boolean comesAfterPrereqs(ArrayList schedule, Course c) { + ArrayList allPrereqs = this.process(new ArrayList(), c); + for (Course prereq : allPrereqs) { + if (!schedule.contains(prereq)) { + return false; + } + } + return true; + } + // returns true if the schedule is valid for all the courses in it. + boolean validSchedule(ArrayList schedule) { + for (Course c : schedule) { + if (!this.comesAfterPrereqs(schedule, c)) { + return false; + } + } + return true; + } + // process every course in the given list with that result list. + // Once every course has been processed, return the result list. + ArrayList topSort() { + ArrayList response = new ArrayList(); + for (Course c : this.courses) { + response = this.process(response, c); + } + return response; + } +} + +class Course { + String name; + ArrayList prereqs; + Course(String name) { + this.name = name; + this.prereqs = new ArrayList(); + } + // EFFECT: adds a course as a prereq to this one + void addPrereq(Course c) { + this.prereqs.add(c); + } + // add methods here +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project new file mode 100644 index 0000000..c96d5b4 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project @@ -0,0 +1,17 @@ + + + Lect30_Graphs + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java new file mode 100644 index 0000000..eb19168 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java @@ -0,0 +1,45 @@ +import java.util.Deque; +import java.util.ArrayDeque; + +// Represents a mutable collection of items +interface ICollection { + // Is this collection empty? + boolean isEmpty(); + // EFFECT: adds the item to the collection + void add(T item); + // Returns the first item of the collection + // EFFECT: removes that first item + T remove(); +} + +class Stack implements ICollection { + Deque contents; + Stack() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addFirst(item); + } +} + +class Queue implements ICollection { + Deque contents; + Queue() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addLast(item); // NOTE: Different from Stack! + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java new file mode 100644 index 0000000..5c6f639 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java @@ -0,0 +1,162 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.ArrayDeque; + +class Vertex { + //... any data about vertices, such as people's names, or place's GPS coordinates ... + String name; + ArrayList outEdges; // edges from this node + + Vertex(String name, ArrayList outEdges) { + this.name = name; + this.outEdges = outEdges; + } + Vertex(String name, Edge outEdge) { + this(name, new ArrayList(Arrays.asList(outEdge))); + } + Vertex(String name) { + this(name, new ArrayList()); + } + void setEdge(Edge edge) { + this.outEdges.add(edge); + } + + boolean hasPathTo(Vertex dest) { + ArrayList checked = new ArrayList(); + + return this.hasPathToHelp(dest, checked); + } + boolean hasPathToHelp(Vertex dest, ArrayList checked) { + for (Edge edge : this.outEdges) { + if (checked.contains(edge)) { + continue; + } + checked.add(edge); + if (edge.to == dest || + edge.to.hasPathToHelp(dest, checked)) { + return true; + } + } + return false; + } +} + +class Edge { + Vertex from; + Vertex to; + int weight; + + Edge(Vertex from, Vertex to, int weight) { + this.from = from; + this.to = to; + this.weight = weight; + from.setEdge(this); + } + Edge(Vertex from, Vertex to) { + this(from, to, 1); + } +} + +class Graph { + ArrayList allVertices; + + Graph(ArrayList allVertices) { + this.allVertices = allVertices; + } + Graph() { + this.allVertices = new ArrayList(); + } + + ArrayList getEdges() { + ArrayList response = new ArrayList(); + for (Vertex vertex : this.allVertices) { + for (Edge edge : vertex.outEdges) { + if (!(response.contains(edge))) { + response.add(edge); + } + } + } + return response; + } + + boolean hasPathBetween(Vertex from, Vertex to) { + Deque alreadySeen = new ArrayDeque(); + Deque worklist = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.addFirst(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.removeLast(); + if (next.equals(to)) { + return true; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.addFirst(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + return false; + } + boolean breadthFistSearch(Vertex from, Vertex to) { + return searchHelp(from, to, new Queue()); + } + boolean depthFirstSearch(Vertex from, Vertex to) { + return searchHelp(from, to, new Stack()); + } + boolean searchHelp(Vertex from, Vertex to, ICollection worklist) { + Deque alreadySeen = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.add(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.remove(); + if (next.equals(to)) { + return true; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.add(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + return false; + } + Deque findPath(Vertex from, Vertex to, ICollection worklist) { + Deque alreadySeen = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.add(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.remove(); + if (next.equals(to)) { + return alreadySeen; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.add(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + throw new RuntimeException("Could not find a valid path"); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java new file mode 100644 index 0000000..c9c9d47 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java @@ -0,0 +1,113 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.ArrayDeque; +import tester.Tester; + +class Examples { + Vertex v0; + Vertex v1; + Vertex v2; + Vertex v3; + Vertex vAlone; + ArrayList linearVerts; + + Edge e0; + Edge e1; + Edge e2; + ArrayList linearEdges; + + Vertex vA; + Vertex vB; + Vertex vC; + Vertex vD; + Vertex vE; + ArrayList circVerts; + + Edge eAB; + Edge eBD; + Edge eBC; + Edge eCA; + Edge eEB; + ArrayList circEdges; + + Graph gEmpty; + Graph gLinear; + Graph gCircular; + + void init() { + v0 = new Vertex("0"); + v1 = new Vertex("1"); + v2 = new Vertex("2"); + v3 = new Vertex("3"); + vAlone = new Vertex("Alone"); + + e0 = new Edge(v0, v1); + e1 = new Edge(v1, v2); + e2 = new Edge(v2, v3); + + linearVerts = new ArrayList(Arrays.asList(v0, v1, v2)); + linearEdges = new ArrayList(Arrays.asList(e0, e1, e2)); + + vA = new Vertex("A"); + vB = new Vertex("B"); + vC = new Vertex("C"); + vD = new Vertex("D"); + vE = new Vertex("E"); + + eAB = new Edge(vA, vB); + eBD = new Edge(vB, vD); + eBC = new Edge(vB, vC); + eCA = new Edge(vC, vA); + eEB = new Edge(vE, vB); + + circVerts = new ArrayList( + Arrays.asList(vA, vB, vC, vD, vE)); + circEdges = new ArrayList( + Arrays.asList(eAB, eBD, eBC, eCA, eEB)); + + gEmpty = new Graph(); + gLinear = new Graph(linearVerts); + gCircular = new Graph(circVerts); + } + + void testGetEdges(Tester t) { + init(); + t.checkExpect(this.gLinear.getEdges(), linearEdges); + t.checkExpect(this.gCircular.getEdges(), circEdges); + } + void testHasPath(Tester t) { + init(); + t.checkExpect(this.v0.hasPathTo(v3), true); + t.checkExpect(this.v0.hasPathTo(vAlone), false); + t.checkExpect(this.vA.hasPathTo(vC), true); + t.checkExpect(this.vA.hasPathTo(vE), false); + t.checkExpect(this.gLinear.hasPathBetween(v0, v3), true); + t.checkExpect(this.gLinear.hasPathBetween(v0, vAlone), false); + t.checkExpect(this.gCircular.hasPathBetween(vA, vC), true); + t.checkExpect(this.gCircular.hasPathBetween(vA, vD), true); + t.checkExpect(this.gCircular.hasPathBetween(vA, vE), false); + t.checkExpect(this.gCircular.hasPathBetween(vE, vA), true); + } + void testSearch(Tester t) { + init(); + t.checkExpect(this.gLinear.breadthFistSearch(v0, v3), true); + t.checkExpect(this.gLinear.breadthFistSearch(v0, vAlone), false); + t.checkExpect(this.gCircular.breadthFistSearch(vA, vC), true); + t.checkExpect(this.gCircular.breadthFistSearch(vA, vD), true); + t.checkExpect(this.gCircular.breadthFistSearch(vA, vE), false); + t.checkExpect(this.gCircular.breadthFistSearch(vE, vA), true); + + t.checkExpect(this.gLinear.depthFirstSearch(v0, v3), true); + t.checkExpect(this.gLinear.depthFirstSearch(v0, vAlone), false); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vC), true); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vD), true); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vE), false); + t.checkExpect(this.gCircular.depthFirstSearch(vE, vA), true); + } + void testFindPath(Tester t) { + init(); + t.checkExpect(this.gLinear.findPath(v0, v3, new Queue()), + new ArrayDeque(Arrays.asList(v3, v2, v1, v0))); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project new file mode 100644 index 0000000..5581f2d --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project @@ -0,0 +1,17 @@ + + + Lect31_DijkstrasAlgorithm + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java new file mode 100644 index 0000000..32b2b20 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java @@ -0,0 +1,126 @@ +import java.util.Deque; +import java.util.ArrayDeque; +import java.util.ArrayList; + +// Represents a mutable collection of items +interface ICollection { + // Is this collection empty? + boolean isEmpty(); + // EFFECT: adds the item to the collection + void add(T item); + // Returns the first item of the collection + // EFFECT: removes that first item + T remove(); +} + +// first in first out +class Stack implements ICollection { + Deque contents; + Stack() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addFirst(item); + } +} + +// last in last out +class Queue implements ICollection { + Deque contents; + Queue() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addLast(item); // NOTE: Different from Stack! + } +} + +// highest priority out +class PriorityQueue implements ICollection { + ArrayList heap; + IComparator comp; + PriorityQueue(ArrayList inputList, IComparator comp) { + this.comp = comp; + buildHeap(inputList); + } + PriorityQueue(IComparator comp) { + this(new ArrayList(), comp); + } + void buildHeap(ArrayList inputList) { + this.heap = inputList; + for (int i = inputList.size() - 1; i >= 0; i--) { + this.downHeap(i); + } + } + // swaps the parent and child items + void swap(int parentIndex, int childIndex) { + T temp = heap.get(parentIndex); + heap.set(parentIndex, heap.get(childIndex)); + heap.set(childIndex, temp); + } + // recursively uses comp to compare child with parent + // and swaps if child is higher priority + void upHeap(int childIndex) { + int parentIndex = (childIndex - 1) / 2; + // comp will return >0 if left has higher priority than right + // ergo swap when comp returns <0 + if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) { + this.swap(parentIndex, childIndex); + this.upHeap(parentIndex); + } + } + // recursively uses comp to compare parent with children + // and swaps if child is higher priority + void downHeap(int parentIndex) { + this.downHeapMaxDepth(parentIndex, this.heap.size()); + } + void downHeapMaxDepth(int parentIndex, int maxDepthIndex) { + int leftChildIndex = 2 * parentIndex + 1; + int rightChildIndex = 2 * parentIndex + 2; + if (rightChildIndex < maxDepthIndex) { + if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) { + if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) { + this.swap(parentIndex, leftChildIndex); + this.downHeapMaxDepth(leftChildIndex, maxDepthIndex); + } + } else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) { + this.swap(parentIndex, rightChildIndex); + this.downHeapMaxDepth(rightChildIndex, maxDepthIndex); + } + } else if (leftChildIndex < maxDepthIndex) { + if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) { + this.swap(parentIndex, leftChildIndex); + this.downHeapMaxDepth(leftChildIndex, maxDepthIndex); + } + } + } + + // Interface methods + public boolean isEmpty() { + return this.heap.isEmpty(); + } + public void add(T item) { + this.heap.add(item); + this.upHeap(heap.size() - 1); + } + public T remove() { + int lastIndex = this.heap.size() - 1; + this.swap(0, lastIndex); + T response = this.heap.remove(lastIndex); + this.downHeap(0); + return response; + } + +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java new file mode 100644 index 0000000..df6feb4 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java @@ -0,0 +1,51 @@ +interface IPred { + boolean apply(T t); +} + +interface IFunc { + R apply(A arg); +} + +interface IFunc2 { + R apply(A1 arg1, A2 arg2); +} + +interface IComparator { + // Returns a negative number if t1 priority is less than t2 priority==- + int compare(T t1, T t2); +} + +class ParentLargerInteger implements IComparator { + // returns true (>0) if left has higher priority (larger int) + public int compare(Integer left, Integer right) { + return left - right; + } +} + +class ParentSmallerInteger implements IComparator { + // returns true (>0) if left has a higher priority (smaller int) + public int compare(Integer left, Integer right) { + return right - left; + } +} + +class HigherVertexWeight implements IComparator { + // returns true (>0) if left has a higher priority (larger weight) + public int compare(Vertex left, Vertex right) { + return left.weight - right.weight; + } +} + +class SmallerVertexWeight implements IComparator { + // returns true (>0) if left has a higher priority (smaller weight) + public int compare(Vertex left, Vertex right) { + return right.weight - left.weight; + } +} + +class SmallerPathCost implements IComparator { + // returns true (>0) if left has a lower cost (cumulative cost) + public int compare(Path left, Path right) { + return right.weight - left.weight; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java new file mode 100644 index 0000000..0a0c1b9 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java @@ -0,0 +1,230 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.ArrayDeque; + +class Vertex { + //... any data about vertices, such as people's names, or place's GPS coordinates ... + String name; + int weight; + ArrayList outEdges; // edges from this node + + Vertex(String name, int weight, ArrayList outEdges) { + this.name = name; + this.weight = weight; + this.outEdges = outEdges; + } + Vertex(String name, Edge outEdge) { + this(name, 1, new ArrayList(Arrays.asList(outEdge))); + } + Vertex(String name, int weight) { + this(name, weight, new ArrayList()); + } + Vertex(String name) { + this(name, 1, new ArrayList()); + } + + void setEdge(Edge edge) { + this.outEdges.add(edge); + } + + boolean hasPathTo(Vertex dest) { + ArrayList checked = new ArrayList(); + return this.hasPathToHelp(dest, checked); + } + boolean hasPathToHelp(Vertex dest, ArrayList checked) { + for (Edge edge : this.outEdges) { + if (checked.contains(edge)) { + continue; + } + checked.add(edge); + if (edge.to == dest || + edge.to.hasPathToHelp(dest, checked)) { + return true; + } + } + return false; + } +} + +class Edge { + Vertex from; + Vertex to; + int weight; + + Edge(Vertex from, Vertex to, int weight) { + this.from = from; + this.to = to; + this.weight = weight; + from.setEdge(this); + } + Edge(Vertex from, Vertex to) { + this(from, to, 1); + } +} + +class Path { + ArrayList route; + Vertex next; + int weight; + Path(ArrayList route, Vertex next, int weight) { + this.route = route; + this.next = next; + this.weight = weight; + } + Path(Vertex v) { + this(new ArrayList(), v, v.weight); + } + Path() { + this(new ArrayList(), null, 0); + } + + void addNext(Vertex v) { + this.route.add(this.next); + this.weight = this.weight + v.weight; + this.next = v; + } + Path branchPath(Vertex v, int edgeWeight) { + // create copy of this + Path copy = new Path(new ArrayList(this.route), this.next, + this.weight + edgeWeight); + copy.addNext(v); + return copy; + } + ArrayList getFullRoute() { + route.add(this.next); + return this.route; + } +} + +class Graph { + ArrayList allVertices; + + Graph(ArrayList allVertices) { + this.allVertices = allVertices; + } + Graph() { + this.allVertices = new ArrayList(); + } + + ArrayList getEdges() { + ArrayList response = new ArrayList(); + for (Vertex vertex : this.allVertices) { + for (Edge edge : vertex.outEdges) { + if (!(response.contains(edge))) { + response.add(edge); + } + } + } + return response; + } + + boolean hasPathBetween(Vertex from, Vertex to) { + Deque alreadySeen = new ArrayDeque(); + Deque worklist = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.addFirst(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.removeLast(); + if (next.equals(to)) { + return true; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.addFirst(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + return false; + } + boolean breadthFirstSearch(Vertex from, Vertex to) { + return searchHelp(from, to, new Queue()); + } + boolean depthFirstSearch(Vertex from, Vertex to) { + return searchHelp(from, to, new Stack()); + } + boolean weightedSearch(Vertex from, Vertex to, IComparator comp) { + return searchHelp(from, to, new PriorityQueue(comp)); + } + boolean searchHelp(Vertex from, Vertex to, ICollection worklist) { + Deque alreadySeen = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.add(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.remove(); + if (next.equals(to)) { + return true; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.add(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + return false; + } + // ArrayList leastCostPath(Vertex from, Vertex to) { + // ICollection weightedPaths = new PriorityQueue(new SmallerPathCost()); + // Deque alreadySeen = new ArrayDeque(); + // + // // Initialize the worklist with the from vertex' + // weightedPaths.add(new Path(from)); + // // As long as the worklist isn't empty... + // while (!weightedPaths.isEmpty()) { + // Path cheapestPath = weightedPaths.remove(); + // if (cheapestPath.next.equals(to)) { + // // we need to add cheapestPath.next to returned list + // return cheapestPath.getFullRoute(); // Success! + // } else if (alreadySeen.contains(cheapestPath.next)) { + // // do nothing: we've already seen this one + // } else { + // // add all the neighbors of next to the worklist for further processing + // for (Edge e : cheapestPath.next.outEdges) { + // weightedPaths.add(cheapestPath.branchPath(e.to, e.weight)); + // } + // // add next to alreadySeen, since we're done with it + // alreadySeen.add(cheapestPath.next); + // } + // } + // // We haven't found the to vertex, and there are no more to try + // throw new RuntimeException("Cannot find valid route"); + // } + Deque findPath(Vertex from, Vertex to, ICollection worklist) { + Deque alreadySeen = new ArrayDeque(); + + // Initialize the worklist with the from vertex + worklist.add(from); + // As long as the worklist isn't empty... + while (!worklist.isEmpty()) { + Vertex next = worklist.remove(); + if (next.equals(to)) { + return alreadySeen; // Success! + } else if (alreadySeen.contains(next)) { + // do nothing: we've already seen this one + } else { + // add all the neighbors of next to the worklist for further processing + for (Edge e : next.outEdges) { + worklist.add(e.to); + } + // add next to alreadySeen, since we're done with it + alreadySeen.addFirst(next); + } + } + // We haven't found the to vertex, and there are no more to try + throw new RuntimeException("Could not find a valid path"); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java new file mode 100644 index 0000000..895553d --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java @@ -0,0 +1,153 @@ +import java.util.ArrayList; +import java.util.Deque; +import java.util.Arrays; +import java.util.ArrayDeque; +import tester.Tester; + +class GraphExamples { + Vertex v0; + Vertex v1; + Vertex v2; + Vertex v3; + Vertex vAlone; + ArrayList linearVerts; + + Edge e0; + Edge e1; + Edge e2; + ArrayList linearEdges; + + Vertex vA; + Vertex vB; + Vertex vC; + Vertex vD; + Vertex vE; + ArrayList circVerts; + + Edge eAB; + Edge eBD; + Edge eBC; + Edge eCA; + Edge eEB; + ArrayList circEdges; + + Vertex wA; + Vertex wB; + Vertex wC; + Vertex wD; + Vertex wE; + Vertex wF; + ArrayList weightedVerts; + + Edge wAB; + Edge wBC; + Edge wCD; + Edge wDE; + Edge wEF; + Edge wAF; + ArrayList weightedEdges; + + Graph gEmpty; + Graph gLinear; + Graph gCircular; + Graph gWeighted; + + void init() { + v0 = new Vertex("0"); + v1 = new Vertex("1"); + v2 = new Vertex("2"); + v3 = new Vertex("3"); + e0 = new Edge(v0, v1); + e1 = new Edge(v1, v2); + e2 = new Edge(v2, v3); + linearVerts = new ArrayList(Arrays.asList(v0, v1, v2)); + linearEdges = new ArrayList(Arrays.asList(e0, e1, e2)); + + vA = new Vertex("A"); + vB = new Vertex("B"); + vC = new Vertex("C"); + vD = new Vertex("D"); + vE = new Vertex("E"); + eAB = new Edge(vA, vB); + eBD = new Edge(vB, vD); + eBC = new Edge(vB, vC); + eCA = new Edge(vC, vA); + eEB = new Edge(vE, vB); + circVerts = new ArrayList( + Arrays.asList(vA, vB, vC, vD, vE)); + circEdges = new ArrayList( + Arrays.asList(eAB, eBD, eBC, eCA, eEB)); + + wA = new Vertex("A"); + wB = new Vertex("B"); + wC = new Vertex("C"); + wD = new Vertex("D"); + wE = new Vertex("E"); + wF = new Vertex("F"); + wAB = new Edge(wA, wB, 1); + wBC = new Edge(wB, wC, 1); + wCD = new Edge(wC, wD, 1); + wDE = new Edge(wD, wE, 1); + wEF = new Edge(wE, wF, 1); + wAF = new Edge(wA, wF, 3); + weightedVerts = new ArrayList( + Arrays.asList(wA, wB, wC, wD, wE, wF)); + weightedEdges = new ArrayList( + Arrays.asList(wAB, wBC, wCD, wDE, wEF, wAF)); + + vAlone = new Vertex("Alone"); + gEmpty = new Graph(); + gLinear = new Graph(linearVerts); + gCircular = new Graph(circVerts); + gWeighted = new Graph(weightedVerts); + } + void testGetEdges(Tester t) { + init(); + t.checkExpect(this.gLinear.getEdges(), linearEdges); + t.checkExpect(this.gCircular.getEdges(), circEdges); + } + void testHasPath(Tester t) { + init(); + t.checkExpect(this.v0.hasPathTo(v3), true); + t.checkExpect(this.v0.hasPathTo(vAlone), false); + t.checkExpect(this.vA.hasPathTo(vC), true); + t.checkExpect(this.vA.hasPathTo(vE), false); + t.checkExpect(this.gLinear.hasPathBetween(v0, v3), true); + t.checkExpect(this.gLinear.hasPathBetween(v0, vAlone), false); + t.checkExpect(this.gCircular.hasPathBetween(vA, vC), true); + t.checkExpect(this.gCircular.hasPathBetween(vA, vD), true); + t.checkExpect(this.gCircular.hasPathBetween(vA, vE), false); + t.checkExpect(this.gCircular.hasPathBetween(vE, vA), true); + } + void testSearch(Tester t) { + init(); + t.checkExpect(this.gLinear.breadthFirstSearch(v0, v3), true); + t.checkExpect(this.gLinear.breadthFirstSearch(v0, vAlone), false); + t.checkExpect(this.gCircular.breadthFirstSearch(vA, vC), true); + t.checkExpect(this.gCircular.breadthFirstSearch(vA, vD), true); + t.checkExpect(this.gCircular.breadthFirstSearch(vA, vE), false); + t.checkExpect(this.gCircular.breadthFirstSearch(vE, vA), true); + + t.checkExpect(this.gLinear.depthFirstSearch(v0, v3), true); + t.checkExpect(this.gLinear.depthFirstSearch(v0, vAlone), false); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vC), true); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vD), true); + t.checkExpect(this.gCircular.depthFirstSearch(vA, vE), false); + t.checkExpect(this.gCircular.depthFirstSearch(vE, vA), true); + + IComparator smallerWeight = new SmallerVertexWeight(); + t.checkExpect(this.gWeighted.weightedSearch(wA, wF, smallerWeight), true); + t.checkExpect(this.gWeighted.weightedSearch(wA, wB, smallerWeight), true); + t.checkExpect(this.gWeighted.weightedSearch(wF, wA, smallerWeight), false); + } + // void testWeightedSearch(Tester t) { + // init(); + // ArrayList ans = new ArrayList(); + // ans.add(wA); + // ans.add(wF); + // t.checkExpect(this.gWeighted.leastCostPath(wA, wF), ans); + // wAF.weight = 10; + // t.checkExpect(this.gWeighted.leastCostPath(wA, wF), + // new ArrayList(Arrays.asList(wA, wB, wC, wD, wE, wF))); + // } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java new file mode 100644 index 0000000..bda801f --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java @@ -0,0 +1,142 @@ +import java.util.ArrayList; +import java.util.Arrays; +import tester.Tester; + +class PQExamples { + ArrayList unsortedList; + ArrayList upHeapedList; + ArrayList downHeapedList; + ArrayList sortedList; + ArrayList worstCaseList; + + PriorityQueue heapEmptyParentSmaller; + PriorityQueue heapPopulatedParentSmaller; + PriorityQueue heapGreaterTop; + + IComparator compParentGreater; + IComparator compParentSmaller; + + void init() { + unsortedList = new ArrayList( + Arrays.asList(10, 60, 15, 30, 50, 40, 20, 80, 20, 50)); + downHeapedList = new ArrayList( + Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50)); + upHeapedList = new ArrayList( + Arrays.asList(80, 60, 40, 50, 50, 15, 20, 10, 20, 30)); + worstCaseList = new ArrayList( + Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1)); + + compParentGreater = new ParentLargerInteger(); + compParentSmaller = new ParentSmallerInteger(); + heapEmptyParentSmaller = new PriorityQueue(compParentSmaller); + heapPopulatedParentSmaller = new PriorityQueue(unsortedList, compParentSmaller); + } + void testSwap(Tester t) { + init(); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(10); + heapEmptyParentSmaller.heap.add(20); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 20); + heapEmptyParentSmaller.swap(0, 1); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 20); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 10); + } + void testUpHeap(Tester t) { + init(); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(0); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 1); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 20); + heapEmptyParentSmaller.heap.add(10); + heapEmptyParentSmaller.upHeap(1); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + heapEmptyParentSmaller.heap.add(30); + heapEmptyParentSmaller.upHeap(2); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 3); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(3); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 4); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30); + t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(4); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(5); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 6); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(4), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(5), 30); + } + void testDownHeap(Tester t) { + init(); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(0, 50); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 1); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 50); + heapEmptyParentSmaller.heap.add(0, 40); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50); + heapEmptyParentSmaller.heap.add(0, 60); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 50); + heapEmptyParentSmaller.heap.add(0, 30); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 50); + heapEmptyParentSmaller.heap.add(0, 70); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(4), 70); + } + void testBuildDownHeap(Tester t) { + init(); + heapEmptyParentSmaller.buildHeap(unsortedList); + t.checkExpect(heapEmptyParentSmaller.heap, downHeapedList); + ArrayList worstDownList = new ArrayList(Arrays.asList( + 1, 2, 3, 6, 5, 4, 7, 8, 9)); + init(); + heapEmptyParentSmaller.buildHeap(worstCaseList); + t.checkExpect(this.heapEmptyParentSmaller.heap, worstDownList); + } + void testAdd(Tester t) { + init(); + ArrayList addedList_90 = new ArrayList( + Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50, 90)); + ArrayList addedList_9005 = new ArrayList( + Arrays.asList(5, 20, 10, 30, 50, 15, 20, 80, 60, 50, 90, 40)); + this.heapPopulatedParentSmaller.add(90); + t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_90); + this.heapPopulatedParentSmaller.add(5); + t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_9005); + } + void testRemove(Tester t) { + init(); + t.checkExpect(this.heapPopulatedParentSmaller.remove(), 10); + ArrayList removedList = new ArrayList( + Arrays.asList(15, 20, 20, 30, 50, 40, 50, 80, 60)); + t.checkExpect(this.heapPopulatedParentSmaller.heap, removedList); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project new file mode 100644 index 0000000..4bbb79a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project @@ -0,0 +1,17 @@ + + + Lect32_SpanningTrees + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java new file mode 100644 index 0000000..32b2b20 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java @@ -0,0 +1,126 @@ +import java.util.Deque; +import java.util.ArrayDeque; +import java.util.ArrayList; + +// Represents a mutable collection of items +interface ICollection { + // Is this collection empty? + boolean isEmpty(); + // EFFECT: adds the item to the collection + void add(T item); + // Returns the first item of the collection + // EFFECT: removes that first item + T remove(); +} + +// first in first out +class Stack implements ICollection { + Deque contents; + Stack() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addFirst(item); + } +} + +// last in last out +class Queue implements ICollection { + Deque contents; + Queue() { + this.contents = new ArrayDeque(); + } + public boolean isEmpty() { + return this.contents.isEmpty(); + } + public T remove() { + return this.contents.removeLast(); + } + public void add(T item) { + this.contents.addLast(item); // NOTE: Different from Stack! + } +} + +// highest priority out +class PriorityQueue implements ICollection { + ArrayList heap; + IComparator comp; + PriorityQueue(ArrayList inputList, IComparator comp) { + this.comp = comp; + buildHeap(inputList); + } + PriorityQueue(IComparator comp) { + this(new ArrayList(), comp); + } + void buildHeap(ArrayList inputList) { + this.heap = inputList; + for (int i = inputList.size() - 1; i >= 0; i--) { + this.downHeap(i); + } + } + // swaps the parent and child items + void swap(int parentIndex, int childIndex) { + T temp = heap.get(parentIndex); + heap.set(parentIndex, heap.get(childIndex)); + heap.set(childIndex, temp); + } + // recursively uses comp to compare child with parent + // and swaps if child is higher priority + void upHeap(int childIndex) { + int parentIndex = (childIndex - 1) / 2; + // comp will return >0 if left has higher priority than right + // ergo swap when comp returns <0 + if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) { + this.swap(parentIndex, childIndex); + this.upHeap(parentIndex); + } + } + // recursively uses comp to compare parent with children + // and swaps if child is higher priority + void downHeap(int parentIndex) { + this.downHeapMaxDepth(parentIndex, this.heap.size()); + } + void downHeapMaxDepth(int parentIndex, int maxDepthIndex) { + int leftChildIndex = 2 * parentIndex + 1; + int rightChildIndex = 2 * parentIndex + 2; + if (rightChildIndex < maxDepthIndex) { + if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) { + if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) { + this.swap(parentIndex, leftChildIndex); + this.downHeapMaxDepth(leftChildIndex, maxDepthIndex); + } + } else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) { + this.swap(parentIndex, rightChildIndex); + this.downHeapMaxDepth(rightChildIndex, maxDepthIndex); + } + } else if (leftChildIndex < maxDepthIndex) { + if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) { + this.swap(parentIndex, leftChildIndex); + this.downHeapMaxDepth(leftChildIndex, maxDepthIndex); + } + } + } + + // Interface methods + public boolean isEmpty() { + return this.heap.isEmpty(); + } + public void add(T item) { + this.heap.add(item); + this.upHeap(heap.size() - 1); + } + public T remove() { + int lastIndex = this.heap.size() - 1; + this.swap(0, lastIndex); + T response = this.heap.remove(lastIndex); + this.downHeap(0); + return response; + } + +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java new file mode 100644 index 0000000..773243e --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java @@ -0,0 +1,44 @@ +interface IPred { + boolean apply(T t); +} + +interface IFunc { + R apply(A arg); +} + +interface IFunc2 { + R apply(A1 arg1, A2 arg2); +} + +interface IComparator { + // Returns a negative number if t1 priority is less than t2 priority==- + int compare(T t1, T t2); +} + +class ParentLargerInteger implements IComparator { + // returns true (>0) if left has higher priority (larger int) + public int compare(Integer left, Integer right) { + return left - right; + } +} + +class ParentSmallerInteger implements IComparator { + // returns true (>0) if left has a higher priority (smaller int) + public int compare(Integer left, Integer right) { + return right - left; + } +} + +class ParentLargerEdge implements IComparator { + // returns true (>0) if left edge has a higher priority (lower weight) + public int compare(Edge left, Edge right) { + return left.weight - right.weight; + } +} + +class ParentSmallerEdge implements IComparator { + // returns true (>0) if left edge has a higher priority (higher weight) + public int compare(Edge left, Edge right) { + return right.weight - left.weight; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java new file mode 100644 index 0000000..bda801f --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java @@ -0,0 +1,142 @@ +import java.util.ArrayList; +import java.util.Arrays; +import tester.Tester; + +class PQExamples { + ArrayList unsortedList; + ArrayList upHeapedList; + ArrayList downHeapedList; + ArrayList sortedList; + ArrayList worstCaseList; + + PriorityQueue heapEmptyParentSmaller; + PriorityQueue heapPopulatedParentSmaller; + PriorityQueue heapGreaterTop; + + IComparator compParentGreater; + IComparator compParentSmaller; + + void init() { + unsortedList = new ArrayList( + Arrays.asList(10, 60, 15, 30, 50, 40, 20, 80, 20, 50)); + downHeapedList = new ArrayList( + Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50)); + upHeapedList = new ArrayList( + Arrays.asList(80, 60, 40, 50, 50, 15, 20, 10, 20, 30)); + worstCaseList = new ArrayList( + Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1)); + + compParentGreater = new ParentLargerInteger(); + compParentSmaller = new ParentSmallerInteger(); + heapEmptyParentSmaller = new PriorityQueue(compParentSmaller); + heapPopulatedParentSmaller = new PriorityQueue(unsortedList, compParentSmaller); + } + void testSwap(Tester t) { + init(); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(10); + heapEmptyParentSmaller.heap.add(20); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 20); + heapEmptyParentSmaller.swap(0, 1); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 20); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 10); + } + void testUpHeap(Tester t) { + init(); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(0); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 1); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 20); + heapEmptyParentSmaller.heap.add(10); + heapEmptyParentSmaller.upHeap(1); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 2); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + heapEmptyParentSmaller.heap.add(30); + heapEmptyParentSmaller.upHeap(2); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 3); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(3); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 4); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30); + t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(4); + heapEmptyParentSmaller.heap.add(20); + heapEmptyParentSmaller.upHeap(5); + t.checkExpect(heapEmptyParentSmaller.heap.size(), 6); + t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10); + t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(2), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(4), 20); + t.checkExpect(heapEmptyParentSmaller.heap.get(5), 30); + } + void testDownHeap(Tester t) { + init(); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0); + heapEmptyParentSmaller.heap.add(0, 50); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 1); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 50); + heapEmptyParentSmaller.heap.add(0, 40); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50); + heapEmptyParentSmaller.heap.add(0, 60); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 50); + heapEmptyParentSmaller.heap.add(0, 30); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 50); + heapEmptyParentSmaller.heap.add(0, 70); + heapEmptyParentSmaller.downHeap(0); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 40); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 60); + t.checkExpect(this.heapEmptyParentSmaller.heap.get(4), 70); + } + void testBuildDownHeap(Tester t) { + init(); + heapEmptyParentSmaller.buildHeap(unsortedList); + t.checkExpect(heapEmptyParentSmaller.heap, downHeapedList); + ArrayList worstDownList = new ArrayList(Arrays.asList( + 1, 2, 3, 6, 5, 4, 7, 8, 9)); + init(); + heapEmptyParentSmaller.buildHeap(worstCaseList); + t.checkExpect(this.heapEmptyParentSmaller.heap, worstDownList); + } + void testAdd(Tester t) { + init(); + ArrayList addedList_90 = new ArrayList( + Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50, 90)); + ArrayList addedList_9005 = new ArrayList( + Arrays.asList(5, 20, 10, 30, 50, 15, 20, 80, 60, 50, 90, 40)); + this.heapPopulatedParentSmaller.add(90); + t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_90); + this.heapPopulatedParentSmaller.add(5); + t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_9005); + } + void testRemove(Tester t) { + init(); + t.checkExpect(this.heapPopulatedParentSmaller.remove(), 10); + ArrayList removedList = new ArrayList( + Arrays.asList(15, 20, 20, 30, 50, 40, 50, 80, 60)); + t.checkExpect(this.heapPopulatedParentSmaller.heap, removedList); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java new file mode 100644 index 0000000..940db97 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java @@ -0,0 +1,160 @@ +import java.util.ArrayList; +import java.util.HashMap; + +class Util { + Util() {} + + boolean isOneTree(ArrayList vertices, HashMap setMap) { + // this seems wildly inefficient but it works + for (Vertex v0 : vertices) { + for (Vertex v1 : vertices) { + if (!this.sameTree(v0.name, v1.name, setMap)) { + return false; + } + } + } + return true; + } + boolean sameTree(String k1, String k2, HashMap setMap) { + return this.getStump(k1, setMap).equals(this.getStump(k2, setMap)); + // if (setMap.get(k1).equals(setMap.get(k2))) { + // // easy answer + // return true; + // } else if (setMap.get(k1).equals(k1) && + // setMap.get(k2).equals(k2)) { + // // if both nodes are part of their own sets they cannot be part + // // of the same set + // return false; + // } else { + // // run up the tree to see if it ends in the same tree + // // i can climb both sides here because when we get to a stump + // // the self reference will by definition create a loop that will + // // be broken by conditional above + // return sameTree(setMap.get(k1), setMap.get(k2), setMap); + // } + } + String getStump(String nodeName, HashMap setMap) { + String nodeSet = setMap.get(nodeName); + if (nodeName.equals(nodeSet)) { + return nodeSet; + } else { + return getStump(nodeSet, setMap); + } + } + void union(HashMap setMap, String k1, String k2) { + if (setMap.get(k2).equals(k2)) { + // if k2 is stump of tree change to k1 + setMap.put(k2, this.getStump(k1, setMap)); + } else { + // go up the tree to change stump's set to k1 + this.union(setMap, k1, setMap.get(k2)); + } + } +} + +class Vertex { + String name; + ArrayList outEdges; + Vertex(String name, ArrayList outEdges) { + this.name = name; + this.outEdges = outEdges; + } + Vertex(String name) { + this(name, new ArrayList()); + } + void addEdge(Edge e) { + this.outEdges.add(e); + } +} + +class Edge { + String name; + Vertex from, to; + int weight; + Edge(String name, Vertex from, Vertex to, int weight) { + this.name = name; + this.from = from; + this.to = to; + this.weight = weight; + to.addEdge(this); + from.addEdge(this); + } + Edge(Vertex from, Vertex to, int weight) { + this("", from, to, weight); + } + Edge(Vertex from, Vertex to) { + this("", from, to, 0); + } +} + +class Graph { + ArrayList vertices; + Graph(ArrayList vertices) { + this.vertices = vertices; + } + + ArrayList makePrimTree() { + // The final resulting tree + ArrayList tree = new ArrayList(); + // The set of connected vertices + HashMap connected = new HashMap(); + // The priority queue of candidate edges + PriorityQueue frontier = new PriorityQueue(new ParentSmallerEdge()); + + if (!this.vertices.equals(null)) { + for (Vertex v : vertices) { + connected.put(v, false); + } + Vertex first = vertices.get(0); + for (Edge e : first.outEdges) { + frontier.add(e); + } + connected.put(first, true); + while (!frontier.isEmpty()) { + Edge lowestCostEdge = frontier.remove(); + if (connected.get(lowestCostEdge.from) && connected.get(lowestCostEdge.to)) { + // if both vertices are connected do nothing + } else if (!connected.get(lowestCostEdge.from)) { + tree.add(lowestCostEdge); + connected.put(lowestCostEdge.from, true); + for (Edge e : lowestCostEdge.from.outEdges) { + frontier.add(e); + } + } else { + tree.add(lowestCostEdge); + connected.put(lowestCostEdge.to, true); + for (Edge e : lowestCostEdge.to.outEdges) { + frontier.add(e); + } + } + } + } + return tree; + } + ArrayList makeKruskalTree() { + HashMap setMap = new HashMap();; + ArrayList tree = new ArrayList(); + PriorityQueue worklist = new PriorityQueue(new ParentSmallerEdge()); + + for (Vertex v : this.vertices) { + // initialize every node's representative to itself + setMap.put(v.name, v.name); + for (Edge e : v.outEdges) { + // all edges in graph, sorted by edge weights + worklist.add(e); + } + } + Util u = new Util(); + while (!u.isOneTree(this.vertices, setMap)) { + Edge lowestCostEdge = worklist.remove(); + if (u.sameTree(lowestCostEdge.from.name, lowestCostEdge.to.name, setMap)) { + // discard this edge + // they're already connected + } else { + tree.add(lowestCostEdge); + u.union(setMap, lowestCostEdge.to.name, lowestCostEdge.from.name); + } + } + return tree; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/TreeExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/TreeExamples.java new file mode 100644 index 0000000..baa42c6 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/TreeExamples.java @@ -0,0 +1,59 @@ +import java.util.Arrays; +import tester.Tester; +import java.util.ArrayList; + +class Examples { + Vertex a; + Vertex b; + Vertex c; + Vertex d; + Vertex e; + Vertex f; + Edge ab; + Edge ae; + Edge bc; + Edge be; + Edge bf; + Edge cd; + Edge ce; + Edge df; + + Graph graph0; + Graph graph1; + + void init() { + a = new Vertex("A"); + b = new Vertex("B"); + c = new Vertex("C"); + d = new Vertex("D"); + e = new Vertex("E"); + f = new Vertex("F"); + ab = new Edge("AB", a, b, 30); + ae = new Edge("AE", a, e, 50); + bc = new Edge("BC", b, c, 40); + be = new Edge("BE", b, e, 35); + bf = new Edge("BF", b, f, 50); + cd = new Edge("CD", c, d, 25); + ce = new Edge("CE", c, e, 15); + df = new Edge("DF", d, f, 50); + + graph1 = new Graph(new ArrayList(Arrays.asList(a, b, c, d, e, f))); + } + + void testMakePrimTree(Tester t) { + init(); + t.checkExpect(this.graph1.makePrimTree(), new ArrayList(Arrays.asList( + ab, be, ce, cd, bf))); + ae.weight = 1; + t.checkExpect(this.graph1.makePrimTree(), new ArrayList(Arrays.asList( + ae, ce, cd, ab, bf))); + } + void testMakeKruskalsTree(Tester t) { + init(); + t.checkExpect(this.graph1.makeKruskalTree(), new ArrayList(Arrays.asList( + ce, cd, ab, be, df))); + ae.weight = 1; + t.checkExpect(this.graph1.makeKruskalTree(), new ArrayList(Arrays.asList( + ae, ce, cd, ab, df))); + } +}