From 6b99966b5ea7094ecd1744ce0528b649f313b82d Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 20 Jun 2017 16:59:24 +0200 Subject: [PATCH] WIP: RM Estimator --- pom.xml | 64 +- src/main/java/App.java | 15 +- src/main/java/Model/Arrangement.java | 42 +- .../Model/DCEL/DoublyConnectedEdgeList.java | 231 +++-- src/main/java/Model/DCEL/Edge.java | 186 ++-- src/main/java/Model/DCEL/Face.java | 200 ++--- src/main/java/Model/DCEL/Node.java | 56 +- src/main/java/Model/Line.java | 136 +-- src/main/java/Model/Pair.java | 38 +- src/main/java/Model/Point.java | 86 +- src/main/java/Model/Slab.java | 59 +- .../java/Presenter/Algorithms/Algorithm.java | 2 - .../Algorithms/InversionCounter.java | 165 ---- .../LeastMedianOfSquaresEstimator.java | 791 +++++++++--------- .../Algorithms/RepeatedMedianEstimator.java | 293 ++++--- .../Algorithms/TheilSenEstimator.java | 1 + .../YOrderLineComparatorBegin.java | 29 + .../Comparators/YOrderLineComparatorEnd.java | 29 + src/main/java/Presenter/InversionCounter.java | 195 +++++ src/main/java/Presenter/Presenter.java | 282 ++++--- src/main/java/View/ArrangementDialog.java | 225 ++--- src/main/java/View/ArrangementDialog2.java | 136 +-- src/main/java/View/MainFrame.java | 519 ++++++------ src/main/java/View/MenuPanel.java | 41 +- src/main/java/View/OutputPanel.java | 127 +-- src/main/java/View/PlotDialog.java | 160 ++-- src/main/java/View/SidePanel.java | 173 ++-- .../Model/DoublyConnectedEdgeListTest.java | 133 ++- .../LeastMedianOfSquaresEstimatorTest.java | 155 ++-- 29 files changed, 2399 insertions(+), 2170 deletions(-) delete mode 100644 src/main/java/Presenter/Algorithms/InversionCounter.java create mode 100644 src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java create mode 100644 src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java create mode 100644 src/main/java/Presenter/InversionCounter.java diff --git a/pom.xml b/pom.xml index 75ac318..552615e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,39 +1,39 @@ - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - wwu - masterarbeit - 1.0-SNAPSHOT - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - + wwu + masterarbeit + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + - - - - org.jfree - jfreechart - 1.0.14 - + + + + org.jfree + jfreechart + 1.0.14 + - - - junit - junit - 4.12 - - + + + junit + junit + 4.12 + + \ No newline at end of file diff --git a/src/main/java/App.java b/src/main/java/App.java index 3c4f6eb..121b5b8 100644 --- a/src/main/java/App.java +++ b/src/main/java/App.java @@ -1,8 +1,7 @@ import Model.Arrangement; import Presenter.Presenter; import View.MainFrame; - -import javax.swing.*; +import javax.swing.SwingUtilities; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -14,13 +13,13 @@ import javax.swing.*; public class App { - public static void main(String[] args) { + public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - MainFrame view = new MainFrame(); - view.setPresenter(new Presenter(new Arrangement(), view)); - }); + SwingUtilities.invokeLater(() -> { + MainFrame view = new MainFrame(); + view.setPresenter(new Presenter(new Arrangement(), view)); + }); - } + } } diff --git a/src/main/java/Model/Arrangement.java b/src/main/java/Model/Arrangement.java index 2e3ce7b..7d40e44 100644 --- a/src/main/java/Model/Arrangement.java +++ b/src/main/java/Model/Arrangement.java @@ -11,33 +11,33 @@ import java.util.LinkedList; */ public class Arrangement { - private LinkedList nodes; - private LinkedList lines; + private LinkedList nodes; + private LinkedList lines; - public Arrangement() { - nodes = new LinkedList<>(); - lines = new LinkedList<>(); - } + public Arrangement() { + nodes = new LinkedList<>(); + lines = new LinkedList<>(); + } - public void addNode(Point node) { - this.nodes.add(node); - } + public void addNode(Point node) { + this.nodes.add(node); + } - public void addLine(Line line) { - this.lines.add(line); - } + public void addLine(Line line) { + this.lines.add(line); + } - public LinkedList getNodes() { - return nodes; - } + public LinkedList getNodes() { + return nodes; + } - public LinkedList getLines() { - return lines; - } + public LinkedList getLines() { + return lines; + } - public void setLines(LinkedList lines) { - this.lines = lines; - } + public void setLines(LinkedList lines) { + this.lines = lines; + } } diff --git a/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java b/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java index 33770d0..e9a9573 100644 --- a/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java +++ b/src/main/java/Model/DCEL/DoublyConnectedEdgeList.java @@ -2,7 +2,6 @@ package Model.DCEL; import Model.Point; - import java.util.LinkedList; /** @@ -14,141 +13,141 @@ import java.util.LinkedList; */ public class DoublyConnectedEdgeList { - private LinkedList nodes; - private LinkedList edges; - private LinkedList faces; + private LinkedList nodes; + private LinkedList edges; + private LinkedList faces; - public DoublyConnectedEdgeList() { - this.nodes = new LinkedList<>(); - this.edges = new LinkedList<>(); - this.faces = new LinkedList<>(); + public DoublyConnectedEdgeList() { + this.nodes = new LinkedList<>(); + this.edges = new LinkedList<>(); + this.faces = new LinkedList<>(); + } + + public Node createNode(Point point, String id) { + + Node node = new Node(); + node.setPoint(point); + node.setID(id); + + return node; + } + + public Edge createEdge(Node source, Node destination, String id) { + + Edge edge = new Edge(); + Edge twin = new Edge(); + + edge.setOrigin(source); + edge.setID(id); + edge.setTwin(twin); + twin.setOrigin(destination); + twin.setID("#" + id); + twin.setTwin(edge); + + source.setIncidentEdge(edge); + destination.setIncidentEdge(twin); + + return edge; + } + + public Face createFace(Edge outerComponent, Edge innerComponent, String id) { + + Face face = new Face(outerComponent, null); + face.setID(id); + Edge tempEdge; + + if (outerComponent != null) { + tempEdge = outerComponent; + do { + tempEdge.setIncidentFace(face); + tempEdge = tempEdge.getNext(); + } while (!tempEdge.equals(outerComponent)); } - public Node createNode(Point point, String id) { - - Node node = new Node(); - node.setPoint(point); - node.setID(id); - - return node; + if (innerComponent != null) { + LinkedList componentlist; + componentlist = face.getInnerComponents(); + componentlist.add(innerComponent); + tempEdge = innerComponent; + do { + tempEdge.setIncidentFace(face); + tempEdge = tempEdge.getNext(); + } while (!tempEdge.equals(innerComponent)); } - public Edge createEdge(Node source, Node destination, String id) { + return face; + } - Edge edge = new Edge(); - Edge twin = new Edge(); + public void createConnection(Edge edge, Edge succ) { + edge.setNext(succ); + succ.setPrev(edge); - edge.setOrigin(source); - edge.setID(id); - edge.setTwin(twin); - twin.setOrigin(destination); - twin.setID("#" + id); - twin.setTwin(edge); + edge.getTwin().setPrev(succ.getTwin()); + succ.getTwin().setNext(edge.getTwin()); + } - source.setIncidentEdge(edge); - destination.setIncidentEdge(twin); + public LinkedList getEdgesOfInnerComponents(Face face) { - return edge; + LinkedList list = new LinkedList(); + LinkedList innerComponents = face.getInnerComponents(); + Edge it; + for (Edge e : innerComponents) { + it = e; + do { + list.add(it); + //System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID()); + it = it.getNext(); + } while (it != e); } - public Face createFace(Edge outerComponent, Edge innerComponent, String id) { + return list; + } - Face face = new Face(outerComponent, null); - face.setID(id); - Edge tempEdge; + public LinkedList getEdgesOfOuterComponents(Face face) { - if (outerComponent != null) { - tempEdge = outerComponent; - do { - tempEdge.setIncidentFace(face); - tempEdge = tempEdge.getNext(); - } while (!tempEdge.equals(outerComponent)); - } + LinkedList list = new LinkedList(); + Edge it = face.getOuterComponent(); + do { + list.add(it); + //System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID()); + it = it.getNext(); + } while (it != face.getOuterComponent()); - if (innerComponent != null) { - LinkedList componentlist; - componentlist = face.getInnerComponents(); - componentlist.add(innerComponent); - tempEdge = innerComponent; - do { - tempEdge.setIncidentFace(face); - tempEdge = tempEdge.getNext(); - } while (!tempEdge.equals(innerComponent)); - } - - return face; - } - - public void createConnection(Edge edge, Edge succ) { - edge.setNext(succ); - succ.setPrev(edge); - - edge.getTwin().setPrev(succ.getTwin()); - succ.getTwin().setNext(edge.getTwin()); - } - - public LinkedList getEdgesOfInnerComponents(Face face) { - - LinkedList list = new LinkedList(); - LinkedList innerComponents = face.getInnerComponents(); - Edge it; - for (Edge e : innerComponents) { - it = e; - do { - list.add(it); - //System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID()); - it = it.getNext(); - } while (it != e); - } - - return list; - } - - public LinkedList getEdgesOfOuterComponents(Face face) { - - LinkedList list = new LinkedList(); - Edge it = face.getOuterComponent(); - do { - list.add(it); - //System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID()); - it = it.getNext(); - } while (it != face.getOuterComponent()); - - return list; - } + return list; + } - public LinkedList getConnectedEdges(Node node) { - Edge edge = node.getIncidentEdge(); - LinkedList list = new LinkedList(); - do { - list.add(edge); - edge = edge.getNext(); - } while (node != edge.getOrigin()); - return list; - } + public LinkedList getConnectedEdges(Node node) { + Edge edge = node.getIncidentEdge(); + LinkedList list = new LinkedList(); + do { + list.add(edge); + edge = edge.getNext(); + } while (node != edge.getOrigin()); + return list; + } - public LinkedList getNodes() { - return nodes; - } + public LinkedList getNodes() { + return nodes; + } - public void setNodes(LinkedList nodes) { - this.nodes = nodes; - } + public void setNodes(LinkedList nodes) { + this.nodes = nodes; + } - public LinkedList getEdges() { - return edges; - } + public LinkedList getEdges() { + return edges; + } - public void setEdges(LinkedList edges) { - this.edges = edges; - } + public void setEdges(LinkedList edges) { + this.edges = edges; + } - public LinkedList getFaces() { - return faces; - } + public LinkedList getFaces() { + return faces; + } - public void setFaces(LinkedList faces) { - this.faces = faces; - } + public void setFaces(LinkedList faces) { + this.faces = faces; + } } diff --git a/src/main/java/Model/DCEL/Edge.java b/src/main/java/Model/DCEL/Edge.java index 2bdff3e..6496326 100644 --- a/src/main/java/Model/DCEL/Edge.java +++ b/src/main/java/Model/DCEL/Edge.java @@ -9,109 +9,109 @@ package Model.DCEL; */ public class Edge { - private Node origin; - private Edge twin; - private Face incidentFace; - private Edge next; - private Edge prev; - private String id; + private Node origin; + private Edge twin; + private Face incidentFace; + private Edge next; + private Edge prev; + private String id; - public Edge() { - new Edge(null, null, null, null, null); + public Edge() { + new Edge(null, null, null, null, null); + } + + public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) { + this.origin = origin; + this.twin = twin; + this.next = next; + this.prev = prev; + this.incidentFace = incidentFace; + } + + public Node getOrigin() { + return origin; + } + + public void setOrigin(Node origin) { + this.origin = origin; + } + + public Edge getTwin() { + return twin; + } + + public void setTwin(Edge twin) { + this.twin = twin; + } + + public Face getIncidentFace() { + return incidentFace; + } + + public void setIncidentFace(Face incidentFace) { + this.incidentFace = incidentFace; + } + + public Edge getNext() { + return next; + } + + public void setNext(Edge next) { + this.next = next; + } + + public Edge getPrev() { + return prev; + } + + public void setPrev(Edge prev) { + this.prev = prev; + } + + public boolean hasNext() { + if (getNext() == null) { + return false; + } else { + return true; } - public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) { - this.origin = origin; - this.twin = twin; - this.next = next; - this.prev = prev; - this.incidentFace = incidentFace; - } + } - public Node getOrigin() { - return origin; - } + public Edge insertNode(Node node) { - public void setOrigin(Node origin) { - this.origin = origin; - } + Edge edge = new Edge(); + Edge twin = new Edge(); - public Edge getTwin() { - return twin; - } + edge.setOrigin(node); + edge.setNext(this.getNext()); + edge.setPrev(this); + edge.setTwin(twin); + edge.setIncidentFace(this.getIncidentFace()); - public void setTwin(Edge twin) { - this.twin = twin; - } + twin.setOrigin(this.getTwin().getOrigin()); + twin.setPrev(this.getTwin().getPrev()); + twin.setNext(this.getTwin()); + twin.setTwin(edge); + twin.setIncidentFace(this.getTwin().getIncidentFace()); - public Face getIncidentFace() { - return incidentFace; - } + Node twinOrigin = this.getTwin().getOrigin(); + twinOrigin.setIncidentEdge(twin); + node.setIncidentEdge(edge); - public void setIncidentFace(Face incidentFace) { - this.incidentFace = incidentFace; - } + this.getTwin().setOrigin(node); + this.getTwin().getPrev().setNext(twin); + this.getNext().setPrev(edge); + this.setNext(edge); + this.getTwin().setPrev(twin); - public Edge getNext() { - return next; - } + return edge; + } - public void setNext(Edge next) { - this.next = next; - } + public String getID() { + return this.id; + } - public Edge getPrev() { - return prev; - } - - public void setPrev(Edge prev) { - this.prev = prev; - } - - public boolean hasNext() { - if (getNext() == null) { - return false; - } else { - return true; - } - - } - - public Edge insertNode(Node node) { - - Edge edge = new Edge(); - Edge twin = new Edge(); - - edge.setOrigin(node); - edge.setNext(this.getNext()); - edge.setPrev(this); - edge.setTwin(twin); - edge.setIncidentFace(this.getIncidentFace()); - - twin.setOrigin(this.getTwin().getOrigin()); - twin.setPrev(this.getTwin().getPrev()); - twin.setNext(this.getTwin()); - twin.setTwin(edge); - twin.setIncidentFace(this.getTwin().getIncidentFace()); - - Node twinOrigin = this.getTwin().getOrigin(); - twinOrigin.setIncidentEdge(twin); - node.setIncidentEdge(edge); - - this.getTwin().setOrigin(node); - this.getTwin().getPrev().setNext(twin); - this.getNext().setPrev(edge); - this.setNext(edge); - this.getTwin().setPrev(twin); - - return edge; - } - - public String getID() { - return this.id; - } - - public void setID(String id) { - this.id = id; - } + public void setID(String id) { + this.id = id; + } } diff --git a/src/main/java/Model/DCEL/Face.java b/src/main/java/Model/DCEL/Face.java index a7035b9..7772978 100644 --- a/src/main/java/Model/DCEL/Face.java +++ b/src/main/java/Model/DCEL/Face.java @@ -11,113 +11,115 @@ import java.util.LinkedList; */ public class Face { - private LinkedList innerComponents; - private Edge outerComponent; - private String id; + private LinkedList innerComponents; + private Edge outerComponent; + private String id; + + public Face() { + this.outerComponent = null; + this.innerComponents = new LinkedList<>(); + } + + public Face(Edge outerComponent, LinkedList innerComponents) { + this.outerComponent = outerComponent; + if (innerComponents != null) { + this.innerComponents = innerComponents; + } else { + this.innerComponents = new LinkedList<>(); - public Face() { - this.outerComponent = null; - this.innerComponents = new LinkedList<>(); } - public Face(Edge outerComponent, LinkedList innerComponents) { - this.outerComponent = outerComponent; - if (innerComponents != null) { - this.innerComponents = innerComponents; - } else { - this.innerComponents = new LinkedList<>(); + } + public LinkedList getInnerComponents() { + return innerComponents; + } + + public void setInnerComponents(LinkedList innerComponents) { + this.innerComponents = innerComponents; + } + + public Edge getOuterComponent() { + return outerComponent; + } + + public void setOuterComponent(Edge outerComponent) { + this.outerComponent = outerComponent; + } + + public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) { + + if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace() + .equals(this)) { + LinkedList components = new LinkedList(); + for (Edge e : innerComponents) { + components.add(e); + } + Face face = new Face(getOuterComponent(), components); + Edge edge = new Edge(); + Edge twin = new Edge(); + + edge.setOrigin(edgeWithSameDestination.getOrigin()); + edge.setTwin(twin); + edge.setNext(edgeToMySource); + edge.setPrev(edgeWithSameDestination.getPrev()); + + twin.setOrigin(edgeToMySource.getOrigin()); + twin.setTwin(edge); + twin.setNext(edgeWithSameDestination); + twin.setPrev(edgeToMySource.getPrev()); + + Edge tempEdge = edge.getNext(); + Edge tempTwin = twin.getNext(); + //kreis umlaufen um festzustellen welche fläche kleiner ist + while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) { + tempEdge = tempEdge.getNext(); + tempTwin = tempTwin.getNext(); + } + + if (tempEdge.equals(edge)) { + setOuterComponent(twin); + twin.setIncidentFace(this); + face.setOuterComponent(edge); + } else { + setOuterComponent(edge); + edge.setIncidentFace(this); + face.setOuterComponent(twin); + } + + LinkedList bla = new LinkedList(); + Edge iterEdge = face.getOuterComponent(); + bla.add(face.getOuterComponent()); + + while (iterEdge.hasNext()) { + bla.add(iterEdge.getNext()); + iterEdge = iterEdge.getNext(); + } + + for (Edge e : face.getInnerComponents()) { + iterEdge = e; + while (iterEdge.hasNext()) { + bla.add(iterEdge.getNext()); + iterEdge = iterEdge.getNext(); } + } + for (Edge e : bla) { + e.setIncidentFace(face); + } + return face; + } else { + throw new IllegalArgumentException( + "Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!"); } - public LinkedList getInnerComponents() { - return innerComponents; - } + } - public void setInnerComponents(LinkedList innerComponents) { - this.innerComponents = innerComponents; - } + public String getID() { + return this.id; + } - public Edge getOuterComponent() { - return outerComponent; - } - - public void setOuterComponent(Edge outerComponent) { - this.outerComponent = outerComponent; - } - - public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) { - - if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace().equals(this)) { - LinkedList components = new LinkedList(); - for (Edge e : innerComponents) { - components.add(e); - } - Face face = new Face(getOuterComponent(), components); - Edge edge = new Edge(); - Edge twin = new Edge(); - - edge.setOrigin(edgeWithSameDestination.getOrigin()); - edge.setTwin(twin); - edge.setNext(edgeToMySource); - edge.setPrev(edgeWithSameDestination.getPrev()); - - twin.setOrigin(edgeToMySource.getOrigin()); - twin.setTwin(edge); - twin.setNext(edgeWithSameDestination); - twin.setPrev(edgeToMySource.getPrev()); - - Edge tempEdge = edge.getNext(); - Edge tempTwin = twin.getNext(); - //kreis umlaufen um festzustellen welche fläche kleiner ist - while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) { - tempEdge = tempEdge.getNext(); - tempTwin = tempTwin.getNext(); - } - - if (tempEdge.equals(edge)) { - setOuterComponent(twin); - twin.setIncidentFace(this); - face.setOuterComponent(edge); - } else { - setOuterComponent(edge); - edge.setIncidentFace(this); - face.setOuterComponent(twin); - } - - LinkedList bla = new LinkedList(); - Edge iterEdge = face.getOuterComponent(); - bla.add(face.getOuterComponent()); - - while (iterEdge.hasNext()) { - bla.add(iterEdge.getNext()); - iterEdge = iterEdge.getNext(); - } - - for (Edge e : face.getInnerComponents()) { - iterEdge = e; - while (iterEdge.hasNext()) { - bla.add(iterEdge.getNext()); - iterEdge = iterEdge.getNext(); - } - } - - for (Edge e : bla) { - e.setIncidentFace(face); - } - return face; - } else { - throw new IllegalArgumentException("Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!"); - } - - } - - public String getID() { - return this.id; - } - - public void setID(String id) { - this.id = id; - } + public void setID(String id) { + this.id = id; + } } diff --git a/src/main/java/Model/DCEL/Node.java b/src/main/java/Model/DCEL/Node.java index b2c0efb..028cf74 100644 --- a/src/main/java/Model/DCEL/Node.java +++ b/src/main/java/Model/DCEL/Node.java @@ -11,40 +11,40 @@ import Model.Point; */ public class Node { - private Point point; - private Edge incidentEdge; - private String id; + private Point point; + private Edge incidentEdge; + private String id; - public Node() { - new Node(null, null); - } + public Node() { + new Node(null, null); + } - public Node(Point point, Edge incidentEdge) { - this.point = point; - this.incidentEdge = incidentEdge; - } + public Node(Point point, Edge incidentEdge) { + this.point = point; + this.incidentEdge = incidentEdge; + } - public Point getPoint() { - return point; - } + public Point getPoint() { + return point; + } - public void setPoint(Point point) { - this.point = point; - } + public void setPoint(Point point) { + this.point = point; + } - public Edge getIncidentEdge() { - return incidentEdge; - } + public Edge getIncidentEdge() { + return incidentEdge; + } - public void setIncidentEdge(Edge incidentEdge) { - this.incidentEdge = incidentEdge; - } + public void setIncidentEdge(Edge incidentEdge) { + this.incidentEdge = incidentEdge; + } - public String getID() { - return this.id; - } + public String getID() { + return this.id; + } - public void setID(String id) { - this.id = id; - } + public void setID(String id) { + this.id = id; + } } diff --git a/src/main/java/Model/Line.java b/src/main/java/Model/Line.java index db9c57e..893778b 100644 --- a/src/main/java/Model/Line.java +++ b/src/main/java/Model/Line.java @@ -9,95 +9,95 @@ package Model; */ public class Line { - private double m; - private double b; + private double m; + private double b; - private double x1; - private double x2; - private double y1; - private double y2; + private double x1; + private double x2; + private double y1; + private double y2; - private String id; + private String id; - public Line(double m, double b, String id) { - this.m = m; - this.b = b; + public Line(double m, double b, String id) { + this.m = m; + this.b = b; - this.x1 = Double.MIN_VALUE; - this.y1 = (Double.MIN_VALUE * m ) + b; - this.x2 = Double.MAX_VALUE * 0.5; - this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; - this.id = id; - } + this.x1 = Double.MIN_VALUE; + this.y1 = (Double.MIN_VALUE * m) + b; + this.x2 = Double.MAX_VALUE * 0.5; + this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b; + this.id = id; + } - public Line(double m, double b) { - this.m = m; - this.b = b; + public Line(double m, double b) { + this.m = m; + this.b = b; - this.x1 = Double.MIN_VALUE; - this.y1 = (Double.MIN_VALUE * m ) + b; - this.x2 = Double.MAX_VALUE * 0.5; - this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b; - } + this.x1 = Double.MIN_VALUE; + this.y1 = (Double.MIN_VALUE * m) + b; + this.x2 = Double.MAX_VALUE * 0.5; + this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b; + } - public Line(double x1, double x2, double y1, double y2) { - this.x1 = x1; - this.x2 = x2; - this.y1 = y1; - this.y2 = y2; + public Line(double x1, double x2, double y1, double y2) { + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; - this.m = (y2 -y1)/(x2-x1); - this.b = y2 - (x2 * m); + this.m = (y2 - y1) / (x2 - x1); + this.b = y2 - (x2 * m); - } + } - public double getM() { - return m; - } + public double getM() { + return m; + } - public void setM(double m) { - this.m = m; - } + public void setM(double m) { + this.m = m; + } - public double getB() { - return b; - } + public double getB() { + return b; + } - public void setB(double b) { - this.b = b; - } + public void setB(double b) { + this.b = b; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - public double getX1() { - return x1; - } + public double getX1() { + return x1; + } - public double getX2() { - return x2; - } + public double getX2() { + return x2; + } - public double getY1() { - return y1; - } + public double getY1() { + return y1; + } - public double getY2() { - return y2; - } + public double getY2() { + return y2; + } - public void setEndPoints(double x1, double y1, double x2, double y2){ - this.x1 = x1; - this.x2 = x2; - this.y1 = y1; - this.y2 = y2; - } + public void setEndPoints(double x1, double y1, double x2, double y2) { + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + } } diff --git a/src/main/java/Model/Pair.java b/src/main/java/Model/Pair.java index 238a5e9..8a2f0f5 100644 --- a/src/main/java/Model/Pair.java +++ b/src/main/java/Model/Pair.java @@ -8,26 +8,28 @@ package Model; * @Date: 19.06.2017. */ public class Pair { - private Integer p1; - private Integer p2; - public Pair(Integer p1, Integer p2) { - this.p1 = p1; - this.p2 = p2; - } - public Integer getP1() { - return p1; - } + private Integer p1; + private Integer p2; - public void setP1(Integer p1) { - this.p1 = p1; - } + public Pair(Integer p1, Integer p2) { + this.p1 = p1; + this.p2 = p2; + } - public Integer getP2() { - return p2; - } + public Integer getP1() { + return p1; + } - public void setP2(Integer p2) { - this.p2 = p2; - } + public void setP1(Integer p1) { + this.p1 = p1; + } + + public Integer getP2() { + return p2; + } + + public void setP2(Integer p2) { + this.p2 = p2; + } } diff --git a/src/main/java/Model/Point.java b/src/main/java/Model/Point.java index 8ad0ef1..0793977 100644 --- a/src/main/java/Model/Point.java +++ b/src/main/java/Model/Point.java @@ -9,57 +9,57 @@ package Model; */ public class Point implements Comparable { - private Double x; - private Double y; - private String id; + private Double x; + private Double y; + private String id; - public Point(Double x, Double y) { - this.x = x; - this.y = y; - } + public Point(Double x, Double y) { + this.x = x; + this.y = y; + } - public Point(Double x, Double y, String id) { - this.x = x; - this.y = y; - this.id = id; - } + public Point(Double x, Double y, String id) { + this.x = x; + this.y = y; + this.id = id; + } - public Double getX() { - return x; - } + public Double getX() { + return x; + } - public void setX(Double x) { - this.x = x; - } + public void setX(Double x) { + this.x = x; + } - public Double getY() { - return y; - } + public Double getY() { + return y; + } - public void setY(Double y) { - this.y = y; - } + public void setY(Double y) { + this.y = y; + } - @Override - public int compareTo(Point o) { - if (this.getX() == o.getX()) { - if (this.getY() <= o.getY()) { - return -1; - } else { - return 1; - } - } else if (this.getX() < o.getX()) { - return -1; - } else { - return 1; - } + @Override + public int compareTo(Point o) { + if (this.getX() == o.getX()) { + if (this.getY() <= o.getY()) { + return -1; + } else { + return 1; + } + } else if (this.getX() < o.getX()) { + return -1; + } else { + return 1; } + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } } diff --git a/src/main/java/Model/Slab.java b/src/main/java/Model/Slab.java index 079aa98..44d67eb 100644 --- a/src/main/java/Model/Slab.java +++ b/src/main/java/Model/Slab.java @@ -8,43 +8,44 @@ package Model; * @Date: 16.06.2017. */ public class Slab { - private double upper; - private double lower; - private Boolean activity; - public Slab(double lower, double upper) { - this.upper = upper; - this.lower = lower; - this.activity = true; - } + private double upper; + private double lower; + private Boolean activity; - public Boolean getActivity() { - return activity; - } + public Slab(double lower, double upper) { + this.upper = upper; + this.lower = lower; + this.activity = true; + } - public void setActivity(Boolean isActive) { - this.activity = isActive; - } + public Boolean getActivity() { + return activity; + } - public double getUpper() { - return upper; - } + public void setActivity(Boolean isActive) { + this.activity = isActive; + } - public void setUpper(double upper) { - this.upper = upper; - } + public double getUpper() { + return upper; + } - public double getLower() { - return lower; - } + public void setUpper(double upper) { + this.upper = upper; + } - public void setLower(double lower) { - this.lower = lower; - } + public double getLower() { + return lower; + } - public Double getDistance(){ + public void setLower(double lower) { + this.lower = lower; + } - return Math.abs(this.upper - this.lower); - } + public Double getDistance() { + + return Math.abs(this.upper - this.lower); + } } \ No newline at end of file diff --git a/src/main/java/Presenter/Algorithms/Algorithm.java b/src/main/java/Presenter/Algorithms/Algorithm.java index 002549d..80eb110 100644 --- a/src/main/java/Presenter/Algorithms/Algorithm.java +++ b/src/main/java/Presenter/Algorithms/Algorithm.java @@ -1,7 +1,5 @@ package Presenter.Algorithms; -import java.util.Observable; - /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * diff --git a/src/main/java/Presenter/Algorithms/InversionCounter.java b/src/main/java/Presenter/Algorithms/InversionCounter.java deleted file mode 100644 index f6253a6..0000000 --- a/src/main/java/Presenter/Algorithms/InversionCounter.java +++ /dev/null @@ -1,165 +0,0 @@ -package Presenter.Algorithms; - -import Model.Line; -import Model.Pair; -import Model.Point; -import Model.Slab; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -/** - * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. - * - * @Author: Armin Wolf - * @Email: a_wolf28@uni-muenster.de - * @Date: 18.06.2017. - */ -public class InversionCounter { - - private HashMap dictionaryTO; - private HashMap dictionaryBACK; - private ArrayList substituted; - private ArrayList inversions; - - //indexieren der Punkte damit die schnittpunkte berechnet werden können - private HashMap secondaryIndex; - private ArrayList umin; - private ArrayList umax; - - - public int run(List a, List b){ - - dictionaryTO = new HashMap<>(); - dictionaryBACK = new HashMap<>(); - substituted = new ArrayList<>(); - inversions = new ArrayList<>(); - - ArrayList temp = new ArrayList<>(); - - temp.addAll(a); - - for (int i=0;i set, Slab slab){ - ArrayList listA = new ArrayList<>(); - ArrayList listB = new ArrayList<>(); - - prepareData(set, slab, listA, listB); - return run(listA, listB); - } - - - private void prepareData(List set, Slab slab, ArrayList listA, ArrayList listB){ - secondaryIndex = new HashMap<>(); - umin = new ArrayList<>(); - umax = new ArrayList<>(); - - int counter = 0; - for (Line p : set) { - //vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet - umin.add(new Point(slab.getLower() * p.getM() + p.getB(),p.getM(), counter+"")); - umax.add(new Point(slab.getUpper() * p.getM() + p.getB(),p.getM() ,counter+"")); - counter++; - } - - for (int i=0; i a, int start, int end, List aux) { - if (start >= end) { - return 0; - } - int invCount = 0; - int mid = start + (end - start) / 2; - int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer - int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer - invCount += (invCountLeft + invCountRight); - for (int i = start; i <= end; i++) { - aux.set(i, a.get(i)); - } - int left = start; - int right = mid + 1; - int index = start; - while (left <= mid && right <= end) { - if (aux.get(left) < aux.get(right)) { - a.set(index++, aux.get(left++)); - } else { - - for (int i=left; i<=mid;i++){ - // System.out.println(aux.get(i)+" -- "+ aux.get(right)); - inversions.add(new Pair(aux.get(i), aux.get(right))); - } - a.set(index++, aux.get(right++)); - invCount += mid - left + 1; // number of inversions for aux[right] - } - } - while (left <= mid) { - a.set(index++, aux.get(left++)); - } - // no need to copy over remaining aux[right++] because they are already inside a - return invCount; - } - - - public ArrayList getInversionPairs(){ - ArrayList result = new ArrayList<>(); - - for (int i=0;i " + p.getP2()); - //} - - - return result; - } - -} diff --git a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java index 00c30a5..18a47d3 100644 --- a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java +++ b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java @@ -3,10 +3,15 @@ package Presenter.Algorithms; import Model.Line; import Model.Point; import Model.Slab; +import Presenter.InversionCounter; import Presenter.Presenter; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; import java.util.Observable; +import java.util.PriorityQueue; +import java.util.Random; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -18,432 +23,440 @@ import java.util.Observable; public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm { - private Presenter presenter; + private Presenter presenter; - private LinkedList set = new LinkedList<>(); - private LinkedList intersections = new LinkedList<>(); - private InversionCounter invCounter = new InversionCounter(); - private int n; - private double quantileError; - private int kPlus; - private int kMinus; - private PriorityQueue slabs; - private Slab subSlabU1; - private Slab subSlabU2; - private Line sigmaMin; - private double heightsigmaMin; - private Double intersectionsPoint; - private Double constant; + private LinkedList set = new LinkedList<>(); + private LinkedList intersections = new LinkedList<>(); + private InversionCounter invCounter = new InversionCounter(); + private int n; + private double quantileError; + private int kPlus; + private int kMinus; + private PriorityQueue slabs; + private Slab subSlabU1; + private Slab subSlabU2; + private Line sigmaMin; + private double heightsigmaMin; + private Double intersectionsPoint; + private Double constant; - public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections, Presenter presenter) { - this.set = set; - this.intersections = intersections; + public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections, + Presenter presenter) { + this.set = set; + this.intersections = intersections; - //(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);.... - n = set.size(); - double quantile = 0.5; - double qPlus = quantile; - quantileError = 0.1; - double qMinus = qPlus * (1 - quantileError); - kMinus = (int) Math.ceil(n * qMinus); - kPlus = (int) Math.ceil(n * qPlus); - this.presenter = presenter; - } + //(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);.... + n = set.size(); + double quantile = 0.5; + double qPlus = quantile; + quantileError = 0.1; + double qMinus = qPlus * (1 - quantileError); + kMinus = (int) Math.ceil(n * qMinus); + kPlus = (int) Math.ceil(n * qPlus); + this.presenter = presenter; + } - public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections) { - this(set, intersections, null); - } + public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections) { + this(set, intersections, null); + } - /** - * - */ - public void run() { + /** + * + */ + public void run() { - - //(2.) Let U <- (-inf, inf) be the initial active slabs... - Comparator comparator = new Comparator() { - @Override - public int compare(Slab o1, Slab o2) { - if (o1.getDistance() < o2.getDistance()) - return -1; - if (o1.getDistance() > o2.getDistance()) - return 1; - else - return 0; - } - }; - slabs = new PriorityQueue<>(comparator); - slabs.add(new Slab(-100000, 100000)); - heightsigmaMin = Double.MAX_VALUE; - LinkedList tmpIntersections = intersections; - - //(3.) Apply the following steps as long as the exists active slabs - boolean active = true; - Slab slab; - while (!this.slabs.isEmpty()) { - slab = this.slabs.peek(); - if (slab.getActivity()){ - //(a.) Select any active Slab and calc. the inversions - int numberOfIntersections = countInversions(slab); - - //(b.) apply plane sweep - if ((constant * n) >= numberOfIntersections) { - sigmaMin = planeSweep(slab); - } else { - //(c.) otherwise.... - // get random intersections point... - Collections.shuffle(tmpIntersections, new Random()); - for (int i=0;i slab.getLower() && tmpIntersections.get(i).getX() < slab.getUpper()) { - intersectionsPoint = tmpIntersections.get(i).getX(); - break; - } else { - intersectionsPoint = null; - } - } - - if (intersectionsPoint != null){ - splitActiveSlab(intersectionsPoint, slab); - //(d.) this may update sigma min - upperBound(intersectionsPoint); - //(e.) for i={1,2}, call lower bound(Ui) - lowerBound(subSlabU1); - lowerBound(subSlabU2); - - if (subSlabU1.getActivity()){ - this.slabs.add(subSlabU1); - } - if (subSlabU2.getActivity()){ - this.slabs.add(subSlabU2); - } - - } else { - this.slabs.poll(); - } - } - - - } else { - this.slabs.remove(slab); - } + //(2.) Let U <- (-inf, inf) be the initial active slabs... + Comparator comparator = new Comparator() { + @Override + public int compare(Slab o1, Slab o2) { + if (o1.getDistance() < o2.getDistance()) { + return -1; } - if (presenter != null){ - setChanged(); - double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5; - double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5; - notifyObservers(new Line(m,b)); - } - } - - /** - * @param slab - * @return - */ - public int countInversions(Slab slab) { - - int numberOfInversions = 0; - // debug - //for (int i=0;i xQueue = new ArrayList<>(); - for (Point point : intersections) { - if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { - xQueue.add(point); - } - } - Collections.sort(xQueue); - - - Line bracelet = sigmaMin; - double heightOfBracelet = heightsigmaMin; - - for (Point current : xQueue){ - Double[] currentBracelet = calcKMinusBracelet(current, kMinus); - - if (currentBracelet == null){ - continue; - } else if (currentBracelet[0] < heightOfBracelet){ - heightOfBracelet = currentBracelet[0]; - bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]); - } - } - - slab.setActivity(false); - return bracelet; - } - - /** - * Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs erzeugt. - * @param point x Koordinate an der, der Split geschieht. - */ - public void splitActiveSlab(double point, Slab active) { - subSlabU1 = new Slab(active.getLower()+0.01, point); - subSlabU2 = new Slab(point, active.getUpper()); - - this.slabs.remove(active); - } - - /** - * - * @param point - */ - public void upperBound(double point) { - - double height = heightsigmaMin; - double tmpHeight; - ArrayList sortedLineSequence = getEjValues(point); - - - int itnbr = ((n - kMinus) + 1); - for (int i = 0; i < itnbr; i++) { - tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i); - if (tmpHeight < height){ - height = tmpHeight; - } - - if (height < heightsigmaMin) { - heightsigmaMin = height; - if (sigmaMin != null){ - sigmaMin.setEndPoints(point, sortedLineSequence.get(i) - ,point, sortedLineSequence.get((i + kMinus) - 1)); - } else { - sigmaMin = new Line(point, point, sortedLineSequence.get(i), sortedLineSequence.get((i + kMinus) - 1)); - } - } - } - - } - - /** - * @param pslab - * @return - */ - public void lowerBound(Slab pslab) { - - int[] alpha = new int[n]; - int[] beta = new int[n]; - int strictlyGreater = 0; - - //Teil I. - ArrayList umaxList; - ArrayList uminList; - - //y koordinaten der Schnittpunkte - ArrayList lines = new ArrayList<>(); - for (Line p : set) { - lines.add(new Line(pslab.getLower(), pslab.getUpper(),((pslab.getLower() * p.getM()) + p.getB()), ((pslab.getUpper() * p.getM()) + p.getB()))); - } - - umaxList = getEjValues(pslab.getUpper()); - uminList = getEjValues(pslab.getLower()); - - for (int i = 0; i < n; i++) { - Line level = new Line(pslab.getLower(),pslab.getUpper(),uminList.get(i), umaxList.get(i)); - for (Line line : lines) { - if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) { - alpha[i]++; - } - - if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) { - strictlyGreater++; - } - } - beta[i] = n - (alpha[i] + strictlyGreater); - strictlyGreater = 0; - } - //TEST der Alpha und Beta werte, siehe JUnit Test - //for (int i=0;i= n) { - //System.out.println("i: "+i+", j:"+j+". ungültig"); - pslab.setActivity(false); - break; - } else { - h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)), Math.abs(umaxList.get(j) - umaxList.get(i))); - double error = 0.01; - if (((1 + error) * h) < heightsigmaMin) { - //System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin); - pslab.setActivity(true); - return; - } - } - i = 0; - } - - } - - /** - * Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte als e_j Werte - * bekannt. - * - * @param u vertikale Gerade - * @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben) - */ - public ArrayList getEjValues(double u) { - - ArrayList ret = new ArrayList<>(); - - for (Line p : set) { - ret.add((p.getM() * u) + p.getB()); - } - - Collections.sort(ret); - - return ret; - } - - /** - * Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus Bracelet. - * Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus Geraden schneidet - * und dabei minimal ist. - * @param px Koordinate um die "vertikale Gerade" zu simulieren. - * @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1) - */ - public Double[] calcKMinusBracelet(Point px, int kMinusValue) { - - //y Koordinaten für das kMinus brecalet - LinkedList intersections = new LinkedList<>(); - for (Line line : set) { - intersections.add((px.getX() * line.getM())+line.getB()); - } - if (intersections.size() >= kMinusValue){ - Collections.sort(intersections); - double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1)); - Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)}; - return ret; + if (o1.getDistance() > o2.getDistance()) { + return 1; } else { - return null; + return 0; + } + } + }; + slabs = new PriorityQueue<>(comparator); + slabs.add(new Slab(-100000, 100000)); + heightsigmaMin = Double.MAX_VALUE; + LinkedList tmpIntersections = intersections; + + //(3.) Apply the following steps as long as the exists active slabs + boolean active = true; + Slab slab; + while (!this.slabs.isEmpty()) { + slab = this.slabs.peek(); + if (slab.getActivity()) { + //(a.) Select any active Slab and calc. the inversions + int numberOfIntersections = countInversions(slab); + + //(b.) apply plane sweep + if ((constant * n) >= numberOfIntersections) { + sigmaMin = planeSweep(slab); + } else { + //(c.) otherwise.... + // get random intersections point... + Collections.shuffle(tmpIntersections, new Random()); + for (int i = 0; i < tmpIntersections.size(); i++) { + if (tmpIntersections.get(i).getX() > slab.getLower() + && tmpIntersections.get(i).getX() < slab.getUpper()) { + intersectionsPoint = tmpIntersections.get(i).getX(); + break; + } else { + intersectionsPoint = null; + } + } + + if (intersectionsPoint != null) { + splitActiveSlab(intersectionsPoint, slab); + //(d.) this may update sigma min + upperBound(intersectionsPoint); + //(e.) for i={1,2}, call lower bound(Ui) + lowerBound(subSlabU1); + lowerBound(subSlabU2); + + if (subSlabU1.getActivity()) { + this.slabs.add(subSlabU1); + } + if (subSlabU2.getActivity()) { + this.slabs.add(subSlabU2); + } + + } else { + this.slabs.poll(); + } } + + } else { + this.slabs.remove(slab); + } + } + if (presenter != null) { + setChanged(); + double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5; + double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5; + notifyObservers(new Line(m, b)); + } + } + + /** + * @param slab + * @return + */ + public int countInversions(Slab slab) { + + int numberOfInversions = 0; + // debug + //for (int i=0;i xQueue = new ArrayList<>(); + for (Point point : intersections) { + if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { + xQueue.add(point); + } + } + Collections.sort(xQueue); + + Line bracelet = sigmaMin; + double heightOfBracelet = heightsigmaMin; + + for (Point current : xQueue) { + Double[] currentBracelet = calcKMinusBracelet(current, kMinus); + + if (currentBracelet == null) { + continue; + } else if (currentBracelet[0] < heightOfBracelet) { + heightOfBracelet = currentBracelet[0]; + bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]); + } } - /** - * Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den JUnit Testfällen. - */ + slab.setActivity(false); + return bracelet; + } - public LinkedList getSet() { - return set; + /** + * Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs + * erzeugt. + * + * @param point x Koordinate an der, der Split geschieht. + */ + public void splitActiveSlab(double point, Slab active) { + subSlabU1 = new Slab(active.getLower() + 0.01, point); + subSlabU2 = new Slab(point, active.getUpper()); + + this.slabs.remove(active); + } + + /** + * + * @param point + */ + public void upperBound(double point) { + + double height = heightsigmaMin; + double tmpHeight; + ArrayList sortedLineSequence = getEjValues(point); + + int itnbr = ((n - kMinus) + 1); + for (int i = 0; i < itnbr; i++) { + tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i); + if (tmpHeight < height) { + height = tmpHeight; + } + + if (height < heightsigmaMin) { + heightsigmaMin = height; + if (sigmaMin != null) { + sigmaMin.setEndPoints(point, sortedLineSequence.get(i) + , point, sortedLineSequence.get((i + kMinus) - 1)); + } else { + sigmaMin = new Line(point, point, sortedLineSequence.get(i), + sortedLineSequence.get((i + kMinus) - 1)); + } + } } - public void setSet(LinkedList set) { - this.set = set; + } + + /** + * @param pslab + * @return + */ + public void lowerBound(Slab pslab) { + + int[] alpha = new int[n]; + int[] beta = new int[n]; + int strictlyGreater = 0; + + //Teil I. + ArrayList umaxList; + ArrayList uminList; + + //y koordinaten der Schnittpunkte + ArrayList lines = new ArrayList<>(); + for (Line p : set) { + lines.add( + new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()), + ((pslab.getUpper() * p.getM()) + p.getB()))); } - public LinkedList getIntersections() { - return intersections; + umaxList = getEjValues(pslab.getUpper()); + uminList = getEjValues(pslab.getLower()); + + for (int i = 0; i < n; i++) { + Line level = new Line(pslab.getLower(), pslab.getUpper(), uminList.get(i), umaxList.get(i)); + for (Line line : lines) { + if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) { + alpha[i]++; + } + + if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) { + strictlyGreater++; + } + } + beta[i] = n - (alpha[i] + strictlyGreater); + strictlyGreater = 0; + } + //TEST der Alpha und Beta werte, siehe JUnit Test + //for (int i=0;i= n) { + //System.out.println("i: "+i+", j:"+j+". ungültig"); + pslab.setActivity(false); + break; + } else { + h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)), + Math.abs(umaxList.get(j) - umaxList.get(i))); + double error = 0.01; + if (((1 + error) * h) < heightsigmaMin) { + //System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin); + pslab.setActivity(true); + return; + } + } + i = 0; } - public void setIntersections(LinkedList intersections) { - this.intersections = intersections; + } + + /** + * Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte + * als e_j Werte bekannt. + * + * @param u vertikale Gerade + * @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben) + */ + public ArrayList getEjValues(double u) { + + ArrayList ret = new ArrayList<>(); + + for (Line p : set) { + ret.add((p.getM() * u) + p.getB()); } - public int getN() { - return n; + Collections.sort(ret); + + return ret; + } + + /** + * Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus + * Bracelet. Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus + * Geraden schneidet und dabei minimal ist. + * + * @param px Koordinate um die "vertikale Gerade" zu simulieren. + * @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1) + */ + public Double[] calcKMinusBracelet(Point px, int kMinusValue) { + + //y Koordinaten für das kMinus brecalet + LinkedList intersections = new LinkedList<>(); + for (Line line : set) { + intersections.add((px.getX() * line.getM()) + line.getB()); + } + if (intersections.size() >= kMinusValue) { + Collections.sort(intersections); + double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1)); + Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)}; + return ret; + } else { + return null; } - public void setN(int n) { - this.n = n; - } + } - public double getQuantileError() { - return quantileError; - } + /** + * Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den + * JUnit Testfällen. + */ - public void setQuantileError(double quantileError) { - this.quantileError = quantileError; - } + public LinkedList getSet() { + return set; + } - public int getkPlus() { - return kPlus; - } + public void setSet(LinkedList set) { + this.set = set; + } - public void setkPlus(int kPlus) { - this.kPlus = kPlus; - } + public LinkedList getIntersections() { + return intersections; + } - public int getkMinus() { - return kMinus; - } + public void setIntersections(LinkedList intersections) { + this.intersections = intersections; + } - public void setkMinus(int kMinus) { - this.kMinus = kMinus; - } + public int getN() { + return n; + } - public Slab getSubSlabU1() { - return subSlabU1; - } + public void setN(int n) { + this.n = n; + } - public void setSubSlabU1(Slab subSlabU1) { - this.subSlabU1 = subSlabU1; - } + public double getQuantileError() { + return quantileError; + } - public Slab getSubSlabU2() { - return subSlabU2; - } + public void setQuantileError(double quantileError) { + this.quantileError = quantileError; + } - public void setSubSlabU2(Slab subSlabU2) { - this.subSlabU2 = subSlabU2; - } + public int getkPlus() { + return kPlus; + } - public Line getSigmaMin() { - return sigmaMin; - } + public void setkPlus(int kPlus) { + this.kPlus = kPlus; + } - public void setSigmaMin(Line sigmaMin) { - this.sigmaMin = sigmaMin; - } + public int getkMinus() { + return kMinus; + } - public double getHeightsigmaMin() { - return heightsigmaMin; - } + public void setkMinus(int kMinus) { + this.kMinus = kMinus; + } - public void setHeightsigmaMin(double heightsigmaMin) { - this.heightsigmaMin = heightsigmaMin; - } + public Slab getSubSlabU1() { + return subSlabU1; + } - public double getIntersectionsPoint() { - return intersectionsPoint; - } + public void setSubSlabU1(Slab subSlabU1) { + this.subSlabU1 = subSlabU1; + } - public void setIntersectionsPoint(double intersectionsPoint) { - this.intersectionsPoint = intersectionsPoint; - } + public Slab getSubSlabU2() { + return subSlabU2; + } - public Double getConstant() { - return constant; - } + public void setSubSlabU2(Slab subSlabU2) { + this.subSlabU2 = subSlabU2; + } - public void setConstant(Double constant) { - this.constant = constant; - } + public Line getSigmaMin() { + return sigmaMin; + } + + public void setSigmaMin(Line sigmaMin) { + this.sigmaMin = sigmaMin; + } + + public double getHeightsigmaMin() { + return heightsigmaMin; + } + + public void setHeightsigmaMin(double heightsigmaMin) { + this.heightsigmaMin = heightsigmaMin; + } + + public double getIntersectionsPoint() { + return intersectionsPoint; + } + + public void setIntersectionsPoint(double intersectionsPoint) { + this.intersectionsPoint = intersectionsPoint; + } + + public Double getConstant() { + return constant; + } + + public void setConstant(Double constant) { + this.constant = constant; + } } diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java index dca5568..a7ca993 100644 --- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java +++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java @@ -1,13 +1,14 @@ package Presenter.Algorithms; import Model.Line; -import Model.Pair; import Model.Slab; - +import Presenter.InversionCounter; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedList; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -18,127 +19,225 @@ import java.util.Random; */ public class RepeatedMedianEstimator implements Algorithm { - private LinkedList set; - private Slab interval; - private InversionCounter invCounter = new InversionCounter(); + private LinkedList set; + private HashMap> linePairs; + private Slab interval; - //in der Literatur als L_i, C_i, und R_i bekannt - private Integer countLeftSlab; - private Integer countCenterSlab; - private Integer countRightSlab; + //in der Literatur als L_i, C_i, und R_i bekannt + private ArrayList countLeftSlab; + private ArrayList countCenterSlab; + private ArrayList countRightSlab; - //die Mengen L,C und R - private ArrayList linesInLeftSlab; - private ArrayList linesInCenterSlab; - private ArrayList linesInRightSlab; + //die Mengen L,C und R + private ArrayList linesInLeftSlab; + private ArrayList linesInCenterSlab; + private ArrayList linesInRightSlab; - private Double r; - private Integer n; - private Double k; - private Double kLow; - private Double kHigh; - private Double beta; + private Double r; + private Integer n; + private Double k; + private Double kLow; + private Double kHigh; + private Double beta; - private Line thetaLow; - private Line thetaHigh; + private Double thetaLow; + private Double thetaHigh; + public RepeatedMedianEstimator(LinkedList set) { + this.set = set; + interval = new Slab(-10000, 10000); + n = set.size(); + beta = 0.5; + countLeftSlab = new ArrayList<>(); + countCenterSlab = new ArrayList<>(); + countRightSlab = new ArrayList<>(); - public RepeatedMedianEstimator(LinkedList set) { - this.set = set; - interval = new Slab(-10000,10000); - n = set.size(); - beta = 1.0; - countLeftSlab = 0; - countCenterSlab = n - 1; - countRightSlab = 0; - - linesInLeftSlab = new ArrayList<>(); - linesInCenterSlab = new ArrayList<>(set); - linesInRightSlab = new ArrayList<>(); + for (int i = 0; i < n; i++) { + countLeftSlab.add(0); + countRightSlab.add(0); + countCenterSlab.add(n - 1); } - - public void run(){ - while (linesInCenterSlab.size() != 1){ - r = Math.floor(Math.pow(n, beta)); - ArrayList lines = sampleLines(linesInCenterSlab, r); - - //TODO: hier kommt der neue Ansatz vom zweiten Algorithmus hin - estimateMedianIntersectionAbscissas(lines); - - k = (Math.floor(n * 0.5) - linesInLeftSlab.size()); - computeSlabBorders(); - thetaLow = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kLow); - thetaHigh = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kHigh); - countNumberOfIntersectionsAbscissas(); - } - } + linesInLeftSlab = new ArrayList<>(); + linesInCenterSlab = new ArrayList<>(set); + linesInRightSlab = new ArrayList<>(); + linePairs = new HashMap<>(); + } + public void run() { + while (linesInCenterSlab.size() != 1) { + r = Math.floor(Math.pow(n, beta)); + ArrayList lines = sampleLines(linesInCenterSlab, r); - public void computeSlabBorders(){ - kLow = Math.max(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))-((3 * Math.sqrt(r))/(2)))); - kHigh = Math.min(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))+((3 * Math.sqrt(r))/(2)))); - } + InversionCounter invCounter = new InversionCounter(); + invCounter.run(lines, interval); - public ArrayList sampleLines(ArrayList set, Double r){ - - ArrayList sampledLines = new ArrayList<>(); - - Random random = new Random(n); - for (int i=0; i> tmpMap; + tmpMap = invCounter.getIntersectionAbscissas(); + linePairs.putAll(tmpMap); + if (tmpMap.size() > 0){ + ArrayList medianIntersections = new ArrayList<>(); + for (Line l : lines) { + medianIntersections.add(estimateMedianIntersectionAbscissas(l)); } - return sampledLines; - } + k = (Math.floor(n * 0.5) - linesInLeftSlab.size()); + computeSlabBorders(); + thetaLow = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kLow); + thetaHigh = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kHigh); - public Line randomizedSelect(ArrayList a, int start, int end, double i){ - if (start == end) - return a.get(start); - int q = randomizedPartition(a, start, end); - int tmpPivot = q - start + 1; - - if ( i == tmpPivot ){ - return a.get(q); - } else if ( i < tmpPivot ) { - return randomizedSelect(a, start, q-1, i); - } else { - return randomizedSelect(a, q+1, end, i-tmpPivot); + for (Line l : linesInCenterSlab) { + countNumberOfIntersectionsAbscissas(l); } + + contractIntervals(); + } } - public int randomizedPartition(ArrayList a, int start, int end){ - int delta = Math.abs(end - start); - Random random = new Random(delta); - int i = start + random.nextInt(); - Collections.swap(a, end, i); - return partition(a, start, end); + System.out.println( + "Ergebnis: " + linesInCenterSlab.get(0).getM() + " * x + " + linesInCenterSlab.get(0) + .getB()); + } + + + public void computeSlabBorders() { + kLow = Math + .max(1, Math.ceil(((r * k) / (linesInCenterSlab.size())) - ((3 * Math.sqrt(r)) / (2)))); + kHigh = Math + .min(r, Math.ceil(((r * k) / (linesInCenterSlab.size())) + ((3 * Math.sqrt(r)) / (2)))); + } + + public ArrayList sampleLines(ArrayList set, Double r) { + + ArrayList sampledLines = new ArrayList<>(); + + for (int i = 0; i < r; i++) { + sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, n))); } - public int partition(ArrayList a, int start, int end){ - Line x = a.get(end); - int i = start - 1; - for (int j=start; j a, int start, int end, double i) { + if (start == end) { + return a.get(start); + } + int q = randomizedPartition(a, start, end); + int tmpPivot = q - start + 1; + + if (i == tmpPivot) { + return a.get(q); + } else if (i < tmpPivot) { + return randomizedSelect(a, start, q - 1, i); + } else { + return randomizedSelect(a, q + 1, end, i - tmpPivot); + } + } + + public int randomizedPartition(ArrayList a, int start, int end) { + int delta = Math.abs(end - start); + int i = start + ThreadLocalRandom.current().nextInt(0, delta); + Collections.swap(a, end, i); + return partition(a, start, end); + } + + public int partition(ArrayList a, int start, int end) { + Double x = a.get(end); + int i = start - 1; + for (int j = start; j < end; j++) { + if (a.get(j) <= x) { + i++; + Collections.swap(a, i, j); + } + } + Collections.swap(a, i + 1, end); + return i + 1; + } + + + public void countNumberOfIntersectionsAbscissas(Line sampledLine) { + + if (linePairs.get(sampledLine) != null){ + double intersection; + Integer index = Integer.parseInt(sampledLine.getId()); + + for (Line line : linePairs.get(sampledLine)) { + intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); + + int tmpVal; + if (intersection <= thetaLow) { + tmpVal = countLeftSlab.get(index) + 1; + countLeftSlab.set(index, tmpVal); + tmpVal = countCenterSlab.get(index) - 1; + countCenterSlab.set(index, tmpVal); + } else if (intersection > thetaHigh) { + tmpVal = countRightSlab.get(index) + 1; + countRightSlab.set(index, tmpVal); + tmpVal = countCenterSlab.get(index) - 1; + countCenterSlab.set(index, tmpVal); } - Collections.swap(a, i+1, end); - return i+1; - } - public void countNumberOfIntersectionsAbscissas(){ + countCenterSlab + .set(index, Math.abs((n - 1) - (countLeftSlab.get(index) + countRightSlab.get(index)))); + } + } + } + + + public Double estimateMedianIntersectionAbscissas(Line sampledLine) { + + Integer index = Integer.parseInt(sampledLine.getId()); + ArrayList intersections = new ArrayList<>(); + double intersection; + + for (Line line : linePairs.get(sampledLine)) { + if (line != sampledLine){ + intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); + intersections.add(intersection); + } + } + + Collections.sort(intersections); + double ki = Math.floor((n - 1) / 2) - countLeftSlab.get(index); + int accessIndex = ((int) Math.floor((Math.sqrt(n) * ki) / countCenterSlab.get(index)))-1; + System.out.println(accessIndex); + + return intersections.get(accessIndex); + } + + + public void contractIntervals() { + if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size() + + linesInCenterSlab.size())) { + for (int i = 0; i < linesInCenterSlab.size(); i++) { + int maxVal = Math + .max(countLeftSlab.get(i), Math.max(countCenterSlab.get(i), countRightSlab.get(i))); + if (countLeftSlab.get(i) == maxVal) { + linesInLeftSlab.add(linesInCenterSlab.get(i)); + linesInCenterSlab.remove(i); + } + + if (countRightSlab.get(i) == maxVal) { + linesInRightSlab.add(linesInCenterSlab.get(i)); + linesInCenterSlab.remove(i); + } + } + + for (int i = 0; i < n; i++) { + countLeftSlab.set(i,0); + countRightSlab.set(i,0); + countCenterSlab.set(i,n - 1); + } + + interval.setLower(thetaLow - 0.01); + interval.setUpper(thetaHigh); } - - public void estimateMedianIntersectionAbscissas(ArrayList sampledLines){ - int inversions = invCounter.run(sampledLines, interval); - } - + } } diff --git a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java index 609aaf7..7dcfc79 100644 --- a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java +++ b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java @@ -8,4 +8,5 @@ package Presenter.Algorithms; * @Date: 28.05.2017. */ public class TheilSenEstimator implements Algorithm { + } diff --git a/src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java b/src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java new file mode 100644 index 0000000..104d959 --- /dev/null +++ b/src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java @@ -0,0 +1,29 @@ +package Presenter.Comparators; + +import Model.Line; +import java.util.Comparator; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 19.06.2017. + */ +public class YOrderLineComparatorBegin implements Comparator { + + @Override + public int compare(Line o1, Line o2) { + if (o1.getY1() == o2.getY1()) { + if (o1.getX1() <= o2.getX1()) { + return -1; + } else { + return 1; + } + } else if (o1.getY1() < o2.getY1()) { + return -1; + } else { + return 1; + } + } +} diff --git a/src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java b/src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java new file mode 100644 index 0000000..e6f3ab7 --- /dev/null +++ b/src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java @@ -0,0 +1,29 @@ +package Presenter.Comparators; + +import Model.Line; +import java.util.Comparator; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 19.06.2017. + */ +public class YOrderLineComparatorEnd implements Comparator { + + @Override + public int compare(Line o1, Line o2) { + if (o1.getY2() == o2.getY2()) { + if (o1.getX2() <= o2.getX2()) { + return -1; + } else { + return 1; + } + } else if (o1.getY2() < o2.getY2()) { + return -1; + } else { + return 1; + } + } +} diff --git a/src/main/java/Presenter/InversionCounter.java b/src/main/java/Presenter/InversionCounter.java new file mode 100644 index 0000000..e439a00 --- /dev/null +++ b/src/main/java/Presenter/InversionCounter.java @@ -0,0 +1,195 @@ +package Presenter; + +import Model.Line; +import Model.Pair; +import Model.Slab; +import Presenter.Comparators.YOrderLineComparatorBegin; +import Presenter.Comparators.YOrderLineComparatorEnd; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. + * + * @Author: Armin Wolf + * @Email: a_wolf28@uni-muenster.de + * @Date: 18.06.2017. + */ +public class InversionCounter { + + private HashMap dictionaryTO; + private HashMap dictionaryBACK; + private ArrayList substituted; + private ArrayList inversions; + private List set; + + //indexieren der Punkte damit die schnittpunkte berechnet werden können + private HashMap secondaryDictionaryTO; + private HashMap secondaryDictionaryBACK; + private ArrayList umin; + + + public int run(List a, List b) { + + dictionaryTO = new HashMap<>(); + dictionaryBACK = new HashMap<>(); + substituted = new ArrayList<>(); + inversions = new ArrayList<>(); + + ArrayList temp = new ArrayList<>(); + + temp.addAll(a); + + for (int i = 0; i < a.size(); i++) { + dictionaryTO.put(a.get(i), i + 1); + dictionaryBACK.put(i + 1, a.get(i)); + } + + for (int j = 0; j < b.size(); j++) { + substituted.add(dictionaryTO.get(b.get(j))); + } + + int ret = countInversions(substituted, 0, substituted.size() - 1, temp); + + getIntersectionAbscissas(); + + return ret; + } + + public int run(List set, Slab slab) { + ArrayList listA = new ArrayList<>(); + ArrayList listB = new ArrayList<>(); + + prepareData(set, slab, listA, listB); + return run(listA, listB); + } + + + private void prepareData(List set, Slab slab, ArrayList listA, + ArrayList listB) { + secondaryDictionaryTO = new HashMap<>(); + secondaryDictionaryBACK = new HashMap<>(); + this.set = set; + umin = new ArrayList<>(); + Line tmpLine; + + for (Line p : set) { + //vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet + tmpLine = new Line(p.getM(), p.getM(), slab.getLower() * p.getM() + p.getB(), + slab.getUpper() * p.getM() + p.getB()); + //wird benötigt um späer die Schnittpunkte ermitteln zu können + tmpLine.setB(p.getB()); + tmpLine.setM(p.getM()); + umin.add(tmpLine); + } + + for (int i = 0; i < umin.size(); i++) { + secondaryDictionaryTO.put(umin.get(i), i); + secondaryDictionaryBACK.put(i, this.set.get(i)); + } + + Collections.sort(umin, new YOrderLineComparatorBegin()); + for (Line q : umin) { + listA.add(secondaryDictionaryTO.get(q)); + } + + Collections.sort(umin, new YOrderLineComparatorEnd()); + for (Line q : umin) { + listB.add(secondaryDictionaryTO.get(q)); + } + + } + + + /** + * Angepasster Merge-Sort Algorithmus. + * Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen + * die als Groundtruth dienen. + * + * @param a Eingabefeld mit den Elementen die überprüft werden sollen. + * @param start Startpunkt des Eingabefeldes. + * @param end Endpunkt des Eingabefeldes. + * @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen. + * @return Anzahl der inversionen zwischen a und aux. + */ + public int countInversions(List a, int start, int end, List aux) { + if (start >= end) { + return 0; + } + int invCount = 0; + int mid = start + (end - start) / 2; + int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer + int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer + invCount += (invCountLeft + invCountRight); + for (int i = start; i <= end; i++) { + aux.set(i, a.get(i)); + } + int left = start; + int right = mid + 1; + int index = start; + while (left <= mid && right <= end) { + if (aux.get(left) < aux.get(right)) { + a.set(index++, aux.get(left++)); + } else { + + for (int i = left; i <= mid; i++) { + // System.out.println(aux.get(i)+" -- "+ aux.get(right)); + inversions.add(new Pair(aux.get(i), aux.get(right))); + } + a.set(index++, aux.get(right++)); + invCount += mid - left + 1; // number of inversions for aux[right] + } + } + while (left <= mid) { + a.set(index++, aux.get(left++)); + } + // no need to copy over remaining aux[right++] because they are already inside a + return invCount; + } + + + public HashMap> getIntersectionAbscissas() { + ArrayList result = new ArrayList<>(); + HashMap> ret = new HashMap<>(); + + for (int i = 0; i < inversions.size(); i++) { + result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()), + dictionaryBACK.get(inversions.get(i).getP2()))); + } + ArrayList linePairs; + + for (Pair p : result) { + Line l1 = secondaryDictionaryBACK.get(p.getP1()); + Line l2 = secondaryDictionaryBACK.get(p.getP2()); + if (ret.get(l2) == null){ + linePairs = new ArrayList<>(); + } else { + linePairs = ret.get(l2); + } + linePairs.add(l1); + ret.put(l2, linePairs); + + //Symetrie + if (ret.get(l1) == null){ + linePairs = new ArrayList<>(); + } else { + linePairs = ret.get(l1); + } + linePairs.add(l2); + ret.put(l1, linePairs); + } + +// System.out.println("----------------------------------------------------------"); +// for (Line outerLine : ret.keySet()){ +// System.out.println("Linie: "+outerLine); +// for (Line innerLine : ret.get(outerLine)){ +// System.out.println("\t\t -> "+innerLine); +// } +// } +// System.out.println("----------------------------------------------------------"); + return ret; + } + +} diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index 9d34f87..6dd2010 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -4,13 +4,13 @@ import Model.Arrangement; import Model.Line; import Model.Point; import Presenter.Algorithms.LeastMedianOfSquaresEstimator; +import Presenter.Algorithms.RepeatedMedianEstimator; import View.MainFrame; - -import javax.swing.*; import java.util.LinkedList; import java.util.List; import java.util.Observable; import java.util.Observer; +import javax.swing.SwingUtilities; /** @@ -22,166 +22,172 @@ import java.util.Observer; */ public class Presenter implements Observer { - private Arrangement model; - private MainFrame view; + private Arrangement model; + private MainFrame view; - private LeastMedianOfSquaresEstimator lms; + private LeastMedianOfSquaresEstimator lms; - private Double max; - private Double min; + private Double max; + private Double min; - public Presenter(Arrangement model, MainFrame view) { - this.model = model; - this.view = view; + public Presenter(Arrangement model, MainFrame view) { + this.model = model; + this.view = view; // Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d}; // Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d}; - Double[] x = {18d,24d,30d,34d,38d}; - Double[] y = {18d,26d,30d,40d,70d}; + Double[] x = {18d, 24d, 30d, 34d, 38d}; + Double[] y = {18d, 26d, 30d, 40d, 70d}; // Double[] x = {1d,3d,4d,5d,8d}; // Double[] y = {4d,2d,1d,0d,0d}; - view.logHeading("Duale Darstellung der Punkte als Geraden:"); - for (int j = 0; j < x.length; j++) { - Line p = new Line(x[j], y[j]); - view.log("f(x) = " + p.getM() + "x + " + p.getB()); - this.model.addLine(p); + view.logHeading("Duale Darstellung der Punkte als Geraden:"); + for (int j = 0; j < x.length; j++) { + Line p = new Line(x[j], y[j]); + p.setId(j+""); + view.log("f(x) = " + p.getM() + "x + " + p.getB()); + this.model.addLine(p); + } + + calcArrangementNodes(); + //print + List heading = new LinkedList<>(); + List> rows = new LinkedList<>(); + heading.add("X - Koordinate"); + heading.add("Y - Koordinate"); + for (Point p : model.getNodes()) { + LinkedList rowEntry = new LinkedList<>(); + rowEntry.add(p.getX().toString()); + rowEntry.add(p.getY().toString()); + rows.add(rowEntry); + } + view.logHeading("Schnittpunkte der Dualen Geraden:"); + view.createTable(heading, rows); + + + Thread t = new Thread(() -> { + RepeatedMedianEstimator rm = new RepeatedMedianEstimator(this.getLines()); + rm.run(); + }); + t.start(); + + } + + + @Override + public void update(Observable o, Object arg) { + Line result = ((Line) arg); + SwingUtilities.invokeLater(() -> { + getView().createPlot(result.getM(), result.getB()); + getView().setLmsIsComplete(true); + getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt"); + getView().log("m: " + result.getM() + "\t b: " + result.getB()); + }); + + } + + + public void startArrangementVisualization() { + view.createArrangement(); + } + + public void startScatterPlotVisualization(String[] input) { + Double constant = Double.parseDouble(input[0]); + Double error = Double.parseDouble(input[1]); + lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes(), this); + lms.setConstant(constant); + lms.setQuantileError(error); + lms.addObserver(this); + lms.run(); + } + + + public Point calcIntersection(Line a, Line b) { + Line p1 = a; + Line p2 = b; + + Double x = (p1.getB() - p2.getB()) / (p2.getM() - p1.getM()); + Double y = ((p1.getM() * p2.getB()) - (p2.getM() * p1.getB())) / (p1.getM() - p2.getM()); + + return new Point(x, y); + } + + public void calcArrangementNodes() { + try { + Thread thread = new Thread(() -> { + for (int i = 0; i < getLines().size(); i++) { + for (int j = i; j < getLines().size(); j++) { + if (i != j) { + model.addNode(calcIntersection(getLines().get(j), getLines().get(i))); + } + } } - - calcArrangementNodes(); - //print - List heading = new LinkedList<>(); - List> rows = new LinkedList<>(); - heading.add("X - Koordinate"); - heading.add("Y - Koordinate"); - for (Point p : model.getNodes()) { - LinkedList rowEntry = new LinkedList<>(); - rowEntry.add(p.getX().toString()); - rowEntry.add(p.getY().toString()); - rows.add(rowEntry); - } - view.logHeading("Schnittpunkte der Dualen Geraden:"); - view.createTable(heading, rows); - - - + }); + thread.start(); + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); } + } - @Override - public void update(Observable o, Object arg) { - Line result = ((Line) arg); - SwingUtilities.invokeLater(()->{ - getView().createPlot(result.getM(), result.getB()); - getView().setLmsIsComplete(true); - getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt"); - getView().log("m: "+result.getM()+"\t b: "+result.getB()); - }); + public LinkedList> calcArrangementLines() { + LinkedList> lineCoordinates = new LinkedList<>(); + double x1 = -1000; + double x2 = 1000; + for (Line point : model.getLines()) { + LinkedList line = new LinkedList(); + double y1 = (point.getM() * x1 + point.getB()); + double y2 = (point.getM() * x2 + point.getB()); + line.add(new Point(x1, y1)); + line.add(new Point(x2, y2)); + lineCoordinates.add(line); } + return lineCoordinates; + } - public void startArrangementVisualization() { - view.createArrangement(); - } - - public void startScatterPlotVisualization(String[] input) { - Double constant = Double.parseDouble(input[0]); - Double error = Double.parseDouble(input[1]); - lms = new LeastMedianOfSquaresEstimator(model.getLines(), model.getNodes(), this); - lms.setConstant(constant); - lms.setQuantileError(error); - lms.addObserver(this); - lms.run(); - } + /*************************************************************************************************************************** + * Getter und Setter Methoden + ***************************************************************************************************************************/ - public Point calcIntersection(Line a, Line b) { - Line p1 = a; - Line p2 = b; + public Arrangement getModel() { + return model; + } - Double x = (p1.getB() - p2.getB()) / (p2.getM() - p1.getM()); - Double y = ((p1.getM() * p2.getB()) - (p2.getM() * p1.getB())) / (p1.getM() - p2.getM()); + public void setModel(Arrangement model) { + this.model = model; + } - return new Point(x, y); - } + public MainFrame getView() { + return view; + } - public void calcArrangementNodes() { - try { - Thread thread = new Thread(() -> { - for (int i = 0; i < getLines().size(); i++) { - for (int j = i; j < getLines().size(); j++) { - if (i != j){ - model.addNode(calcIntersection(getLines().get(j), getLines().get(i))); - } - } - } - }); - thread.start(); - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + public void setView(MainFrame view) { + this.view = view; + } - } + public LinkedList getLines() { + return this.model.getLines(); + } - public LinkedList> calcArrangementLines(){ - LinkedList> lineCoordinates = new LinkedList<>(); - double x1 = -1000; - double x2 = 1000; + public void setLines(LinkedList lines) { + this.model.setLines(lines); + } + public Double getMax() { + return max; + } - for (Line point : model.getLines()) { - LinkedList line = new LinkedList(); - double y1 = (point.getM() * x1 + point.getB()); - double y2 = (point.getM() * x2 + point.getB()); - line.add(new Point(x1,y1)); - line.add(new Point(x2,y2)); - lineCoordinates.add(line); - } + public void setMax(Double max) { + this.max = max; + } - return lineCoordinates; - } - /*************************************************************************************************************************** - * Getter und Setter Methoden - ***************************************************************************************************************************/ + public Double getMin() { + return min; + } - - public Arrangement getModel() { - return model; - } - - public void setModel(Arrangement model) { - this.model = model; - } - - public MainFrame getView() { - return view; - } - - public void setView(MainFrame view) { - this.view = view; - } - - public LinkedList getLines() { - return this.model.getLines(); - } - - public void setLines(LinkedList lines) { - this.model.setLines(lines); - } - - public Double getMax() { - return max; - } - - public void setMax(Double max) { - this.max = max; - } - - public Double getMin() { - return min; - } - - public void setMin(Double min) { - this.min = min; - } + public void setMin(Double min) { + this.min = min; + } } diff --git a/src/main/java/View/ArrangementDialog.java b/src/main/java/View/ArrangementDialog.java index 9b48cd8..c6907f1 100644 --- a/src/main/java/View/ArrangementDialog.java +++ b/src/main/java/View/ArrangementDialog.java @@ -1,7 +1,15 @@ package View; -import Model.Line; import Model.Point; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.util.LinkedList; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.SwingConstants; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -13,12 +21,6 @@ import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.util.ShapeUtilities; -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.*; -import java.util.LinkedList; - /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -28,123 +30,122 @@ import java.util.LinkedList; */ public class ArrangementDialog extends JPanel { - private LinkedList> lines; - private LinkedList points; - private double max; - private double min; - private JFreeChart chart; - private ChartPanel panel; - private JSlider hslider; - private JSlider vslider; - private double domainMin, domainMax; - private double rangeMin, rangeMax; - private ValueAxis domain; - private ValueAxis range; + private LinkedList> lines; + private LinkedList points; + private double max; + private double min; + private JFreeChart chart; + private ChartPanel panel; + private JSlider hslider; + private JSlider vslider; + private double domainMin, domainMax; + private double rangeMin, rangeMax; + private ValueAxis domain; + private ValueAxis range; - public ArrangementDialog() { - super(); - this.setPreferredSize(new Dimension(800, 800)); - this.setMinimumSize(new Dimension(800, 800)); - this.setLayout(new BorderLayout()); - this.vslider = new JSlider(SwingConstants.VERTICAL,1,100,50); - this.hslider = new JSlider(SwingConstants.HORIZONTAL,10,1000,500); + public ArrangementDialog() { + super(); + this.setPreferredSize(new Dimension(800, 800)); + this.setMinimumSize(new Dimension(800, 800)); + this.setLayout(new BorderLayout()); + this.vslider = new JSlider(SwingConstants.VERTICAL, 1, 100, 50); + this.hslider = new JSlider(SwingConstants.HORIZONTAL, 10, 1000, 500); + } + + public void setPrameters(LinkedList> lines, LinkedList points) { + this.lines = lines; + this.points = points; + this.domainMin = Double.MAX_VALUE; + this.domainMax = Double.MIN_VALUE; + this.rangeMin = Double.MAX_VALUE; + this.rangeMax = Double.MIN_VALUE; + } + + public void createArrangement() { + XYSeriesCollection dataset = new XYSeriesCollection(); + + for (LinkedList p : lines) { + XYSeries series = new XYSeries(p.get(0).getX() + p.get(0).getY()); + series.add(p.get(0).getX(), p.get(0).getY()); + series.add(p.get(1).getX(), p.get(1).getY()); + dataset.addSeries(series); } - public void setPrameters(LinkedList> lines, LinkedList points) { - this.lines = lines; - this.points = points; - this.domainMin = Double.MAX_VALUE; - this.domainMax = Double.MIN_VALUE; - this.rangeMin = Double.MAX_VALUE; - this.rangeMax = Double.MIN_VALUE; + XYSeries intersections = new XYSeries("intersections"); + for (Point p : points) { + domainMax = domainMax < p.getX() ? p.getX() : domainMax; + domainMin = domainMin > p.getX() ? p.getX() : domainMin; + rangeMax = rangeMax < p.getY() ? p.getY() : rangeMax; + rangeMin = rangeMin > p.getY() ? p.getY() : rangeMin; + intersections.add(p.getX(), p.getY()); + } + dataset.addSeries(intersections); + + chart = ChartFactory.createXYLineChart( + null, null, null, dataset, + PlotOrientation.HORIZONTAL, false, false, false); + chart.setRenderingHints( + new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); + chart.setAntiAlias(true); + + final XYPlot plot = chart.getXYPlot(); + + domain = plot.getDomainAxis(); + range = plot.getRangeAxis(); + + domain.setRange(domainMin - 1, domainMax + 1); + range.setRange(rangeMin - 1, rangeMax + 1); + plot.setBackgroundPaint(Color.WHITE); + plot.setDomainGridlinePaint(Color.white); + plot.setRangeGridlinePaint(Color.white); + + final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); + renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false); + plot.setRenderer(renderer); + + for (int i = 0; i < lines.size(); i++) { + // Setze die Shapes für die Schnittpunkte + renderer.setSeriesPaint(i, Color.BLUE); + renderer.setBaseSeriesVisible(true); } - public void createArrangement() { - XYSeriesCollection dataset = new XYSeriesCollection(); + Shape shape = ShapeUtilities.createDiagonalCross(4, 1); + renderer.setSeriesPaint(lines.size(), Color.BLACK); + renderer.setSeriesShape(lines.size(), shape); - for (LinkedList p : lines) { - XYSeries series = new XYSeries(p.get(0).getX() + p.get(0).getY()); - series.add(p.get(0).getX(), p.get(0).getY()); - series.add(p.get(1).getX(), p.get(1).getY()); - dataset.addSeries(series); - } + panel = new ChartPanel(chart); + panel.setPreferredSize(new Dimension(800, 800)); - XYSeries intersections = new XYSeries("intersections"); - for (Point p : points) { - domainMax = domainMax < p.getX() ? p.getX() : domainMax; - domainMin = domainMin > p.getX() ? p.getX() : domainMin; - rangeMax = rangeMax < p.getY() ? p.getY() : rangeMax; - rangeMin = rangeMin > p.getY() ? p.getY() : rangeMin; - intersections.add(p.getX(), p.getY()); - } - dataset.addSeries(intersections); + addListener(); - chart = ChartFactory.createXYLineChart( - null, null, null, dataset, - PlotOrientation.HORIZONTAL, false, false, false); - chart.setRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) ); - chart.setAntiAlias(true); + this.add(panel, BorderLayout.CENTER); + this.add(hslider, BorderLayout.SOUTH); + this.add(vslider, BorderLayout.EAST); + } - final XYPlot plot = chart.getXYPlot(); + private void addListener() { + this.vslider.addChangeListener(e -> { + JSlider slider = (JSlider) e.getSource(); + double delta = Math.abs(slider.getValue() - 50) * 0.1; + if (slider.getValue() < 50) { + domain.setRange(domainMin - delta, domainMax - delta); + } else { + domain.setRange(domainMin + delta, domainMax + delta); + } + }); - domain = plot.getDomainAxis(); - range = plot.getRangeAxis(); + this.hslider.addChangeListener(e -> { + JSlider slider = (JSlider) e.getSource(); + double delta = Math.abs(slider.getValue() - 500); - domain.setRange(domainMin - 1, domainMax + 1); - range.setRange(rangeMin - 1, rangeMax + 1); - plot.setBackgroundPaint(Color.WHITE); - plot.setDomainGridlinePaint(Color.white); - plot.setRangeGridlinePaint(Color.white); + if (slider.getValue() < 500) { + range.setRange(rangeMin - delta, rangeMax - delta); + } else { + range.setRange(rangeMin + delta, rangeMax + delta); + } + }); - - - final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); - renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false); - plot.setRenderer(renderer); - - for (int i=0;i { - JSlider slider = (JSlider) e.getSource(); - double delta = Math.abs(slider.getValue() - 50) * 0.1; - if (slider.getValue() < 50){ - domain.setRange(domainMin - delta, domainMax - delta); - } else { - domain.setRange(domainMin + delta, domainMax + delta); - } - }); - - this.hslider.addChangeListener(e -> { - JSlider slider = (JSlider) e.getSource(); - double delta = Math.abs(slider.getValue() - 500); - - if (slider.getValue() < 500){ - range.setRange(rangeMin - delta, rangeMax - delta); - } else { - range.setRange(rangeMin + delta, rangeMax + delta); - } - }); - - } + } } diff --git a/src/main/java/View/ArrangementDialog2.java b/src/main/java/View/ArrangementDialog2.java index 42003ef..fab32d2 100644 --- a/src/main/java/View/ArrangementDialog2.java +++ b/src/main/java/View/ArrangementDialog2.java @@ -1,11 +1,16 @@ package View; import Model.Point; - -import javax.swing.*; -import java.awt.*; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.awt.geom.Line2D; import java.util.LinkedList; +import javax.swing.JPanel; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -16,73 +21,76 @@ import java.util.LinkedList; */ public class ArrangementDialog2 extends JPanel { - private int min = 0; - private int max = 800; - private int zero = max/2; - private double scale = 1.0; - private int pointThicknes = 5; + private int min = 0; + private int max = 800; + private int zero = max / 2; + private double scale = 1.0; + private int pointThicknes = 5; - private Dimension dimension; - private LinkedList> lines; - private LinkedList points; - private LinkedList line2Ds; + private Dimension dimension; + private LinkedList> lines; + private LinkedList points; + private LinkedList line2Ds; - public ArrangementDialog2(){ - super(); - this.dimension = new Dimension(max,max); - this.setPreferredSize(dimension); - this.setLayout(new BorderLayout()); + public ArrangementDialog2() { + super(); + this.dimension = new Dimension(max, max); + this.setPreferredSize(dimension); + this.setLayout(new BorderLayout()); + } + + public void setPrameters(LinkedList> lines, LinkedList points) { + this.lines = lines; + this.points = points; + this.repaint(); + } + + public double getScale() { + return scale; + } + + public void setScale(double scale) { + this.scale = scale; + } + + public int getPointThicknes() { + return pointThicknes; + } + + public void setPointThicknes(int pointThicknes) { + this.pointThicknes = pointThicknes; + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + line2Ds = new LinkedList<>(); + g2.translate(zero, zero); + g2.scale(scale, scale); + g2.translate(-1 * zero, -1 * zero); + + //draw the lines + g2.setColor(Color.BLACK); + g2.setStroke(new BasicStroke(5f / (float) scale)); + for (LinkedList line : lines) { + line2Ds.add(new Line2D.Double(zero + line.getFirst().getX().intValue(), + zero + line.getFirst().getY().intValue(), zero + line.getLast().getX().intValue(), + zero + line.getLast().getY().intValue())); + } + for (Line2D.Double line : line2Ds) { + g2.draw(line); } - public void setPrameters(LinkedList> lines, LinkedList points) { - this.lines = lines; - this.points = points; - this.repaint(); - } - - public double getScale() { - return scale; - } - - public void setScale(double scale) { - this.scale = scale; - } - - public int getPointThicknes() { - return pointThicknes; - } - - public void setPointThicknes(int pointThicknes) { - this.pointThicknes = pointThicknes; - } - - @Override - public void paintComponent(Graphics g){ - super.paintComponent(g); - Graphics2D g2 = (Graphics2D) g; - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - line2Ds = new LinkedList<>(); - g2.translate(zero, zero); - g2.scale(scale, scale); - g2.translate(-1 * zero, -1 *zero); - - //draw the lines - g2.setColor(Color.BLACK); - g2.setStroke(new BasicStroke(5f / (float) scale)); - for (LinkedList line : lines){ - line2Ds.add(new Line2D.Double(zero +line.getFirst().getX().intValue(), zero +line.getFirst().getY().intValue(), zero +line.getLast().getX().intValue(), zero +line.getLast().getY().intValue())); - } - for (Line2D.Double line : line2Ds) { - g2.draw(line); - } - - //draw intersections of the lines - g2.setColor(Color.RED); - for (Point point : points) { - g2.fillOval(zero +point.getX().intValue(),zero +point.getY().intValue(), pointThicknes, pointThicknes); - } + //draw intersections of the lines + g2.setColor(Color.RED); + for (Point point : points) { + g2.fillOval(zero + point.getX().intValue(), zero + point.getY().intValue(), pointThicknes, + pointThicknes); } + } } diff --git a/src/main/java/View/MainFrame.java b/src/main/java/View/MainFrame.java index ae7f3df..8cd9dc1 100644 --- a/src/main/java/View/MainFrame.java +++ b/src/main/java/View/MainFrame.java @@ -1,21 +1,20 @@ package View; -import Model.Line; -import Presenter.Algorithms.LeastMedianOfSquaresEstimator; import Presenter.Presenter; -import com.sun.org.apache.xpath.internal.operations.Bool; -import jdk.nashorn.internal.scripts.JO; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.List; -import java.util.Observable; -import java.util.Observer; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -24,291 +23,293 @@ import java.util.Observer; * @Email: a_wolf28@uni-muenster.de * @Date: 28.05.2017. */ -public class MainFrame extends JFrame{ +public class MainFrame extends JFrame { - private Presenter presenter; - private Boolean lmsIsComplete = false; - private Boolean rmIsComplete = false; - private Boolean tsIsComplete = false; + private Presenter presenter; + private Boolean lmsIsComplete = false; + private Boolean rmIsComplete = false; + private Boolean tsIsComplete = false; - //TODO refactoring - private JButton arrangementButton; - private JButton button3; + //TODO refactoring + private JButton arrangementButton; + private JButton button3; - private OutputPanel output; - private MenuPanel menupanel; - private SidePanel sidepanel; - private JPanel pane; + private OutputPanel output; + private MenuPanel menupanel; + private SidePanel sidepanel; + private JPanel pane; - private ArrangementDialog arrangement; - private JDialog arrangementDialog; - private PlotDialog plot; + private ArrangementDialog arrangement; + private JDialog arrangementDialog; + private PlotDialog plot; - private JSplitPane splitpane; - private JScrollPane scrollPane; + private JSplitPane splitpane; + private JScrollPane scrollPane; - private JTabbedPane tabbedPane; + private JTabbedPane tabbedPane; - public MainFrame() { - initializeComponents(); - setDimensions(); - setLayouts(); - setTitles(); + public MainFrame() { + initializeComponents(); + setDimensions(); + setLayouts(); + setTitles(); - addComponents(); + addComponents(); - setCloseOperations(); - setActionListeners(); + setCloseOperations(); + setActionListeners(); - this.setVisible(true); + this.setVisible(true); + } + + + /******************************************************************************************************************* + * visualisierungs methoden + ******************************************************************************************************************/ + + public void createArrangement() { + if (arrangement == null) { + arrangement = new ArrangementDialog(); + arrangement.setPrameters(getPresenter().calcArrangementLines(), + getPresenter().getModel().getNodes()); + arrangement.createArrangement(); + SwingUtilities.invokeLater(() -> { + arrangementDialog.add(arrangement, BorderLayout.CENTER); + arrangementDialog.setVisible(true); + }); + } else { + arrangementDialog.setVisible(true); } + } + + public void createPlot(double m, double b) { + + plot = new PlotDialog(); + SwingUtilities.invokeLater(() -> { + plot.createPlot(getPresenter().getLines()); + plot.addLineToPlot(m, b); + sidepanel.setPlotDialog(plot); + }); + } - /******************************************************************************************************************* - * visualisierungs methoden - ******************************************************************************************************************/ + /******************************************************************************************************************* + * init GUI + ******************************************************************************************************************/ + private void setTitles() { + this.setTitle("MainFrame"); + arrangementDialog.setTitle("Dual Representation - Dialog"); + button3.setText("Import"); + arrangementButton.setText("Dualraum"); + } - public void createArrangement() { - if (arrangement == null) { - arrangement = new ArrangementDialog(); - arrangement.setPrameters(getPresenter().calcArrangementLines(), getPresenter().getModel().getNodes()); - arrangement.createArrangement(); - SwingUtilities.invokeLater(() -> { - arrangementDialog.add(arrangement, BorderLayout.CENTER); - arrangementDialog.setVisible(true); - }); - } else { - arrangementDialog.setVisible(true); - } - } + private void setupTabbedPane() { + tabbedPane.add("Least Median of Squares", sidepanel); + tabbedPane.add("Repeated Median", new JPanel()); + tabbedPane.add("Theil-Sen", new JPanel()); + } - public void createPlot(double m, double b) { + private void addComponents() { + pane.add(arrangementButton); + pane.add(button3); - plot = new PlotDialog(); - SwingUtilities.invokeLater(() -> { - plot.createPlot(getPresenter().getLines()); - plot.addLineToPlot(m, b); - sidepanel.setPlotDialog(plot); - }); - } + setupSplitPane(); + setupTabbedPane(); + + this.add(pane, BorderLayout.SOUTH); + this.add(splitpane, BorderLayout.CENTER); + this.add(menupanel, BorderLayout.NORTH); + } + + private void setupSplitPane() { + splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); + splitpane.setResizeWeight(.5d); + splitpane.setContinuousLayout(true); + splitpane.setLeftComponent(output); + splitpane.setRightComponent(tabbedPane); + } + + private void setCloseOperations() { + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + arrangementDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); + } + + private void setDimensions() { + this.setSize(1900, 1000); + sidepanel.setMinimumSize(new Dimension(400, 500)); + arrangementDialog.setSize(new Dimension(800, 800)); + output.setMinimumSize(new Dimension(400, 500)); + } + + private void setLayouts() { + this.setLayout(new BorderLayout()); + pane.setLayout(new FlowLayout()); + } + + private void initializeComponents() { + //Panels + pane = new JPanel(); + sidepanel = new SidePanel(); + menupanel = new MenuPanel(); + + //Dialogs + arrangementDialog = new JDialog(); + + //Panes + tabbedPane = new JTabbedPane(); + output = new OutputPanel(); + splitpane = new JSplitPane(); + + //Buttons + arrangementButton = new JButton(); + button3 = new JButton(); + } + + private void setActionListeners() { + arrangementButton.addActionListener((ActionEvent e) -> { + Thread t = new Thread(() -> getPresenter().startArrangementVisualization()); + t.start(); + }); + + sidepanel.getStartButton().addActionListener((ActionEvent e) -> { + Thread t = new Thread( + () -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput())); + t.start(); + }); + } + /******************************************************************************************************************* + * log Methode + ******************************************************************************************************************/ + public void log(String s) { + SwingUtilities.invokeLater(() -> output.appendParagraph(s)); + } - /******************************************************************************************************************* - * init GUI - ******************************************************************************************************************/ - private void setTitles(){ - this.setTitle("MainFrame"); - arrangementDialog.setTitle("Dual Representation - Dialog"); - button3.setText("Import"); - arrangementButton.setText("Dualraum"); - } + public void logError(String s) { + SwingUtilities.invokeLater(() -> output.appendParagraphRed(s)); + } - private void setupTabbedPane(){ - tabbedPane.add("LMS", sidepanel); - tabbedPane.add("RM", new JPanel()); - tabbedPane.add("TS", new JPanel()); - } + public void logSuccess(String s) { + SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s)); + } - private void addComponents(){ - pane.add(arrangementButton); - pane.add(button3); + public void logHeading(String s) { + SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s)); + } - setupSplitPane(); - setupTabbedPane(); + public void createTable(List heading, List> rows) { + SwingUtilities.invokeLater(() -> output.logTable(heading, rows)); + } - this.add(pane, BorderLayout.SOUTH); - this.add(splitpane, BorderLayout.CENTER); - this.add(menupanel, BorderLayout.NORTH); - } + /******************************************************************************************************************* + * Getter und Setter Methoden + ******************************************************************************************************************/ - private void setupSplitPane(){ - splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); - splitpane.setResizeWeight(.5d); - splitpane.setContinuousLayout(true); - splitpane.setLeftComponent(output); - splitpane.setRightComponent(tabbedPane); - } + public Boolean getLmsIsComplete() { + return lmsIsComplete; + } - private void setCloseOperations(){ - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - arrangementDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); - } + public void setLmsIsComplete(Boolean lmsIsComplete) { + this.lmsIsComplete = lmsIsComplete; + } - private void setDimensions(){ - this.setSize(1900, 1000); - sidepanel.setMinimumSize(new Dimension(400,500)); - arrangementDialog.setSize(new Dimension(800, 800)); - output.setMinimumSize(new Dimension(400,500)); - } + public Boolean getRmIsComplete() { + return rmIsComplete; + } - private void setLayouts(){ - this.setLayout(new BorderLayout()); - pane.setLayout(new FlowLayout()); - } + public void setRmIsComplete(Boolean rmIsComplete) { + this.rmIsComplete = rmIsComplete; + } - private void initializeComponents(){ - //Panels - pane = new JPanel(); - sidepanel = new SidePanel(); - menupanel = new MenuPanel(); + public Boolean getTsIsComplete() { + return tsIsComplete; + } - //Dialogs - arrangementDialog = new JDialog(); + public void setTsIsComplete(Boolean tsIsComplete) { + this.tsIsComplete = tsIsComplete; + } - //Panes - tabbedPane = new JTabbedPane(); - output = new OutputPanel(); - splitpane = new JSplitPane(); + public JButton getArrangementButton() { + return arrangementButton; + } - //Buttons - arrangementButton = new JButton(); - button3 = new JButton(); - } + public void setArrangementButton(JButton arrangementButton) { + this.arrangementButton = arrangementButton; + } - private void setActionListeners(){ - arrangementButton.addActionListener((ActionEvent e) -> { - Thread t = new Thread(() -> getPresenter().startArrangementVisualization()); - t.start(); - }); + public JButton getButton3() { + return button3; + } - sidepanel.getStartButton().addActionListener((ActionEvent e) -> { - Thread t = new Thread(() -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput())); - t.start(); - }); - } + public void setButton3(JButton button3) { + this.button3 = button3; + } + + public JPanel getPane() { + return pane; + } + + public void setPane(JPanel pane) { + this.pane = pane; + } + + public JDialog getArrangementDialog() { + return arrangementDialog; + } + + public void setArrangementDialog(JDialog arrangementDialog) { + this.arrangementDialog = arrangementDialog; + } + + public OutputPanel getOutput() { + return output; + } + + public void setOutput(OutputPanel output) { + this.output = output; + } + + public JPanel getMenupanel() { + return menupanel; + } + + public JPanel getSidepanel() { + return sidepanel; + } + + public JSplitPane getSplitpane() { + return splitpane; + } + + public void setSplitpane(JSplitPane splitpane) { + this.splitpane = splitpane; + } + + public JScrollPane getScrollPane() { + return scrollPane; + } + + public void setScrollPane(JScrollPane scrollPane) { + this.scrollPane = scrollPane; + } - /******************************************************************************************************************* - * log Methode - ******************************************************************************************************************/ - public void log(String s) { - SwingUtilities.invokeLater(() -> output.appendParagraph(s)); - } + public PlotDialog getPlot() { + return plot; + } - public void logError(String s){ - SwingUtilities.invokeLater(() -> output.appendParagraphRed(s)); - } + public void setPlot(PlotDialog plot) { + this.plot = plot; + } - public void logSuccess(String s){ - SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s)); - } + public Presenter getPresenter() { + return presenter; + } - public void logHeading(String s){ - SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s)); - } - - public void createTable(List heading, List> rows){ - SwingUtilities.invokeLater(() -> output.logTable(heading, rows)); - } - /******************************************************************************************************************* - * Getter und Setter Methoden - ******************************************************************************************************************/ - - public Boolean getLmsIsComplete() { - return lmsIsComplete; - } - - public void setLmsIsComplete(Boolean lmsIsComplete) { - this.lmsIsComplete = lmsIsComplete; - } - - public Boolean getRmIsComplete() { - return rmIsComplete; - } - - public void setRmIsComplete(Boolean rmIsComplete) { - this.rmIsComplete = rmIsComplete; - } - - public Boolean getTsIsComplete() { - return tsIsComplete; - } - - public void setTsIsComplete(Boolean tsIsComplete) { - this.tsIsComplete = tsIsComplete; - } - - public JButton getArrangementButton() { - return arrangementButton; - } - - public void setArrangementButton(JButton arrangementButton) { - this.arrangementButton = arrangementButton; - } - - public JButton getButton3() { - return button3; - } - - public void setButton3(JButton button3) { - this.button3 = button3; - } - - public JPanel getPane() { - return pane; - } - - public void setPane(JPanel pane) { - this.pane = pane; - } - - public JDialog getArrangementDialog() { - return arrangementDialog; - } - - public void setArrangementDialog(JDialog arrangementDialog) { - this.arrangementDialog = arrangementDialog; - } - - public OutputPanel getOutput() { - return output; - } - - public void setOutput(OutputPanel output) { - this.output = output; - } - - public JPanel getMenupanel() { - return menupanel; - } - - public JPanel getSidepanel() { - return sidepanel; - } - - public JSplitPane getSplitpane() { - return splitpane; - } - - public void setSplitpane(JSplitPane splitpane) { - this.splitpane = splitpane; - } - - public JScrollPane getScrollPane() { - return scrollPane; - } - - public void setScrollPane(JScrollPane scrollPane) { - this.scrollPane = scrollPane; - } - - - public PlotDialog getPlot() { - return plot; - } - - public void setPlot(PlotDialog plot) { - this.plot = plot; - } - - public Presenter getPresenter() { - return presenter; - } - - public void setPresenter(Presenter presenter) { - this.presenter = presenter; - } + public void setPresenter(Presenter presenter) { + this.presenter = presenter; + } } diff --git a/src/main/java/View/MenuPanel.java b/src/main/java/View/MenuPanel.java index 788ff74..4e5f5c7 100644 --- a/src/main/java/View/MenuPanel.java +++ b/src/main/java/View/MenuPanel.java @@ -1,9 +1,12 @@ package View; -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import java.awt.BorderLayout; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -14,21 +17,23 @@ import java.awt.event.ActionListener; */ public class MenuPanel extends JPanel { - private JMenuBar menuBar; - private JMenu menu; - private JMenuItem item; + private JMenuBar menuBar; + private JMenu menu; + private JMenuItem item; - public MenuPanel() { - this.setLayout(new BorderLayout()); - this.menuBar = new JMenuBar(); - this.menu = new JMenu("File"); + public MenuPanel() { + this.setLayout(new BorderLayout()); + this.menuBar = new JMenuBar(); + this.menu = new JMenu("File"); - this.item = new JMenuItem("Exit"); - this.item.addActionListener(e -> { System.exit(0);}); + this.item = new JMenuItem("Exit"); + this.item.addActionListener(e -> { + System.exit(0); + }); - menu.add(item); - menuBar.add(menu); - this.add(menuBar, BorderLayout.WEST); - this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH); - } + menu.add(item); + menuBar.add(menu); + this.add(menuBar, BorderLayout.WEST); + this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH); + } } diff --git a/src/main/java/View/OutputPanel.java b/src/main/java/View/OutputPanel.java index fc2905c..3b28c56 100644 --- a/src/main/java/View/OutputPanel.java +++ b/src/main/java/View/OutputPanel.java @@ -1,9 +1,12 @@ package View; -import javax.swing.*; -import javax.swing.border.TitledBorder; -import java.awt.*; +import java.awt.BorderLayout; import java.util.List; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.border.TitledBorder; + /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -13,73 +16,73 @@ import java.util.List; */ public class OutputPanel extends JPanel { - private JTextPane output; - private JScrollPane scrollPane; - private StringBuilder content; + private JTextPane output; + private JScrollPane scrollPane; + private StringBuilder content; - public OutputPanel(){ - this.setBorder(new TitledBorder("Ausgabekanal")); - this.setLayout(new BorderLayout()); - output = new JTextPane(); - output.setEditable(false); - output.setContentType("text/html"); + public OutputPanel() { + this.setBorder(new TitledBorder("Ausgabekanal")); + this.setLayout(new BorderLayout()); + output = new JTextPane(); + output.setEditable(false); + output.setContentType("text/html"); - content = new StringBuilder(); + content = new StringBuilder(); + + scrollPane = new JScrollPane(output); + scrollPane.setWheelScrollingEnabled(true); + this.add(scrollPane, BorderLayout.CENTER); + + } - scrollPane = new JScrollPane(output); - scrollPane.setWheelScrollingEnabled(true); - this.add(scrollPane, BorderLayout.CENTER); + public void appendParagraph(String p) { - } + content.append("

" + p + "


"); - - public void appendParagraph(String p) { - - content.append("

" + p + "


"); - - output.setText(content.toString()); - } - - public void appendParagraphWithHeading(String h1){ - - content.append("

"+ h1 + "


"); - - output.setText(content.toString()); - } - - public void appendParagraphRed(String p) { - - content.append("

" + p + "


"); - - output.setText(content.toString()); - } - public void appendParagraphGreen(String p) { - - content.append("

" + p + "


"); - - output.setText(content.toString()); - } - - public void logTable(List heading, List> rows){ - content.append("
"); - content.append(""); - content.append(""); - for (String str : heading) { - content.append(""); - } - content.append(""); - for (List row : rows) { - content.append(""); - for (String entry : row) { - content.append(""); - } - content.append(""); - } - content.append("
" + str + "
"+entry+"
"); - content.append("
"); output.setText(content.toString()); + } + + public void appendParagraphWithHeading(String h1) { + + content.append("

" + h1 + "


"); + + output.setText(content.toString()); + } + + public void appendParagraphRed(String p) { + + content.append("

" + p + "


"); + + output.setText(content.toString()); + } + + public void appendParagraphGreen(String p) { + + content.append("

" + p + "


"); + + output.setText(content.toString()); + } + + public void logTable(List heading, List> rows) { + content.append("
"); + content.append(""); + content.append(""); + for (String str : heading) { + content.append(""); } + content.append(""); + for (List row : rows) { + content.append(""); + for (String entry : row) { + content.append(""); + } + content.append(""); + } + content.append("
" + str + "
" + entry + "
"); + content.append("
"); + output.setText(content.toString()); + } } diff --git a/src/main/java/View/PlotDialog.java b/src/main/java/View/PlotDialog.java index 0297435..0c6ce60 100644 --- a/src/main/java/View/PlotDialog.java +++ b/src/main/java/View/PlotDialog.java @@ -1,24 +1,25 @@ package View; import Model.Line; -import Model.Point; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Shape; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import javax.swing.JPanel; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.util.ShapeUtilities; -import javax.swing.*; -import java.awt.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; - /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -28,92 +29,91 @@ import java.util.LinkedList; */ public class PlotDialog extends JPanel { - private JFreeChart chart; - private ChartPanel panel; - private XYSeriesCollection datapoints; - private XYSeries series; - private XYSeries linesA, linesB; - private Double min; - private Double max; + private JFreeChart chart; + private ChartPanel panel; + private XYSeriesCollection datapoints; + private XYSeries series; + private XYSeries linesA, linesB; + private Double min; + private Double max; - public PlotDialog() { - super(); - this.setPreferredSize(new Dimension(800, 500)); - this.setMinimumSize(new Dimension(800, 500)); - this.setLayout(new BorderLayout()); + public PlotDialog() { + super(); + this.setPreferredSize(new Dimension(800, 500)); + this.setMinimumSize(new Dimension(800, 500)); + this.setLayout(new BorderLayout()); + } + + public void createPlot(LinkedList points) { + + try { + Thread thread = new Thread(() -> convertData(points)); + thread.start(); + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); } - public void createPlot(LinkedList points) { + //createScatterPlot + chart = ChartFactory.createXYLineChart("", + "X", "Y", datapoints, PlotOrientation.VERTICAL, false, true, false); + Shape diamond = ShapeUtilities.createDiamond(2f); + chart.setBorderVisible(false); + chart.setAntiAlias(true); + chart.getPlot().setBackgroundPaint(Color.WHITE); - try { - Thread thread = new Thread(() -> convertData(points)); - thread.start(); - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + XYPlot xyPlot = (XYPlot) chart.getPlot(); + xyPlot.setDomainCrosshairVisible(true); + xyPlot.setRangeCrosshairVisible(true); - //createScatterPlot - chart = ChartFactory.createXYLineChart("", - "X", "Y", datapoints, PlotOrientation.VERTICAL, false, true, false); - Shape diamond = ShapeUtilities.createDiamond(2f); - chart.setBorderVisible(false); - chart.setAntiAlias(true); - chart.getPlot().setBackgroundPaint(Color.WHITE); + XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer(); + renderer.setSeriesLinesVisible(0, false); + renderer.setSeriesShapesVisible(0, true); + renderer.setSeriesLinesVisible(1, true); + renderer.setSeriesLinesVisible(2, true); - XYPlot xyPlot = (XYPlot) chart.getPlot(); - xyPlot.setDomainCrosshairVisible(true); - xyPlot.setRangeCrosshairVisible(true); + renderer.setSeriesPaint(0, Color.blue); + renderer.setSeriesShape(0, diamond); - XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer(); - renderer.setSeriesLinesVisible(0,false); - renderer.setSeriesShapesVisible(0, true); - renderer.setSeriesLinesVisible(1,true); - renderer.setSeriesLinesVisible(2,true); + renderer.setSeriesPaint(1, Color.red); + renderer.setSeriesShape(1, diamond); + renderer.setSeriesStroke(1, new BasicStroke(2.0f)); + renderer.setBaseSeriesVisible(true); - renderer.setSeriesPaint(0, Color.blue); - renderer.setSeriesShape(0, diamond); + renderer.setSeriesPaint(2, Color.GREEN); + renderer.setSeriesShape(2, diamond); + renderer.setSeriesStroke(2, new BasicStroke(2.0f)); + renderer.setBaseSeriesVisible(true); + xyPlot.setDomainCrosshairVisible(true); + xyPlot.setRangeCrosshairVisible(true); - renderer.setSeriesPaint(1, Color.red); - renderer.setSeriesShape(1, diamond); - renderer.setSeriesStroke(1,new BasicStroke(2.0f)); - renderer.setBaseSeriesVisible(true); + panel = new ChartPanel(chart); + this.add(panel, BorderLayout.CENTER); + } - renderer.setSeriesPaint(2, Color.GREEN); - renderer.setSeriesShape(2, diamond); - renderer.setSeriesStroke(2,new BasicStroke(2.0f)); - renderer.setBaseSeriesVisible(true); + public void addLineToPlot(double m, double b) { + linesA = new XYSeries("linesA"); + linesA.add(min.intValue(), min.intValue() * m + b); + linesA.add(max.intValue(), max.intValue() * m + b); - xyPlot.setDomainCrosshairVisible(true); - xyPlot.setRangeCrosshairVisible(true); + datapoints.addSeries(linesA); + } + + private void convertData(LinkedList points) { + + datapoints = new XYSeriesCollection(); + ArrayList coordinates = new ArrayList<>(); + series = new XYSeries("points"); + for (Line p : points) { + series.add(p.getM(), p.getB()); + coordinates.add(p.getM()); - panel = new ChartPanel(chart); - this.add(panel, BorderLayout.CENTER); - } - - public void addLineToPlot(double m, double b) { - linesA = new XYSeries("linesA"); - linesA.add(min.intValue(), min.intValue() * m + b ); - linesA.add(max.intValue(), max.intValue() * m + b ); - - datapoints.addSeries(linesA); - } - - private void convertData(LinkedList points) { - - datapoints = new XYSeriesCollection(); - ArrayList coordinates = new ArrayList<>(); - series = new XYSeries("points"); - for (Line p : points) { - series.add(p.getM(), p.getB()); - coordinates.add(p.getM()); - - } - this.max = Collections.max(coordinates) + 1; - this.min = Collections.min(coordinates) - 1; - datapoints.addSeries(series); } + this.max = Collections.max(coordinates) + 1; + this.min = Collections.min(coordinates) - 1; + datapoints.addSeries(series); + } } diff --git a/src/main/java/View/SidePanel.java b/src/main/java/View/SidePanel.java index 2ca5c93..f36cced 100644 --- a/src/main/java/View/SidePanel.java +++ b/src/main/java/View/SidePanel.java @@ -1,8 +1,14 @@ package View; -import javax.swing.*; +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; import javax.swing.border.TitledBorder; -import java.awt.*; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -14,99 +20,98 @@ import java.awt.*; public class SidePanel extends JPanel { - private JLabel[] labels; - private JTextField[] input; - private JButton startButton; - private JPanel continer; - private JPanel northPanel; - private JPanel centerPanel; - private PlotDialog plotDialog; - private GridBagConstraints gbc; + private JLabel[] labels; + private JTextField[] input; + private JButton startButton; + private JPanel continer; + private JPanel northPanel; + private JPanel centerPanel; + private PlotDialog plotDialog; + private GridBagConstraints gbc; - public SidePanel() { - this.labels = new JLabel[10]; - this.input = new JTextField[10]; - this.setLayout(new BorderLayout()); - this.northPanel = new JPanel(new BorderLayout()); - this.centerPanel = new JPanel(new BorderLayout()); - this.northPanel.setBorder(new TitledBorder("Konfiguration")); - this.centerPanel.setBorder(new TitledBorder("Visualisierung")); + public SidePanel() { + this.labels = new JLabel[10]; + this.input = new JTextField[10]; + this.setLayout(new BorderLayout()); + this.northPanel = new JPanel(new BorderLayout()); + this.centerPanel = new JPanel(new BorderLayout()); + this.northPanel.setBorder(new TitledBorder("Konfiguration")); + this.centerPanel.setBorder(new TitledBorder("Visualisierung")); + + this.continer = new JPanel(); + this.continer.setLayout(new GridBagLayout()); + + this.gbc = new GridBagConstraints(); + this.gbc.anchor = GridBagConstraints.NORTH; + this.gbc.fill = GridBagConstraints.HORIZONTAL; + + addTextfieldAndInput(0, "Konstante", 0.5); + addTextfieldAndInput(1, "Fehler", 0.05); + + this.startButton = new JButton("start"); + addButton(2, startButton); + + this.northPanel.add(continer, BorderLayout.CENTER); + this.add(northPanel, BorderLayout.NORTH); + this.add(centerPanel, BorderLayout.CENTER); + } - this.continer = new JPanel(); - this.continer.setLayout(new GridBagLayout()); + private void addTextfieldAndInput(int row, String name, Double value) { + this.labels[row] = new JLabel(name); + this.input[row] = new JTextField(); + this.input[row].setText("" + value); - this.gbc = new GridBagConstraints(); - this.gbc.anchor = GridBagConstraints.NORTH; - this.gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(0, 5, 0, 0); + gbc.gridx = 0; + gbc.gridy = row; + gbc.weightx = 0.05; + gbc.weighty = 0.05; + continer.add(this.labels[row], gbc); - addTextfieldAndInput(0, "Konstante", 0.5); - addTextfieldAndInput(1, "Fehler", 0.05); + gbc.gridx = 1; + gbc.gridy = row; + gbc.weightx = 0.9; + gbc.weighty = 0.05; + gbc.insets = new Insets(0, 0, 0, 5); + continer.add(this.input[row], gbc); + } - this.startButton = new JButton("start"); - addButton(2, startButton); + private void addButton(int row, JButton button) { - this.northPanel.add(continer, BorderLayout.CENTER); - this.add(northPanel, BorderLayout.NORTH); - this.add(centerPanel, BorderLayout.CENTER); - } + gbc.insets = new Insets(30, 5, 10, 0); + gbc.gridx = 0; + gbc.gridy = row; + gbc.weightx = 0.05; + gbc.weighty = 0.05; + continer.add(button, gbc); + } - private void addTextfieldAndInput(int row, String name, Double value) { - this.labels[row] = new JLabel(name); - this.input[row] = new JTextField(); - this.input[row].setText("" + value); + public JButton getStartButton() { + return startButton; + } - gbc.insets = new Insets(0, 5, 0, 0); - gbc.gridx = 0; - gbc.gridy = row; - gbc.weightx = 0.05; - gbc.weighty = 0.05; - continer.add(this.labels[row], gbc); + public String[] getInput() { + String[] input = new String[3]; + input[0] = this.input[0].getText(); + input[1] = this.input[1].getText(); + return input; + } - gbc.gridx = 1; - gbc.gridy = row; - gbc.weightx = 0.9; - gbc.weighty = 0.05; - gbc.insets = new Insets(0, 0, 0, 5); - continer.add(this.input[row], gbc); - } + public void setInput(JTextField[] input) { + this.input = input; + } - private void addButton(int row, JButton button) { + public PlotDialog getPlotDialog() { + return plotDialog; + } - gbc.insets = new Insets(30, 5, 10, 0); - gbc.gridx = 0; - gbc.gridy = row; - gbc.weightx = 0.05; - gbc.weighty = 0.05; - - continer.add(button, gbc); - } - - public JButton getStartButton() { - return startButton; - } - - public String[] getInput() { - String[] input = new String[3]; - input[0] = this.input[0].getText(); - input[1] = this.input[1].getText(); - return input; - } - - public void setInput(JTextField[] input) { - this.input = input; - } - - public PlotDialog getPlotDialog() { - return plotDialog; - } - - public void setPlotDialog(PlotDialog plotDialog) { - this.plotDialog = plotDialog; - this.centerPanel.add(plotDialog, BorderLayout.CENTER); - this.plotDialog.setVisible(true); - this.repaint(); - this.revalidate(); - } + public void setPlotDialog(PlotDialog plotDialog) { + this.plotDialog = plotDialog; + this.centerPanel.add(plotDialog, BorderLayout.CENTER); + this.plotDialog.setVisible(true); + this.repaint(); + this.revalidate(); + } } diff --git a/src/test/java/Model/DoublyConnectedEdgeListTest.java b/src/test/java/Model/DoublyConnectedEdgeListTest.java index 459af80..852f7e3 100644 --- a/src/test/java/Model/DoublyConnectedEdgeListTest.java +++ b/src/test/java/Model/DoublyConnectedEdgeListTest.java @@ -1,17 +1,16 @@ package Model; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + import Model.DCEL.DoublyConnectedEdgeList; import Model.DCEL.Edge; import Model.DCEL.Face; import Model.DCEL.Node; +import java.util.LinkedList; import org.junit.Before; import org.junit.Test; -import java.util.LinkedList; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -21,80 +20,80 @@ import static org.junit.Assert.assertEquals; */ public class DoublyConnectedEdgeListTest { - private static DoublyConnectedEdgeList dcel; - private static Node v1, v2, v3, v4, v5; - private static Edge e1, e2, e3, e4, e5; - private static Face f1, f2; + private static DoublyConnectedEdgeList dcel; + private static Node v1, v2, v3, v4, v5; + private static Edge e1, e2, e3, e4, e5; + private static Face f1, f2; - @Before - public void setUp() throws Exception { - dcel = new DoublyConnectedEdgeList(); + @Before + public void setUp() throws Exception { + dcel = new DoublyConnectedEdgeList(); - //initialisiere die TestKnoten im Graphen - v1 = dcel.createNode(new Point(2.5, 7.5), "v1"); - v2 = dcel.createNode(new Point(2.5, 4.0), "v2"); - v3 = dcel.createNode(new Point(6.5, 3.5), "v3"); - v4 = dcel.createNode(new Point(8.5, 6.5), "v4"); - v5 = dcel.createNode(new Point(6.0, 8.0), "v5"); + //initialisiere die TestKnoten im Graphen + v1 = dcel.createNode(new Point(2.5, 7.5), "v1"); + v2 = dcel.createNode(new Point(2.5, 4.0), "v2"); + v3 = dcel.createNode(new Point(6.5, 3.5), "v3"); + v4 = dcel.createNode(new Point(8.5, 6.5), "v4"); + v5 = dcel.createNode(new Point(6.0, 8.0), "v5"); - //initialisere Kanten im Graph - e1 = dcel.createEdge(v1, v5, "e1"); - e2 = dcel.createEdge(v5, v4, "e2"); - e3 = dcel.createEdge(v4, v3, "e3"); - e4 = dcel.createEdge(v3, v2, "e4"); - e5 = dcel.createEdge(v2, v1, "e5"); + //initialisere Kanten im Graph + e1 = dcel.createEdge(v1, v5, "e1"); + e2 = dcel.createEdge(v5, v4, "e2"); + e3 = dcel.createEdge(v4, v3, "e3"); + e4 = dcel.createEdge(v3, v2, "e4"); + e5 = dcel.createEdge(v2, v1, "e5"); - dcel.createConnection(e1, e2); - dcel.createConnection(e2, e3); - dcel.createConnection(e3, e4); - dcel.createConnection(e4, e5); - dcel.createConnection(e5, e1); + dcel.createConnection(e1, e2); + dcel.createConnection(e2, e3); + dcel.createConnection(e3, e4); + dcel.createConnection(e4, e5); + dcel.createConnection(e5, e1); - //intialisiere die Flaechen - f1 = dcel.createFace(null, e1, "f1"); - f2 = dcel.createFace(e1.getTwin(), null, "f2"); + //intialisiere die Flaechen + f1 = dcel.createFace(null, e1, "f1"); + f2 = dcel.createFace(e1.getTwin(), null, "f2"); + } + + + @Test + public void testInnerComponentsAccess() { + System.out.println("Test: testInnerComponentAccess();"); + Edge[] expected = {e1, e2, e3, e4, e5}; + LinkedList list = dcel.getEdgesOfInnerComponents(f1); + + assertArrayEquals(expected, list.toArray()); + } + + @Test + public void testOuterComponentsAccess() { + System.out.println("Test: testOuterComponentAccess();"); + String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"}; + LinkedList list = dcel.getEdgesOfOuterComponents(f2); + + for (int i = 0; i < list.size(); i++) { + assertEquals(expected[i], list.get(i).getID()); } - - @Test - public void testInnerComponentsAccess() { - System.out.println("Test: testInnerComponentAccess();"); - Edge[] expected = {e1, e2, e3, e4, e5}; - LinkedList list = dcel.getEdgesOfInnerComponents(f1); - - assertArrayEquals(expected, list.toArray()); - } - - @Test - public void testOuterComponentsAccess() { - System.out.println("Test: testOuterComponentAccess();"); - String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"}; - LinkedList list = dcel.getEdgesOfOuterComponents(f2); - - for (int i = 0; i < list.size(); i++) { - assertEquals(expected[i], list.get(i).getID()); - } - - } + } - @Test - public void testNodeEdgeAccess() { - System.out.println("Test: testNodeEdgeAccess();"); + @Test + public void testNodeEdgeAccess() { + System.out.println("Test: testNodeEdgeAccess();"); - assertEquals(5, dcel.getConnectedEdges(v4).size()); - } + assertEquals(5, dcel.getConnectedEdges(v4).size()); + } - @Test - public void testDCELAccess() { - System.out.println("Test: testDCELAccess();"); + @Test + public void testDCELAccess() { + System.out.println("Test: testDCELAccess();"); - assertEquals(e1, e1.getTwin().getTwin()); - assertEquals(e1, e1.getPrev().getNext()); - assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID()); - assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext()); - assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext()); - } + assertEquals(e1, e1.getTwin().getTwin()); + assertEquals(e1, e1.getPrev().getNext()); + assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID()); + assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext()); + assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext()); + } } \ No newline at end of file diff --git a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java index cb37d38..402268b 100644 --- a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java +++ b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java @@ -1,16 +1,18 @@ package Presenter.Algorithms; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import Model.Line; import Model.Point; import Model.Slab; -import org.junit.Before; -import org.junit.Test; - +import Presenter.InversionCounter; import java.util.ArrayList; import java.util.LinkedList; - -import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -21,100 +23,97 @@ import static org.junit.Assert.*; */ public class LeastMedianOfSquaresEstimatorTest { - private LeastMedianOfSquaresEstimator lms; + private LeastMedianOfSquaresEstimator lms; - @Before - public void setUp() throws Exception { + @Before + public void setUp() throws Exception { - Double[] x = {18d,24d,30d,34d,38d}; - Double[] y = {18d,26d,30d,40d,70d}; + Double[] x = {18d, 24d, 30d, 34d, 38d}; + Double[] y = {18d, 26d, 30d, 40d, 70d}; - LinkedList lines = new LinkedList<>(); - LinkedList intersections = new LinkedList<>(); + LinkedList lines = new LinkedList<>(); + LinkedList intersections = new LinkedList<>(); - for (int i=0; i<5; i++) - lines.add(new Line(x[i], y[i])); + for (int i = 0; i < 5; i++) { + lines.add(new Line(x[i], y[i])); + } + + lms = new LeastMedianOfSquaresEstimator(lines, intersections); + } + + @Test + public void approximateLMS() throws Exception { + + } - - - lms = new LeastMedianOfSquaresEstimator(lines, intersections); - } - - @Test - public void approximateLMS() throws Exception { - - } - - - @Test - public void mergeSort() throws Exception { + @Test + public void mergeSort() throws Exception { // double[] umin = {6,3,4,1,2,5}; // double[] umax = {3,5,2,6,1,4}; - double[] umin = {1,2,3,4}; - double[] umax = {2,3,4,1}; - ArrayList a = new ArrayList<>(); - ArrayList b = new ArrayList<>(); - - for (double d :umin) { - a.add((int) d); - } - - for (double d :umax) { - b.add((int) d); - } - InversionCounter invCounter = new InversionCounter(); - int ret = invCounter.run(a, b); - assertEquals(3d, ret, 0.001); + double[] umin = {1, 2, 3, 4}; + double[] umax = {2, 3, 4, 1}; + ArrayList a = new ArrayList<>(); + ArrayList b = new ArrayList<>(); + for (double d : umin) { + a.add((int) d); } - @Test - public void geEjValues() throws Exception { - - Double[] expected = {36d,50d,60d,74d,108d}; - ArrayList actual = lms.getEjValues(1d); - assertArrayEquals(expected, actual.toArray()); + for (double d : umax) { + b.add((int) d); } + InversionCounter invCounter = new InversionCounter(); + int ret = invCounter.run(a, b); + assertEquals(3d, ret, 0.001); - @Test - public void calcKMinusBracelet() throws Exception { + } - Point point = new Point(1d, 1d); - Double[] expected = {24d, 36d, 60d}; - Double[] actual = lms.calcKMinusBracelet(point, 3); + @Test + public void geEjValues() throws Exception { - assertArrayEquals(expected, actual); + Double[] expected = {36d, 50d, 60d, 74d, 108d}; + ArrayList actual = lms.getEjValues(1d); + assertArrayEquals(expected, actual.toArray()); + } - } + @Test + public void calcKMinusBracelet() throws Exception { - @Test - public void upperBound() throws Exception { - lms.setkMinus(3); - lms.setHeightsigmaMin(500); - lms.setSigmaMin(new Line(0,0,0,0)); - lms.setN(5); - Line expected = new Line(5,5,146,210); - lms.upperBound(5d); + Point point = new Point(1d, 1d); + Double[] expected = {24d, 36d, 60d}; + Double[] actual = lms.calcKMinusBracelet(point, 3); - assertEquals(expected.getX1(), lms.getSigmaMin().getX1(),0.01); - assertEquals(expected.getX2(), lms.getSigmaMin().getX2(),0.01); - assertEquals(expected.getY1(), lms.getSigmaMin().getY1(),0.01); - assertEquals(expected.getY2(), lms.getSigmaMin().getY2(),0.01); - } + assertArrayEquals(expected, actual); - @Test - public void lowerBound() throws Exception { - //kann nur über sout geprüft werden test passt aber - Double[] expectedAlpha = {0d,0d,0d,2d,4d}; - Double[] expectedBeta = {2d,4d,4d,2d,1d}; - lms.setHeightsigmaMin(500); + } - Slab slab = new Slab(-2,0); - lms.lowerBound(slab); - assertTrue(slab.getActivity()); - } + @Test + public void upperBound() throws Exception { + lms.setkMinus(3); + lms.setHeightsigmaMin(500); + lms.setSigmaMin(new Line(0, 0, 0, 0)); + lms.setN(5); + Line expected = new Line(5, 5, 146, 210); + lms.upperBound(5d); + assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01); + assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01); + assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01); + assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01); + } + + @Test + public void lowerBound() throws Exception { + //kann nur über sout geprüft werden test passt aber + Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d}; + Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d}; + lms.setHeightsigmaMin(500); + + Slab slab = new Slab(-2, 0); + lms.lowerBound(slab); + assertTrue(slab.getActivity()); + } } \ No newline at end of file