From 4c9829f9ecc9a6c1f37c2e7f5accb951c3f8130f Mon Sep 17 00:00:00 2001 From: Schankula Christopher <schankuc@mcmaster.ca> Date: Sun, 1 Apr 2018 17:12:21 -0400 Subject: [PATCH] add more infrastructure to Director for future methods, more info sent to client in histogram.jsp --- src/sort/KDT.java | 72 ++++++++++++++++++++++++++---- src/sort/QuickSelect.java | 4 +- src/web/Director.java | 5 ++- tomcat/webapps/Trawl/histogram.jsp | 11 ++--- 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/sort/KDT.java b/src/sort/KDT.java index 681deb7..1ee1043 100644 --- a/src/sort/KDT.java +++ b/src/sort/KDT.java @@ -10,6 +10,19 @@ import java.util.ArrayList; import sandbox.Point; +/** + * A class for constructing KD-trees with range-searching abilities. Written using + * pseudocode from https://en.wikipedia.org/wiki/K-d_tree for building the tree + * and referencing several resources: + * - http://www.cs.utah.edu/~lifeifei/cs6931/kdtree.pdf + * - https://www.youtube.com/watch?v=Z4dNLvno-EY + * - http://www.cs.uu.nl/docs/vakken/ga/slides5a.pdf + * - https://www.datasciencecentral.com/profiles/blogs/implementing-kd-tree-for-fast-range-search-nearest-neighbor + * All code is original and was written by Christopher W. Schankula. + * @author Christopher W. Schankula + * + * @param <KeyVal> The type of key-value objects to insert into the tree. + */ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { /** * @@ -68,6 +81,11 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { kdt.writeToFile("kdtree.ser"); } + /** + * A node in a serializable KD-tree. + * @author Christopher W. Schankula + * + */ private class KDNode implements Serializable{ /** * @@ -80,6 +98,11 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { private KDNode left, right; private int n; + /** + * Constructor for KDNode. Creates a new KD-tree node. + * @param keyval + * @param n + */ public KDNode(KeyVal keyval, int n) { this.keyval = keyval; this.n = n; @@ -109,6 +132,13 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { this.axes = kdt.axes; } + /** + * Construct a new kd-tree from an array of nodes. + * @param axes A GeneralCompare instance for each dimension of the kd-tree. This + * GeneralCompare must input an object of type KeyVal and output an ordering correspoding + * to that axis. + * @param keyvals An array of Key-Value pairs to insert into the tree. + */ public KDT(ArrayList<GeneralCompare<KeyVal>> axes, Comparable<KeyVal>[] keyvals) { this.axes = axes; root = buildTree(keyvals, 0, keyvals.length - 1, 0); @@ -131,6 +161,13 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { return newNode; } + /** + * Perform a range search for nodes in the tree. + * @param range An ArrayList of GeneralRange instances. This must take a value of type + * KeyVal and return whether that value is in the range for the given axis. Must provide + * an ArrayList with a size equal to the current tree's number of axes, k. + * @return An Iterable of nodes found to be matchign the range search. + */ public Iterable<KeyVal> rangeSearch(ArrayList<GeneralRange<KeyVal>> range){ ArrayList<KeyVal> result = new ArrayList<KeyVal>(); rangeSearch(root, range, result, 0); @@ -166,10 +203,18 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { return true; } + /** + * Returns the number of nodes in the tree. + * @return the number of nodes present in the kd-tree. + */ public int size() { return size(root); } + /** + * The maximum depth for any node in the kd-tree. + * @return the depth of the maximum-depth node in the kd-tree. + */ public int height() { return height(root); } @@ -184,14 +229,32 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { else return x.n; } + /** + * Return the number of axes in the current kd-tree. + * @return the nubmer of axes in the current kd-tree. + */ public int getK() { return axes.size(); } + /** + * Generates and returns a string representation of the nodes in the kd-tree. + * Note: for large trees, this may be slow and unstable. + * @return a string representation of the nodes in the kd-tree. + */ public String toString() { return toString(root, ""); } + private String toString(KDNode x, String depth) { + if (x == null) return depth + "null\n"; + String result = ""; + result += depth + x.keyval.toString() + "\n"; + result += toString(x.left, depth + " "); + result += toString(x.right, depth + " "); + return result; + } + public void writeToFile(String fn) { try { FileOutputStream fileOut = @@ -205,13 +268,4 @@ public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable { i.printStackTrace(); } } - - private String toString(KDNode x, String depth) { - if (x == null) return depth + "null\n"; - String result = ""; - result += depth + x.keyval.toString() + "\n"; - result += toString(x.left, depth + " "); - result += toString(x.right, depth + " "); - return result; - } } diff --git a/src/sort/QuickSelect.java b/src/sort/QuickSelect.java index 1b7e0e3..fb073ef 100644 --- a/src/sort/QuickSelect.java +++ b/src/sort/QuickSelect.java @@ -1,7 +1,5 @@ package sort; -import search.GeneralCompare; - // Code from "Algorithms: 4th Edition" by Robert Sedgewick // Adapted from the Sedgewick Quicksort implementation @@ -37,7 +35,7 @@ public class QuickSelect { * @param gc Lambda function to compare items */ public static <T> void median(Comparable<T>[] a, int lo, int hi, GeneralCompare<T> gc) { - sort(a, lo, hi, (hi - lo) / 2, gc); + sort(a, lo, hi, (hi + lo) / 2, gc); } /** diff --git a/src/web/Director.java b/src/web/Director.java index daa81d8..2b5e4c3 100755 --- a/src/web/Director.java +++ b/src/web/Director.java @@ -18,8 +18,11 @@ public class Director extends HttpServlet { String req = getUrlDoPortion(request); if (req.equals("doBioLookup.do")) view = request.getRequestDispatcher("bioresult.jsp"); + else if (req.equals("doHist.do")) + view = request.getRequestDispatcher("histogram.jsp"); + else if (req.equals("doResult.do")) + view = request.getRequestDispatcher("result.jsp"); - //RequestDispatcher view = request.getRequestDispatcher("histogram.jsp"); view.forward(request, response); } diff --git a/tomcat/webapps/Trawl/histogram.jsp b/tomcat/webapps/Trawl/histogram.jsp index 5744844..17cb163 100644 --- a/tomcat/webapps/Trawl/histogram.jsp +++ b/tomcat/webapps/Trawl/histogram.jsp @@ -1,9 +1,9 @@ <%@ page import="java.util.*, data.Record, model.TrawlExpert, search.BST, search.BasicSearchResult" %> <%@page import="org.json.simple.JSONArray"%> +<%@page import="org.json.simple.JSONObject"%> <%@page import="org.json.simple.parser.JSONParser"%> <% - TrawlExpert te = (TrawlExpert)request.getServletContext().getAttribute("trawl"); BasicSearchResult result = te.rangeSearch(2, 1960, 2016); @@ -23,12 +23,13 @@ y.add(histogram.get(year)); } - js.put("year", x); - js.put("individualCount", y); + js.put("x", x); + js.put("y", y); + js.put("time", result.time()); + js.put("n", result.n()); + js.put("individualCount", result.sum()); out.print(js.toJSONString()); - - %> \ No newline at end of file -- GitLab