diff --git a/src/main/java/Model/Line.java b/src/main/java/Model/Line.java
index 893778b..df0db8e 100644
--- a/src/main/java/Model/Line.java
+++ b/src/main/java/Model/Line.java
@@ -9,6 +9,10 @@ package Model;
*/
public class Line {
+ private final Double MAX = 9999d;
+ private final Double MIN = -9999d;
+
+
private double m;
private double b;
@@ -23,10 +27,10 @@ public class Line {
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 = MIN;
+ this.y1 = (MIN * m) + b;
+ this.x2 = MAX * 0.5;
+ this.y2 = ((MAX * 0.5) * m) + b;
this.id = id;
}
@@ -35,10 +39,10 @@ public class Line {
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 = MIN;
+ this.y1 = (MIN * m) + b;
+ this.x2 = MAX * 0.5;
+ this.y2 = ((MAX * 0.5) * m) + b;
}
public Line(double x1, double x2, double y1, double y2) {
diff --git a/src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java b/src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorBegin.java
similarity index 93%
rename from src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java
rename to src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorBegin.java
index 104d959..117899b 100644
--- a/src/main/java/Presenter/Comparators/YOrderLineComparatorBegin.java
+++ b/src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorBegin.java
@@ -1,4 +1,4 @@
-package Presenter.Comparators;
+package Presenter.Algorithms.Comparators;
import Model.Line;
import java.util.Comparator;
diff --git a/src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java b/src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorEnd.java
similarity index 93%
rename from src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java
rename to src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorEnd.java
index e6f3ab7..e64a512 100644
--- a/src/main/java/Presenter/Comparators/YOrderLineComparatorEnd.java
+++ b/src/main/java/Presenter/Algorithms/Comparators/YOrderLineComparatorEnd.java
@@ -1,4 +1,4 @@
-package Presenter.Comparators;
+package Presenter.Algorithms.Comparators;
import Model.Line;
import java.util.Comparator;
diff --git a/src/main/java/Presenter/Algorithms/IntersectionCounter.java b/src/main/java/Presenter/Algorithms/IntersectionCounter.java
index 5c3ecfd..4ca8852 100644
--- a/src/main/java/Presenter/Algorithms/IntersectionCounter.java
+++ b/src/main/java/Presenter/Algorithms/IntersectionCounter.java
@@ -1,9 +1,8 @@
package Presenter.Algorithms;
import Model.*;
-import Presenter.Comparators.YOrderLineComparatorBegin;
-import Presenter.Comparators.YOrderLineComparatorEnd;
-import Presenter.Presenter;
+import Presenter.Algorithms.Comparators.YOrderLineComparatorBegin;
+import Presenter.Algorithms.Comparators.YOrderLineComparatorEnd;
import java.util.ArrayList;
import java.util.Collections;
@@ -226,8 +225,6 @@ public class IntersectionCounter {
/**
* Diese Methode liefert nur nach dem Ausführen der run
Funktion Sinnvolle Werte.
- *
- *
*/
public void calculateIntersectionAbscissas(Arrangement model){
ArrayList result = new ArrayList<>();
diff --git a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java
index 9b04923..51ed030 100644
--- a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java
+++ b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java
@@ -37,7 +37,10 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
private Line sigmaMin;
private double heightsigmaMin;
private Double intersectionsPoint;
- private Double constant;
+ private Double constant = 0.5;
+
+ private Double slope;
+ private Double yInterception;
public LeastMedianOfSquaresEstimator(LinkedList set, LinkedList intersections,
Presenter presenter) {
@@ -355,6 +358,10 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
+
+ slope = m;
+ yInterception = b;
+
String[] result = {"lms", m+"", b+""};
notifyObservers(result);
}
@@ -460,4 +467,12 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
public void setConstant(Double constant) {
this.constant = constant;
}
+
+ public Double getSlope() {
+ return slope;
+ }
+
+ public Double getyInterception() {
+ return yInterception;
+ }
}
diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java
index f47e6ce..071175b 100644
--- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java
+++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java
@@ -44,6 +44,9 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
private Double thetaLow;
private Double thetaHigh;
+ private Double slope;
+ private Double yInterception;
+
public RepeatedMedianEstimator(LinkedList set, Presenter presenter) {
this.set = set;
@@ -68,6 +71,10 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
linePairs = new HashMap<>();
}
+ public RepeatedMedianEstimator(LinkedList set) {
+ this(set,null);
+ }
+
/**
*
*/
@@ -272,6 +279,8 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
.getB());
+ slope = m;
+ yInterception = b;
String[] result = new String[]{"rm", m+"", b+""};
notifyObservers(result);
}
@@ -432,6 +441,14 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
public void setThetaHigh(Double thetaHigh) {
this.thetaHigh = thetaHigh;
}
+
+ public Double getSlope() {
+ return slope;
+ }
+
+ public Double getyInterception() {
+ return yInterception;
+ }
}
diff --git a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java
index 407c5e7..17cb4f9 100644
--- a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java
+++ b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java
@@ -46,6 +46,9 @@ public class TheilSenEstimator extends Observable implements Algorithm {
private Double aVariant;
private Double bVariant;
+ private Double slope;
+ private Double yInterception;
+
public TheilSenEstimator(LinkedList setOfLines, LinkedList setOfIntersections, Presenter presenter) {
this.presenter = presenter;
@@ -68,6 +71,10 @@ public class TheilSenEstimator extends Observable implements Algorithm {
}
}
+ public TheilSenEstimator(LinkedList setOfLines, LinkedList setOfIntersections) {
+ this(setOfLines,setOfIntersections,null);
+ }
+
/**
* Randomisierter Algorithmus zur Berechnung des Theil-Sen Schätzers.
* Algorithmus stammt aus dem Paper:
@@ -244,10 +251,20 @@ public class TheilSenEstimator extends Observable implements Algorithm {
b = (x * m) - y;
+ slope = m;
+ yInterception = b;
+
String[] result = new String[]{"ts", m + "", b + ""};
notifyObservers(result);
}
}
+ public Double getSlope() {
+ return slope;
+ }
+
+ public Double getyInterception() {
+ return yInterception;
+ }
}
diff --git a/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java b/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java
new file mode 100644
index 0000000..505c216
--- /dev/null
+++ b/src/main/java/Presenter/Evaluation/EvaluateAlgorithms.java
@@ -0,0 +1,149 @@
+package Presenter.Evaluation;
+
+import Model.Arrangement;
+import Model.Interval;
+import Model.Line;
+import Presenter.Algorithms.*;
+import Presenter.Generator.DatasetGenerator;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
+ *
+ * @Author: Armin Wolf
+ * @Email: a_wolf28@uni-muenster.de
+ * @Date: 01.08.2017.
+ */
+public class EvaluateAlgorithms {
+
+ private Arrangement arrangement;
+ private Double[] lmsResult;
+ private Double[] rmResult;
+ private Double[] tsResult;
+
+
+ public EvaluateAlgorithms(){
+ this.arrangement = new Arrangement();
+ }
+
+ public static void main(String args[]){
+ EvaluateAlgorithms e = new EvaluateAlgorithms();
+ try {
+ e.run();
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ public void run() throws InterruptedException {
+
+ Thread thread = new Thread(() -> {
+ DatasetGenerator generator = new DatasetGenerator();
+ arrangement.setLines(generator.generateDataset());
+
+ IntersectionCounter counter = new IntersectionCounter();
+ counter.run(arrangement.getLines(), new Interval(-99999,99999));
+ counter.calculateIntersectionAbscissas(arrangement);
+ });
+ thread.start();
+ thread.join();
+
+
+ Thread lms = new Thread(() -> {
+ LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(arrangement.getLines()
+ ,arrangement.getNodes());
+ lmsAlg.run();
+
+ List errors = sampsonError(arrangement.getLines(), lmsAlg.getSlope(), lmsAlg.getyInterception());
+ lmsResult = getResults(errors);
+ });
+ Thread rm = new Thread(() -> {
+ RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(arrangement.getLines());
+ rmAlg.run();
+ List errors = sampsonError(arrangement.getLines(), rmAlg.getSlope(), rmAlg.getyInterception());
+ rmResult = getResults(errors);
+ });
+ Thread ts = new Thread(() -> {
+ TheilSenEstimator tsAlg = new TheilSenEstimator(arrangement.getLines(), arrangement.getNodes());
+ tsAlg.run();
+
+ List errors = sampsonError(arrangement.getLines(), tsAlg.getSlope(), tsAlg.getyInterception());
+ tsResult = getResults(errors);
+ });
+
+ lms.start();
+ rm.start();
+ ts.start();
+ lms.join();
+ rm.join();
+ ts.join();
+
+ for (int i=0;i<4;i++){
+ System.out.println("LMS: "+ lmsResult[i] + "\tTS: " + tsResult[i] + "\tRM: " + rmResult[i] + "\t");
+ }
+ }
+
+
+ public Double[] getResults(List errorValues){
+
+ Double[] ret = new Double[4];
+ ret[0] = mse(errorValues);
+ ret[1] = rmse(errorValues);
+ ret[2] = mae(errorValues);
+ ret[3] = mdae(errorValues);
+
+ return ret;
+
+ }
+
+ /* Skalierungs Abhängige Approximationsgüten */
+ public Double mse(List errorValues){
+ double error = 0;
+
+ for (Double d : errorValues){
+ error += Math.pow(d,2);
+ }
+
+ error /= errorValues.size();
+
+ return error;
+ }
+
+ public Double rmse(List errorValues){
+ return Math.sqrt(mse(errorValues));
+ }
+
+ public Double mae(List errorValues){
+ double error = 0;
+
+ for (Double d : errorValues){
+ error += Math.abs(d);
+ }
+
+ error /= errorValues.size();
+
+ return error;
+ }
+
+ public Double mdae(List errorValues){
+ return FastElementSelector.randomizedSelect((ArrayList) errorValues, errorValues.size()*0.5);
+ }
+
+
+ public List sampsonError(LinkedList lines, Double m, Double b){
+
+ //Liste mit den Fehler zu jedem Punkt
+ List sampsonrror = new ArrayList<>();
+
+ for (Line line : lines){
+ Double error = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m,2) + 1);
+ sampsonrror.add(error);
+ }
+
+ return sampsonrror;
+ }
+
+}
diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java
index 61c2305..2aa2e5f 100644
--- a/src/main/java/Presenter/Presenter.java
+++ b/src/main/java/Presenter/Presenter.java
@@ -31,37 +31,16 @@ public class Presenter implements Observer {
private Arrangement model;
private MainFrame view;
+ /* Threads */
+ private Thread tsThread;
+ private Thread rmThread;
+ private Thread lmsThread;
+ private Thread importThread;
+ private Thread generatorThread;
+
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 = {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]);
- 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); */
}
@@ -112,7 +91,7 @@ public class Presenter implements Observer {
});
setup();
Thread t = new Thread(() -> {
- calcArrangementNodes();
+ calculateIntersections();
});
t.start();
try {
@@ -138,35 +117,64 @@ public class Presenter implements Observer {
***************************************************************************************************************************/
public void calculateLMS(String[] input) {
if (input[0] != null && input[1] != null){
- Double constant = Double.parseDouble(input[0]);
- Double error = Double.parseDouble(input[1]);
- LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
- lms.setConstant(constant);
- lms.setQuantileError(error);
- lms.addObserver(this);
- lms.run();
- lms.getResult();
+ if (lmsThread == null || !lmsThread.isAlive()){
+ lmsThread = new Thread(() -> {
+ Double constant = Double.parseDouble(input[0]);
+ Double error = Double.parseDouble(input[1]);
+ LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
+ lms.setConstant(constant);
+ lms.setQuantileError(error);
+ lms.addObserver(this);
+ lms.run();
+ lms.getResult();
+ });
+ lmsThread.start();
+ try {
+ lmsThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
}
public void calculateRM(String input){
if (input != null){
- RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
- Double parameter = Double.parseDouble(input);
- rm.setBeta(parameter);
- rm.addObserver(this);
- rm.run();
- rm.getResult();
+ if (rmThread == null || !rmThread.isAlive()){
+ rmThread = new Thread(() -> {
+ RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
+ Double parameter = Double.parseDouble(input);
+ rm.setBeta(parameter);
+ rm.addObserver(this);
+ rm.run();
+ rm.getResult();
+ });
+ rmThread.start();
+ try {
+ rmThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
}
-
public void calculateTS(String input){
if (input != null){
- TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(),this);
- ts.addObserver(this);
- ts.run();
- ts.getResult();
+ if (tsThread == null || !tsThread.isAlive()){
+ tsThread = new Thread(() ->{
+ TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(),this);
+ ts.addObserver(this);
+ ts.run();
+ ts.getResult();
+ });
+ tsThread.start();
+ try {
+ tsThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
}
@@ -202,45 +210,9 @@ public class Presenter implements Observer {
getView().log("
");
}
- // 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() {
+ public void calculateIntersections() {
try {
Thread thread = new Thread(() -> {
- /*Double xMinimum = Double.MAX_VALUE;
- Double xMaximum = Double.MIN_VALUE;
- Double yMinimum = Double.MAX_VALUE;
- Double yMaximum = Double.MIN_VALUE;
-
- for (int i = 0; i < getLines().size(); i++) {
- for (int j = i; j < getLines().size(); j++) {
- if (i != j) {
- Point intersection = calcIntersection(getLines().get(j), getLines().get(i));
-
- if (intersection.getX() != Double.POSITIVE_INFINITY && intersection.getX() != Double.NEGATIVE_INFINITY &&
- intersection.getY() != Double.POSITIVE_INFINITY && intersection.getY() != Double.NEGATIVE_INFINITY ){
- xMinimum = xMinimum > intersection.getX() ? intersection.getX() : xMinimum;
- xMaximum = xMaximum < intersection.getX() ? intersection.getX() : xMaximum;
- yMinimum = yMinimum > intersection.getY() ? intersection.getY() : yMinimum;
- yMaximum = yMaximum < intersection.getY() ? intersection.getY() : yMaximum;
-
- model.addNode(intersection);
- }
- }
- }
- }
- model.setxMinimum(xMinimum);
- model.setxMaximum(xMaximum);
- model.setyMaximum(yMaximum);
- model.setyMinimum(yMinimum);*/
IntersectionCounter counter = new IntersectionCounter();
counter.run(getLines(), new Interval(-99999,99999));
counter.calculateIntersectionAbscissas(getModel());
@@ -255,34 +227,37 @@ public class Presenter implements Observer {
}
}
- public LinkedList calcArrangementLines() {
- LinkedList lineCoordinates = new LinkedList<>();
- double x1 = -1000;
- double x2 = 1000;
-
- for (Line point : model.getLines()) {
- double y1 = (point.getM() * x1 + point.getB());
- double y2 = (point.getM() * x2 + point.getB());
- Line line = new Line(x1, x2, y1, y2);
- line.setId(point.getId());
- lineCoordinates.add(line);
- }
-
- return lineCoordinates;
- }
-
public void startImport(File file){
- DataImporter importer = new DataImporter(file, this);
- importer.addObserver(this);
- importer.run();
+ if (importThread == null || !importThread.isAlive()){
+ importThread = new Thread(()->{
+ DataImporter importer = new DataImporter(file, this);
+ importer.addObserver(this);
+ importer.run();
+ });
+ importThread.start();
+ try {
+ importThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
public void generateDataset(){
- DatasetGenerator generator = new DatasetGenerator();
- getModel().setLines((LinkedList) generator.generateDataset());
- calcArrangementNodes();
- getView().enableFunctionality();
-
+ if (generatorThread == null || !generatorThread.isAlive()){
+ generatorThread = new Thread(() -> {
+ DatasetGenerator generator = new DatasetGenerator();
+ getModel().setLines(generator.generateDataset());
+ calculateIntersections();
+ getView().enableFunctionality();
+ });
+ generatorThread.start();
+ try {
+ generatorThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
/***************************************************************************************************************************
diff --git a/src/main/java/View/MainFrame.java b/src/main/java/View/MainFrame.java
index 52932ac..b6b45e8 100644
--- a/src/main/java/View/MainFrame.java
+++ b/src/main/java/View/MainFrame.java
@@ -81,7 +81,7 @@ public class MainFrame extends JFrame {
arrangementDialog.setSize(new Dimension(800, 800));
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
arrangement.clear();
- arrangement.setPrameters(getPresenter().calcArrangementLines(),
+ arrangement.setPrameters(getPresenter().getLines(),
getPresenter().getModel().getNodes(),
getPresenter().getModel().getxMinimum(),
getPresenter().getModel().getxMaximum(),
@@ -178,7 +178,7 @@ public class MainFrame extends JFrame {
}
private void setDimensions() {
- this.setMinimumSize(new Dimension(1366,768));
+ this.setMinimumSize(new Dimension(1024,768));
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
lmsPanel.setMinimumSize(new Dimension(400, 500));
rmPanel.setMinimumSize(new Dimension(400, 500));