reformated code

This commit is contained in:
Armin Wolf 2020-04-05 20:53:52 +02:00
parent d1e725d73f
commit 219c0d92f4
46 changed files with 498 additions and 406 deletions

View File

@ -35,7 +35,7 @@ sourceCompatibility = '11'
sonarqube {
properties {
property "sonar.projectName", "${rootProject.name}"
property "sonar.projectKey", "$project.group:$rootProject.name"
property "sonar.projectKey", "${project.group}:${rootProject.name}"
}
}

View File

@ -0,0 +1 @@
systemProp.sonar.host.url=http://192.168.0.158:9000

View File

@ -1,9 +1,9 @@
package de.wwwu.awolf;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.ViewController;
import de.wwwu.awolf.view.services.GuiRegisterService;
import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
@ -11,8 +11,6 @@ import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -22,7 +20,7 @@ import java.io.IOException;
*/
public class App extends Application {
private final String TITLE = "Algorithmen zur Berechnung von Ausgleichsgeraden";
private static final String TITLE = "Algorithmen zur Berechnung von Ausgleichsgeraden";
/**
* Maim Methode
@ -30,14 +28,7 @@ public class App extends Application {
* @param argv
*/
public static void main(String[] argv) {
//create instances
final Presenter presenter = Presenter.getInstance();
Logging.logDebug("Presenter initialized!");
//start gui
Platform.setImplicitExit(false);
Logging.logDebug("Start ....");
Application.launch(App.class, argv);
}
@ -46,13 +37,16 @@ public class App extends Application {
Platform.runLater(() -> {
try {
FXMLLoader fxmlLoader = new FXMLLoader(ViewController.class.getResource("/views/MainFrame.fxml"));
FXMLLoader fxmlLoader = new FXMLLoader(
ViewController.class.getResource("/views/MainFrame.fxml"));
Parent pane = fxmlLoader.load();
//register at presenter
new GuiRegisterService(fxmlLoader.getController()).start();
primaryStage.setTitle(TITLE);
Scene scene = new Scene(pane, 1200, 900);
scene.getStylesheets().add(ViewController.class.getResource("/style/style.css").toExternalForm());
scene.getStylesheets()
.add(ViewController.class.getResource("/style/style.css")
.toExternalForm());
primaryStage.setScene(scene);
primaryStage.setOnCloseRequest(e -> {
Platform.exit();

View File

@ -1,8 +1,7 @@
package de.wwwu.awolf.model;
import org.apache.commons.math3.util.Precision;
import java.util.Objects;
import org.apache.commons.math3.util.Precision;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -18,7 +17,6 @@ public class Line implements Comparable<Line> {
private static final double MAX = -9999d;
private Double m;
private Double b;
@ -195,7 +193,8 @@ public class Line implements Comparable<Line> {
public boolean equals(Object obj) {
if (obj instanceof Line) {
Line other = (Line) obj;
return Precision.equals(other.getM(), this.getM(), EPSILON) && Precision.equals(other.getB(), this.getB(), EPSILON);
return Precision.equals(other.getM(), this.getM(), EPSILON) && Precision
.equals(other.getB(), this.getB(), EPSILON);
} else {
return super.equals(obj);
}
@ -222,8 +221,10 @@ public class Line implements Comparable<Line> {
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
public boolean onSegment(Point p, Point q, Point r) {
return q.getX() <= Math.max(p.getX(), r.getX()) && q.getX() >= Math.min(p.getX(), r.getX()) &&
q.getY() <= Math.max(p.getY(), r.getY()) && q.getY() >= Math.min(p.getY(), r.getY());
return q.getX() <= Math.max(p.getX(), r.getX()) && q.getX() >= Math
.min(p.getX(), r.getX()) &&
q.getY() <= Math.max(p.getY(), r.getY()) && q.getY() >= Math
.min(p.getY(), r.getY());
}
// To find orientation of ordered triplet (p, q, r).
@ -235,9 +236,11 @@ public class Line implements Comparable<Line> {
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
double val = (q.getY() - p.getY()) * (r.getX() - q.getX()) -
(q.getX() - p.getX()) * (r.getY() - q.getY());
(q.getX() - p.getX()) * (r.getY() - q.getY());
if (val == 0) return 0; // colinear
if (val == 0) {
return 0; // colinear
}
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
@ -259,18 +262,25 @@ public class Line implements Comparable<Line> {
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
if (o1 != o2 && o3 != o4) {
return true;
}
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
if (o1 == 0 && onSegment(p1, p2, q1)) {
return true;
}
// p1, q1 and q2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
if (o2 == 0 && onSegment(p1, q2, q1)) {
return true;
}
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
if (o3 == 0 && onSegment(p2, p1, q2)) {
return true;
}
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
return o4 == 0 && onSegment(p2, q1, q2);// Doesn't fall in any of the above cases

View File

@ -1,8 +1,7 @@
package de.wwwu.awolf.model;
import org.apache.commons.math3.util.Precision;
import java.util.Objects;
import org.apache.commons.math3.util.Precision;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -90,7 +89,8 @@ public class Point implements Comparable<Point> {
public boolean equals(Object obj) {
if (obj instanceof Point) {
Point other = (Point) obj;
return Precision.equals(other.getX(), this.getX(), EPSILON) && Precision.equals(other.getY(), this.getY(), EPSILON);
return Precision.equals(other.getX(), this.getX(), EPSILON) && Precision
.equals(other.getY(), this.getY(), EPSILON);
} else {
return super.equals(obj);
}

View File

@ -1,6 +1,7 @@
package de.wwwu.awolf.model.communication;
public interface Data {
SubscriberType getType();
void setType(SubscriberType type);

View File

@ -1,12 +1,12 @@
package de.wwwu.awolf.model.communication;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public class EvaluationData implements Data {
private SubscriberType type;
private List<Algorithm.Type> algorithmtypes;
private List<Serializable> oneColumnresult;
@ -60,7 +60,8 @@ public class EvaluationData implements Data {
return multipleColumnResult;
}
public void setMultipleColumnResult(Map<Algorithm.Type, Map<String, String>> multipleColumnResult) {
public void setMultipleColumnResult(
Map<Algorithm.Type, Map<String, String>> multipleColumnResult) {
this.multipleColumnResult = multipleColumnResult;
}

View File

@ -1,6 +1,7 @@
package de.wwwu.awolf.model.communication;
public class TypeData implements Data {
private SubscriberType type;
@Override

View File

@ -2,7 +2,6 @@ package de.wwwu.awolf.model.evaluation;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import java.util.EnumMap;
import java.util.Map;

View File

@ -9,14 +9,13 @@ import de.wwwu.awolf.presenter.data.DataHandler;
import de.wwwu.awolf.presenter.evaluation.EvaluatationHandler;
import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.ViewController;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Flow;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -102,22 +101,22 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
* @param type algorithm type
* @param lines set of lines
*/
public void executeAlgorithmByType(Algorithm.Type type, Set<Line> lines, BooleanProperty guiFlag) {
public void executeAlgorithmByType(Algorithm.Type type, Set<Line> lines,
BooleanProperty guiFlag) {
this.algorithmHandler.runAlgorithmByType(type, lines, guiFlag);
}
/**
* Execute an algorithm specified by a type
* (use the Lines from the LineModel)
* Execute an algorithm specified by a type (use the Lines from the LineModel)
*
* @param type algorithm type
* @param type algorithm type
*/
public Line executeAlgorithmByType(Algorithm.Type type, BooleanProperty guiFlag) {
if (getModel().getSize() == 0) {
Logging.logDebug("No lines in the Model. Nothing to calculate.");
throw new IllegalArgumentException();
} else {
Logging.logDebug("AlgorithmHandler will start " + type.getName() + ", with " + getModel().getSize());
Logging.logDebug("AlgorithmHandler will start " + type.getLabel() + ", with " + getModel().getSize());
return this.algorithmHandler.runAlgorithmByType(type, getModel().getLines(), guiFlag);
}
}
@ -143,11 +142,8 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
this.view = view;
Logging.logDebug("View has been set.");
//customize gui
Platform.runLater(() -> {
this.view.initGui();
});
Platform.runLater(() -> this.view.initGui());
}
/**

View File

@ -7,11 +7,10 @@ import de.wwwu.awolf.model.communication.EvaluationData;
import de.wwwu.awolf.presenter.data.DataHandler;
import de.wwwu.awolf.presenter.evaluation.EvaluatationHandler;
import de.wwwu.awolf.presenter.util.Logging;
import javafx.application.Platform;
import javax.swing.*;
import java.io.File;
import java.util.Set;
import javafx.application.Platform;
import javax.swing.SwingUtilities;
/**
@ -41,16 +40,17 @@ public class Presenter extends AbstractPresenter {
protected void visualizeAlgorithm(Data data) {
AlgorithmData algorithmData = (AlgorithmData) data;
Platform.runLater(() -> {
getView().getAlgorithmTabControllers().get(algorithmData.getAlgorithmType()).updatePlot(getModel(), algorithmData.getLineData());
});
Platform.runLater(() -> getView().getAlgorithmTabControllers().get(algorithmData.getAlgorithmType()).updatePlot(getModel(), algorithmData.getLineData())
);
Logging.logInfo("Type: " + algorithmData.getType() + ". Result: " + algorithmData.getLineData().toString());
}
@Override
protected void evaluatedDatas(Data data) {
EvaluationData evaluationData = (EvaluationData) data;
SwingUtilities.invokeLater(() -> getView().appendEvalResults(evaluationData.getMultipleColumnResult()));
SwingUtilities
.invokeLater(
() -> getView().appendEvalResults(evaluationData.getMultipleColumnResult()));
}
/***************************************************************************************************************************
@ -87,9 +87,8 @@ public class Presenter extends AbstractPresenter {
getModel().setLines(data);
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
Logging.logInfo("Import was successful! ");
Platform.runLater(() -> {
getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null));
});
Platform.runLater(() -> getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null))
);
return data;
}
@ -103,15 +102,13 @@ public class Presenter extends AbstractPresenter {
Set<Line> data = getDataHandler().getData(type, n);
getModel().setLines(data);
Logging.logInfo("Generate was successful!");
Platform.runLater(() -> {
getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null));
});
Platform.runLater(() -> getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null))
);
return data;
}
/**
* Startet die Evaluation zu einen gegegbenen Typ mit den Informationen zu den Datensatz.
* Beispielsweise kann ein Alg. auf mit verschiedenen Datensätzen untersucht werden, oder mehrere Algorithmen
* Startet die Evaluation zu einen gegegbenen Typ mit den Informationen zu den Datensatz. Beispielsweise kann ein Alg. auf mit verschiedenen Datensätzen untersucht werden, oder mehrere Algorithmen
* auf einem gegebenen Datensatz.
*
* @param typ Typ der Evaluation
@ -124,9 +121,8 @@ public class Presenter extends AbstractPresenter {
}
/**
* Startet die Evaluation zu einen gegegbenen Datensatz, der importiert wird.
* Beispielsweise kann ein Alg. auf mit verschiedenen Datensätzen untersucht werden, oder mehrere Algorithmen
* auf einem gegebenen Datensatz.
* Startet die Evaluation zu einen gegegbenen Datensatz, der importiert wird. Beispielsweise kann ein Alg. auf mit verschiedenen Datensätzen untersucht werden, oder mehrere Algorithmen auf einem
* gegebenen Datensatz.
*
* @param typ Typ der Evaluation
* @param alg code für die auszuführenden Algorithmen (siehe <code>EvaluationPanel.checkSelection()</code> Method)

View File

@ -3,7 +3,6 @@ package de.wwwu.awolf.presenter.algorithms;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.communication.Data;
import de.wwwu.awolf.presenter.AbstractPresenter;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Flow;
@ -23,29 +22,28 @@ public interface Algorithm extends Callable<Line>, Flow.Publisher<Data> {
@Override
Line call();
enum Type {
LMS("Least Median of Squares"),
RM("Repeated Median"),
TS("Theil-Sen"),
NAIV_LMS("Brute Force (LMS)"),
NAIV_RM("Brute Force (RM)"),
NAIV_TS("Brute Force (TS)");
public final String name;
Type(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
void setInput(final Set<Line> lines);
Algorithm.Type getType();
void setPresenter(AbstractPresenter presenter);
enum Type {
LMS("Least Median of Squares"),
RM("Repeated Median"),
TS("Theil-Sen"),
NAIVE_LMS("Brute Force (LMS)"),
NAIVE_RM("Brute Force (RM)"),
NAIVE_TS("Brute Force (TS)");
public final String label;
Type(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
}

View File

@ -3,9 +3,6 @@ package de.wwwu.awolf.presenter.algorithms;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.util.Logging;
import javafx.beans.property.BooleanProperty;
import javax.annotation.Nullable;
import java.util.EnumMap;
import java.util.Map;
import java.util.ServiceLoader;
@ -13,6 +10,8 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import javafx.beans.property.BooleanProperty;
import javax.annotation.Nullable;
public class AlgorithmHandler {
@ -27,6 +26,7 @@ public class AlgorithmHandler {
/**
* Singleton getter
*
* @return instance of the singleton
*/
public static AlgorithmHandler getInstance() {
@ -39,10 +39,12 @@ public class AlgorithmHandler {
}
@Nullable
public Line runAlgorithmByType(final Algorithm.Type type, final Set<Line> setOfLines, final BooleanProperty guiFlag) {
public Line runAlgorithmByType(final Algorithm.Type type, final Set<Line> setOfLines,
final BooleanProperty guiFlag) {
if (guiFlag != null)
if (guiFlag != null) {
guiFlag.setValue(true);
}
//get the instance
Algorithm algorithm = algorithmMapping.get(type);
@ -52,20 +54,26 @@ public class AlgorithmHandler {
//get the executor
ExecutorService executor = Presenter.getInstance().getExecutor();
ExecutorCompletionService<Line> completionService = new ExecutorCompletionService<>(executor);
ExecutorCompletionService<Line> completionService = new ExecutorCompletionService<>(
executor);
completionService.submit(algorithm);
try {
return completionService.take().get();
} catch (InterruptedException e) {
Logging.logError("Interrupt Exception while waiting for result of Algorithm: " + algorithm.getType(), e);
Logging.logError(
"Interrupt Exception while waiting for result of Algorithm: " + algorithm
.getType(), e);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
Logging.logError("Execution Exception while computing the result of Algorithm: " + algorithm.getType(), e);
Logging.logError(
"Execution Exception while computing the result of Algorithm: " + algorithm
.getType(), e);
} finally {
if (guiFlag != null)
if (guiFlag != null) {
guiFlag.setValue(false);
}
}
return null;
}

View File

@ -10,8 +10,15 @@ import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.IntersectionComputer;
import de.wwwu.awolf.presenter.util.Logging;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Flow;
/**
@ -22,6 +29,7 @@ import java.util.concurrent.Flow;
* @Date: 28.05.2017.
*/
public class LeastMedianOfSquaresEstimator implements Algorithm {
private static final Algorithm.Type type = Type.LMS;
private List<Line> setOfLines;
@ -40,15 +48,12 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
private double slope;
private double yInterception;
private Flow.Subscriber<? super AlgorithmData> subscriber;
private AbstractPresenter presenter;
/**
* Algorithmus zum berechnen des LMS-Schätzers
* <p>
* Paper:
* Mount, David M, Nathan S Netanyahu, Kathleen Romanik, Ruth Silverman und Angela Y Wu
* A practical approximation algorithm for the LMS line estimator. 2007
* Computational statistics & data Analysis 51.5, S. 24612486
* Paper: Mount, David M, Nathan S Netanyahu, Kathleen Romanik, Ruth Silverman und Angela Y Wu A practical approximation algorithm for the LMS line estimator. 2007 Computational statistics &
* data Analysis 51.5, S. 24612486
*/
@Override
public Line call() {
@ -80,7 +85,6 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
heightsigmaMin = Double.MAX_VALUE;
//(3.) Apply the following steps as long as the exists active intervals
boolean active = true;
Interval interval;
while (!this.intervals.isEmpty()) {
interval = this.intervals.peek();
@ -94,11 +98,13 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
} else {
//(c.) otherwise....
// get random intersections point...
Collection<Point> tmpIntersections = IntersectionComputer.getInstance().compute(setOfLines, interval.getLower(), interval.getUpper());
Collection<Point> tmpIntersections = IntersectionComputer
.getInstance()
.compute(setOfLines, interval.getLower(), interval.getUpper());
boolean found = false;
for (Point tmpIntersection : tmpIntersections) {
if (tmpIntersection.getX() > interval.getLower()
&& tmpIntersection.getX() < interval.getUpper()) {
&& tmpIntersection.getX() < interval.getUpper()) {
intersectionsPoint = tmpIntersection.getX();
found = true;
break;
@ -146,7 +152,6 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
@Override
public void setPresenter(AbstractPresenter presenter) {
this.presenter = presenter;
subscribe(presenter);
}
@ -158,15 +163,14 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
* @return Anzahl der Schnittpunkte
*/
public int countInversions(Interval interval) {
return IntersectionComputer.getInstance().compute(setOfLines, interval.getLower(), interval.getUpper()).size();
return IntersectionComputer.getInstance()
.compute(setOfLines, interval.getLower(), interval.getUpper()).size();
}
/**
* In der Literatur wird ein planesweep vorrausgesetzt um in einem Intervall das minimale kMinus Segment zu
* identifizieren. An dieser Stelle wird eine naivere Lösung verwendet, mithilfe der Schleife werden alle
* Schnittpunkte betrachtet und bei passenden x-Koordinaten werden wird die vertikale Gerade auf kMinus Segmente
* untersucht.
* In der Literatur wird ein planesweep vorrausgesetzt um in einem Intervall das minimale kMinus Segment zu identifizieren. An dieser Stelle wird eine naivere Lösung verwendet, mithilfe der
* Schleife werden alle Schnittpunkte betrachtet und bei passenden x-Koordinaten werden wird die vertikale Gerade auf kMinus Segmente untersucht.
*
* @param interval
* @return
@ -175,7 +179,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
List<Point> xQueue = new ArrayList<>();
Collection<Point> points = IntersectionComputer.getInstance().compute(setOfLines, interval.getLower(), interval.getUpper());
Collection<Point> points = IntersectionComputer.getInstance()
.compute(setOfLines, interval.getLower(), interval.getUpper());
for (Point point : points) {
if (point.getX() >= interval.getLower() && point.getX() < interval.getUpper()) {
xQueue.add(point);
@ -193,7 +198,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
continue;
} else if (currentBracelet[0] < heightOfBracelet) {
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1],
currentBracelet[2]);
}
}
@ -202,8 +208,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
}
/**
* Diese Methode spaltet den aktiven Interval an der x Koordinate point. Es werden zwei neue Slabs
* erzeugt.
* Diese Methode spaltet den aktiven Interval an der x Koordinate point. Es werden zwei neue Slabs erzeugt.
*
* @param point x Koordinate an der, der Split geschieht.
*/
@ -215,8 +220,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
}
/**
* Zu einer vertikalen Gerade werden kMinus Segmente erzeugt und geprüft ob eine bessere Lösung
* als SigmaMin vorliegt.
* Zu einer vertikalen Gerade werden kMinus Segmente erzeugt und geprüft ob eine bessere Lösung als SigmaMin vorliegt.
*
* @param point x-Koordinate zur Konstruktion der vertikalen Gerade
*/
@ -237,10 +241,10 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
heightsigmaMin = height;
if (sigmaMin != null) {
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
, point, sortedLineSequence.get((i + kMinus) - 1));
, point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i),
sortedLineSequence.get((i + kMinus) - 1));
sortedLineSequence.get((i + kMinus) - 1));
}
}
}
@ -266,15 +270,17 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
List<Line> lines = new ArrayList<>();
for (Line p : setOfLines) {
lines.add(
new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()),
((pslab.getUpper() * p.getM()) + p.getB())));
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));
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]++;
@ -288,7 +294,6 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
strictlyGreater = 0;
}
//Teil II.
int i = 0;
double h;
@ -303,7 +308,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)),
Math.abs(umaxList.get(j) - umaxList.get(i)));
Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
pslab.setActivity(true);
@ -316,8 +321,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
}
/**
* Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte
* als e_j Werte bekannt.
* 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)
@ -336,8 +340,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
}
/**
* 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
* 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.
@ -352,8 +355,10 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
}
if (intersections.size() >= kMinusValue) {
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(kMinusValue - 1));
return new Double[]{height, intersections.get(0), intersections.get(kMinusValue - 1)};
double height = Math
.abs(intersections.get(0) - intersections.get(kMinusValue - 1));
return new Double[]{height, intersections.get(0),
intersections.get(kMinusValue - 1)};
} else {
return null;
}

View File

@ -12,8 +12,12 @@ import de.wwwu.awolf.presenter.util.FastElementSelector;
import de.wwwu.awolf.presenter.util.IntersectionComputer;
import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.presenter.util.RandomSampler;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Flow;
@ -59,10 +63,7 @@ public class RepeatedMedianEstimator implements Algorithm {
/**
* Führt den Algortihmus zur Berechnung des RM-Schätzers durch.
* <p>
* Paper:
* Matousek, Jiri, D. M. Mount und N. S. Netanyahu
* Efficient Randomized Algorithms for the Repeated Median Line Estimator. 1998
* Algorithmica 20.2, S. 136150
* Paper: Matousek, Jiri, D. M. Mount und N. S. Netanyahu Efficient Randomized Algorithms for the Repeated Median Line Estimator. 1998 Algorithmica 20.2, S. 136150
*/
public Line call() {
@ -103,7 +104,8 @@ public class RepeatedMedianEstimator implements Algorithm {
final double lowerBound = thetaLow;
final double upperBound = thetaHigh;
if (!lines.isEmpty()) {
lines.forEach(line -> medianIntersectionAbscissas.add(estimateMedianIntersectionAbscissas(lines, line)));
lines.forEach(line -> medianIntersectionAbscissas
.add(estimateMedianIntersectionAbscissas(lines, line)));
}
//Rang vom RM-Wert in C
@ -114,8 +116,10 @@ public class RepeatedMedianEstimator implements Algorithm {
//Berechne die Elemente mit dem Rang Theta_lo und Theta_hi
Collections.sort(medianIntersectionAbscissas);
thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow);
thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh);
thetaLow = FastElementSelector
.randomizedSelect(medianIntersectionAbscissas, kLow);
thetaHigh = FastElementSelector
.randomizedSelect(medianIntersectionAbscissas, kHigh);
//Für jede Gerade in C wird die Anzahl der Schnittpunkte die im Intervall liegen hochgezählt
countNumberOfIntersectionsAbscissas(thetaLow, thetaHigh);
@ -157,20 +161,26 @@ public class RepeatedMedianEstimator implements Algorithm {
*/
public Double estimateMedianIntersectionAbscissas(List<Line> lines, Line sampledLine) {
List<Double> intersections = IntersectionComputer.getInstance().calculateIntersectionAbscissas(lines, sampledLine, original.getLower(), original.getUpper());
List<Double> left = IntersectionComputer.getInstance().calculateIntersectionAbscissas(lines, sampledLine, original.getLower(), interval.getLower());
List<Double> center = IntersectionComputer.getInstance().calculateIntersectionAbscissas(lines, sampledLine, interval.getLower(), interval.getUpper());
List<Double> intersections = IntersectionComputer.getInstance()
.calculateIntersectionAbscissas(lines, sampledLine, original.getLower(),
original.getUpper());
List<Double> left = IntersectionComputer.getInstance()
.calculateIntersectionAbscissas(lines, sampledLine, original.getLower(),
interval.getLower());
List<Double> center = IntersectionComputer.getInstance()
.calculateIntersectionAbscissas(lines, sampledLine, interval.getLower(),
interval.getUpper());
double ki = Math.ceil((n - 1) * 0.5) - left.size();
double i = (Math.ceil((Math.sqrt(n) * ki) / center.size()));
int accessIndex;
if (i < 0)
if (i < 0) {
accessIndex = 0;
else if (i >= intersections.size() && !intersections.isEmpty())
} else if (i >= intersections.size() && !intersections.isEmpty()) {
accessIndex = intersections.size() - 1;
else
} else {
accessIndex = (int) i;
}
return FastElementSelector.randomizedSelect(intersections, accessIndex);
}
@ -180,40 +190,46 @@ public class RepeatedMedianEstimator implements Algorithm {
*/
public void computeSlabBorders() {
kLow = Math.max(1, Math.floor(((r * k) / (countCenterSlab))
- ((3 * Math.sqrt(r)) * (0.5))));
- ((3 * Math.sqrt(r)) * (0.5))));
kHigh = Math.min(r, Math.floor(((r * k) / (countCenterSlab))
+ ((3 * Math.sqrt(r)) * (0.5))));
+ ((3 * Math.sqrt(r)) * (0.5))));
}
/**
* Berechnet die Anzahl der Schnittpunkte pro Bereich. Insgesammt gibt es drei Bereiche:
* Im Intervall => (a,b], vor dem Intervall => (a', a], hinter dem Intervall => (b, b'].
* Berechnet die Anzahl der Schnittpunkte pro Bereich. Insgesammt gibt es drei Bereiche: Im Intervall => (a,b], vor dem Intervall => (a', a], hinter dem Intervall => (b, b'].
*/
public void countNumberOfIntersectionsAbscissas(final double lower, final double upper) {
IntersectionComputer instance = IntersectionComputer.getInstance();
intersectionsInLeftSlab = new HashSet<>(instance.compute(setOfLines, interval.getLower(), lower));
intersectionsInLeftSlab = new HashSet<>(
instance.compute(setOfLines, interval.getLower(), lower));
intersectionsInCenterSlab = new HashSet<>(instance.compute(setOfLines, lower, upper));
intersectionsInRightSlab = new HashSet<>(instance.compute(setOfLines, upper, interval.getUpper()));
intersectionsInRightSlab = new HashSet<>(
instance.compute(setOfLines, upper, interval.getUpper()));
int tmp = new HashSet<>(instance.compute(setOfLines, interval.getLower(), interval.getUpper())).size();
int tmp = new HashSet<>(
instance.compute(setOfLines, interval.getLower(), interval.getUpper()))
.size();
countLeftSlab = intersectionsInLeftSlab.size();
countCenterSlab = intersectionsInCenterSlab.size();
countRightSlab = intersectionsInRightSlab.size();
}
/**
* Verkleinert das aktuelle Intervall. Eines der drei Bereiche wird als neues Intervall gewählt.
* Auf diesem Intervall werden dann in der nächsten Iteration wieder drei Bereiche bestimmt.
* Verkleinert das aktuelle Intervall. Eines der drei Bereiche wird als neues Intervall gewählt. Auf diesem Intervall werden dann in der nächsten Iteration wieder drei Bereiche bestimmt.
*/
public void contractIntervals(final double lower, final double upper) {
double max = Math.max(countLeftSlab, Math.max(countCenterSlab, countRightSlab));
boolean newIntervalIsC = countLeftSlab < Math.ceil(n * 0.5) && Math.ceil(n * 0.5) <= countLeftSlab + countCenterSlab;
boolean newIntervalIsC =
countLeftSlab < Math.ceil(n * 0.5)
&& Math.ceil(n * 0.5) <= countLeftSlab + countCenterSlab;
boolean newIntervalIsL = Math.ceil(n * 0.5) <= countLeftSlab;
boolean newIntervalIsR = countLeftSlab + countCenterSlab < Math.ceil(n * 0.5) && Math.ceil(n * 0.5) <= (countLeftSlab + countCenterSlab + countRightSlab);
boolean newIntervalIsR =
countLeftSlab + countCenterSlab < Math.ceil(n * 0.5) && Math.ceil(n * 0.5) <= (
countLeftSlab
+ countCenterSlab + countRightSlab);
//wähle C als C
if (newIntervalIsC) {
@ -233,7 +249,8 @@ public class RepeatedMedianEstimator implements Algorithm {
potentialYInterceptions.add(line.getB() - (slope * line.getM()));
});
yInterception = FastElementSelector.randomizedSelect(potentialYInterceptions, Math.floor(potentialYInterceptions.size() * 0.5));
yInterception = FastElementSelector.randomizedSelect(potentialYInterceptions,
Math.floor(potentialYInterceptions.size() * 0.5));
if (this.subscriber != null) {
AlgorithmData data = new AlgorithmData();

View File

@ -12,8 +12,12 @@ import de.wwwu.awolf.presenter.util.BinomialCoeffizient;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import de.wwwu.awolf.presenter.util.IntersectionComputer;
import de.wwwu.awolf.presenter.util.RandomSampler;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Flow;
/**
@ -51,10 +55,8 @@ public class TheilSenEstimator implements Algorithm {
/**
* Randomisierter Algorithmus zur Berechnung des Theil-Sen Schätzers.
* Algorithmus stammt aus dem Paper:
* "Jiri Matousek, Randomized optimal algorithm for slope selection,
* Information Processing Letters 39 (1991) 183-187
* Randomisierter Algorithmus zur Berechnung des Theil-Sen Schätzers. Algorithmus stammt aus dem Paper: "Jiri Matousek, Randomized optimal algorithm for slope selection, Information Processing
* Letters 39 (1991) 183-187
*/
public Line call() {
@ -68,13 +70,16 @@ public class TheilSenEstimator implements Algorithm {
//Collections.sort(intervalIntersections);
r = n;
List<Point> intervalIntersections = new LinkedList<>(IntersectionComputer.getInstance().compute(setOfLines, interval.getLower(), interval.getUpper()));
List<Point> intervalIntersections = new LinkedList<>(IntersectionComputer.getInstance()
.compute(setOfLines, interval.getLower(), interval.getUpper()));
while (true) {
if (this.N <= n || (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
if (this.N <= n
|| (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
break;
} else {
//Anzahl der Schnittpunkte im Intervall [-Inf, a)
int numberOfIntersections = getIntervalSize(NEGATIV_INF, interval.getLower());
int numberOfIntersections = getIntervalSize(NEGATIV_INF,
interval.getLower());
//Randomized Interpolating Search
j = (r / N) * (double) (k - numberOfIntersections);
@ -87,15 +92,21 @@ public class TheilSenEstimator implements Algorithm {
das Intrvall weniger als 11*N / sqrt(r) Elemente besitzt */
do {
//zufällige Stichprobe
List<Point> sampledIntersections = RandomSampler.run(intervalIntersections, r);
List<Point> sampledIntersections = RandomSampler
.run(intervalIntersections, r);
aVariant = FastElementSelector.randomizedSelect(getIntersectionAbscissas(sampledIntersections), jA);
bVariant = FastElementSelector.randomizedSelect(getIntersectionAbscissas(sampledIntersections), jB);
aVariant = FastElementSelector
.randomizedSelect(getIntersectionAbscissas(sampledIntersections),
jA);
bVariant = FastElementSelector
.randomizedSelect(getIntersectionAbscissas(sampledIntersections),
jB);
} while (!checkCondition());
interval.setLower(aVariant);
interval.setUpper(bVariant);
intervalIntersections = getOpenIntervalElements(interval.getLower(), interval.getUpper());
intervalIntersections = getOpenIntervalElements(interval.getLower(),
interval.getUpper());
N = getIntervalSize(interval.getLower(), interval.getUpper());
}
}
@ -127,9 +138,8 @@ public class TheilSenEstimator implements Algorithm {
/**
* Diese Funktion überprüft ob die Bedingung für das Interval erfüllt ist. Dabei muss der k-te
* Schnittpunkt in diesem Interval enthalten sein. des weiteren soll die Anzahl der Schnittpunkte
* im Interval kleiner oder gleich dem Term: (11*N)/sqrt(r) sein.
* Diese Funktion überprüft ob die Bedingung für das Interval erfüllt ist. Dabei muss der k-te Schnittpunkt in diesem Interval enthalten sein. des weiteren soll die Anzahl der Schnittpunkte im
* Interval kleiner oder gleich dem Term: (11*N)/sqrt(r) sein.
*
* @return Boolscher Wert ob die Bedingung erfüllt ist
*/
@ -152,8 +162,8 @@ public class TheilSenEstimator implements Algorithm {
/**
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und <code>b</code>
* enthalten sind.
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und
* <code>b</code> enthalten sind.
*
* @param a untere Grenze des Intervals
* @param b obere Grenze des Intrvals
@ -164,16 +174,17 @@ public class TheilSenEstimator implements Algorithm {
}
/**
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und <code>b</code>
* enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste festgehalten und diese werden
* zurückgeliefert.
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und
* <code>b</code> enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste
* festgehalten und diese werden zurückgeliefert.
*
* @param a untere Grenze des Intervals
* @param b obere Grenze des Intrvals
* @return Liste der Schnittpunkte die im Interval (a,b) vertreten sind
*/
public List<Point> getOpenIntervalElements(double a, double b) {
Collection<Point> intersections = IntersectionComputer.getInstance().compute(setOfLines, a, b);
Collection<Point> intersections = IntersectionComputer.getInstance()
.compute(setOfLines, a, b);
return new ArrayList<>(intersections);
}
@ -181,7 +192,8 @@ public class TheilSenEstimator implements Algorithm {
double m, x;
double b, y;
List<Point> resultSt = getOpenIntervalElements(interval.getLower(), interval.getUpper());
List<Point> resultSt = getOpenIntervalElements(interval.getLower(),
interval.getUpper());
List<Double> resultAbscissas = new ArrayList<>();
for (Point p : resultSt) {

View File

@ -8,8 +8,11 @@ import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import de.wwwu.awolf.presenter.util.Logging;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Flow;
/**
@ -21,7 +24,7 @@ import java.util.concurrent.Flow;
*/
public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
private static final Algorithm.Type type = Type.NAIV_LMS;
private static final Algorithm.Type type = Type.NAIVE_LMS;
private List<Line> setOfLines = new ArrayList<>();
private int n;
@ -52,8 +55,14 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
triple.add(j);
triple.add(k);
Collections.sort(triple);
beta = (triple.get(0).getB() - triple.get(2).getB()) / (triple.get(0).getM() - triple.get(2).getM());
alpha = (triple.get(1).getB() + triple.get(2).getB() - (beta * (triple.get(1).getM() + triple.get(2).getM()))) * 0.5;
beta =
(triple.get(0).getB() - triple.get(2).getB()) / (
triple.get(0).getM() - triple.get(2)
.getM());
alpha =
(triple.get(1).getB() + triple.get(2).getB() - (beta * (
triple.get(1).getM() + triple
.get(2).getM()))) * 0.5;
dijk = f(alpha, beta);
if (dijk < ds) {
ds = dijk;
@ -66,7 +75,7 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
}
end = System.currentTimeMillis();
Logging.logInfo("=== E N D - naiv L M S ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());

View File

@ -9,8 +9,11 @@ import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import de.wwwu.awolf.presenter.util.Logging;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Flow;
/**
@ -22,7 +25,7 @@ import java.util.concurrent.Flow;
*/
public class NaivRepeatedMedianEstimator implements Algorithm {
private static final Algorithm.Type type = Type.NAIV_RM;
private static final Algorithm.Type type = Type.NAIVE_RM;
private List<Line> setOfLines;
private Map<String, List<Double>> slopesPerLine;
@ -86,7 +89,7 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
medianY = FastElementSelector.randomizedSelect(yMedians, yMedians.size() * 0.5);
end = System.currentTimeMillis();
Logging.logInfo("=== E N D - naiv R M ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
@ -136,7 +139,6 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
yi = endPoint.getB();
}
double m = (yj - yi) / (xj - xi);
double b = ((xj * yi) - (xi * yj)) / (xj - xi);
return new Point(m, b);

View File

@ -8,7 +8,6 @@ import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import de.wwwu.awolf.presenter.util.Logging;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@ -23,7 +22,7 @@ import java.util.concurrent.Flow;
*/
public class NaivTheilSenEstimator implements Algorithm {
private static final Algorithm.Type type = Type.NAIV_TS;
private static final Algorithm.Type type = Type.NAIVE_TS;
private List<Line> setOfLines;
private double slope;
@ -46,15 +45,16 @@ public class NaivTheilSenEstimator implements Algorithm {
double y = setOfLines.get(i).getB();
for (int j = i + 1; j < setOfLines.size(); j++) {
if (x != setOfLines.get(j).getM()) { // x must be different, otherwise slope becomes infinite
Double slope = (setOfLines.get(j).getB() - y) / (setOfLines.get(j).getM() - x);
if (x != setOfLines.get(j)
.getM()) { // x must be different, otherwise slope becomes infinite
Double slope =
(setOfLines.get(j).getB() - y) / (setOfLines.get(j).getM() - x);
slopesList.add(slope);
++cnt;
}
}
}
List<Double> list1 = new ArrayList<>();
List<Double> list2 = new ArrayList<>();
for (Line line : setOfLines) {
@ -67,7 +67,7 @@ public class NaivTheilSenEstimator implements Algorithm {
yInterception = median2 - slope * median1;
end = System.currentTimeMillis();
Logging.logInfo("=== E N D - naiv T S ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);

View File

@ -8,7 +8,6 @@ import de.wwwu.awolf.presenter.data.generator.LineDatasetGenerator;
import de.wwwu.awolf.presenter.data.io.DataExporter;
import de.wwwu.awolf.presenter.data.io.DataImporter;
import de.wwwu.awolf.presenter.util.Logging;
import java.io.File;
import java.util.Collections;
import java.util.Set;
@ -25,8 +24,9 @@ public class DataHandler {
public Set<Line> getData(final File file) {
//Presenter soll die Klasse überwachen
ExecutorCompletionService<Set<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
Logging.logDebug("Importing Data: " + file.getAbsolutePath());
ExecutorCompletionService<Set<Line>> completionService = new ExecutorCompletionService<>(
this.presenter.getExecutor());
Logging.logDebug("Importing Data: " + file.getAbsolutePath());
completionService.submit(new DataImporter(file));
//wait until future is ready
try {
@ -41,8 +41,9 @@ public class DataHandler {
public Set<Line> getData(final DataType type, final int dataSize) {
//Presenter soll die Klasse überwachen
ExecutorCompletionService<Set<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
Logging.logDebug("Generating Data: Size: " + dataSize + ", dataType: " + type.name());
ExecutorCompletionService<Set<Line>> completionService = new ExecutorCompletionService<>(
this.presenter.getExecutor());
Logging.logDebug("Generating Data: Size: " + dataSize + ", dataType: " + type.name());
switch (type) {
case CIRCLE:

View File

@ -1,12 +1,12 @@
package de.wwwu.awolf.presenter.data.generator;
import de.wwwu.awolf.model.Line;
import java.util.*;
import java.util.concurrent.Callable;
import static de.wwwu.awolf.presenter.data.generator.DatasetGenerator.generateDataLines;
import de.wwwu.awolf.model.Line;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -23,8 +23,7 @@ public class CircleDatasetGenerator implements Callable<Set<Line>> {
}
/**
* Generiert einen Datensatz des typen: Gerade mit zirkulärer Störung. Zuerst wird die
* zirkuläre Störung zu der Liste der (dualen-)Geraden hinzugefügt danach wird die wrapper Methode
* Generiert einen Datensatz des typen: Gerade mit zirkulärer Störung. Zuerst wird die zirkuläre Störung zu der Liste der (dualen-)Geraden hinzugefügt danach wird die wrapper Methode
* <code>generateDataLines()</code> aufgerufen.
*
* @return Liste der Geraden

View File

@ -1,7 +1,6 @@
package de.wwwu.awolf.presenter.data.generator;
import de.wwwu.awolf.model.Line;
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;
@ -33,7 +32,6 @@ public class CloudDatasetGenerator implements Callable<Set<Line>> {
double m = 1 + random.nextDouble();
double b = random.nextDouble();
for (int i = 1; i < (size + 1); i++) {
double y = (random.nextGaussian() * 100) % 100;
double signal = m * i + b;

View File

@ -1,7 +1,6 @@
package de.wwwu.awolf.presenter.data.generator;
import de.wwwu.awolf.model.Line;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
@ -26,8 +25,7 @@ public class DatasetGenerator {
/**
* Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine
* übergebene Liste hinzugefügt.
* Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine übergebene Liste hinzugefügt.
*
* @param n Größe des Datensatzes
* @return Liste des Geraden

View File

@ -1,7 +1,6 @@
package de.wwwu.awolf.presenter.data.generator;
import de.wwwu.awolf.model.Line;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;

View File

@ -3,7 +3,6 @@ package de.wwwu.awolf.presenter.data.io;
import com.opencsv.CSVWriter;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.util.Logging;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@ -33,9 +32,8 @@ public class DataExporter implements Runnable {
}
/**
* Diese Methode schreibt die Geraden der Form: y = mx + b, in eine Komma-Separierte Datei (CSV).
* Der Aufbau der Datei ist: id, m, b. Wenn der Export beendet wurde wird die Beobachter-Klasse informiert.
* In diesem Fall ist dies die Presenter Klasse.
* Diese Methode schreibt die Geraden der Form: y = mx + b, in eine Komma-Separierte Datei (CSV). Der Aufbau der Datei ist: id, m, b. Wenn der Export beendet wurde wird die Beobachter-Klasse
* informiert. In diesem Fall ist dies die Presenter Klasse.
*/
@Override
public void run() {
@ -57,6 +55,7 @@ public class DataExporter implements Runnable {
Logging.logError(e.getMessage(), e);
}
Logging.logInfo("The model has been successfully saved under: " + file.getAbsolutePath() + ".");
Logging.logInfo(
"The model has been successfully saved under: " + file.getAbsolutePath() + ".");
}
}

View File

@ -3,7 +3,6 @@ package de.wwwu.awolf.presenter.data.io;
import com.opencsv.CSVReader;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.util.Logging;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
@ -40,9 +39,8 @@ public class DataImporter implements Callable<Set<Line>> {
}
/**
* Diese Methode importiert liest zeile für zeile die Daten aus der Datei und baut eine Liste von Geraden auf.
* Dabei wird auf die richtige Form geachtet. Falls die Datei nicht, mindestens zwei Spalten enthält wird ein Fehler
* signalisiert und der Import wird abgebrochen.
* Diese Methode importiert liest zeile für zeile die Daten aus der Datei und baut eine Liste von Geraden auf. Dabei wird auf die richtige Form geachtet. Falls die Datei nicht, mindestens zwei
* Spalten enthält wird ein Fehler signalisiert und der Import wird abgebrochen.
*
* @return Liste der Geraden
*/
@ -74,7 +72,8 @@ public class DataImporter implements Callable<Set<Line>> {
result[2] = counter + "";
Thread.sleep(10);
} else {
Logging.logWarning("Diese Datei kann nicht importiert werden. Es müssen mindestens zwei Spalten enthalten sein (x,y). Fehler bei der Eingabe");
Logging.logWarning(
"Diese Datei kann nicht importiert werden. Es müssen mindestens zwei Spalten enthalten sein (x,y). Fehler bei der Eingabe");
return null;
}
}

View File

@ -4,7 +4,6 @@ import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.evaluation.ComparisonResult;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.algorithms.AlgorithmHandler;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletionService;

View File

@ -14,9 +14,14 @@ import de.wwwu.awolf.presenter.evaluation.measures.PercentageErrorBasedMeasure;
import de.wwwu.awolf.presenter.evaluation.measures.ScaleDependentMeasure;
import de.wwwu.awolf.presenter.evaluation.measures.ScaledErrorBasedMeasure;
import de.wwwu.awolf.presenter.util.Logging;
import java.io.File;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Flow;
/**
@ -43,13 +48,7 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
*
* @param type Typ der evaluation
* @param n Größe des Datensatzes
* @param alg 0 = lms,
* 1 = rm,
* 2 = ts,
* 3 = lms, rm,
* 4 = lms, ts,
* 5 = rm, ts,
* 6 = lms, rm, ts,
* @param alg 0 = lms, 1 = rm, 2 = ts, 3 = lms, rm, 4 = lms, ts, 5 = rm, ts, 6 = lms, rm, ts,
* @param datasettyp typ der zu generierenden Datensatz
*/
public EvaluatationHandler(int type, int n, int alg, DataHandler.DataType datasettyp) {
@ -73,13 +72,7 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
* Konstruktor zur evaluation
*
* @param type Typ der evaluation
* @param alg 0 = lms,
* 1 = rm,
* 2 = ts,
* 3 = lms, rm,
* 4 = lms, ts,
* 5 = rm, ts,
* 6 = lms, rm, ts,
* @param alg 0 = lms, 1 = rm, 2 = ts, 3 = lms, rm, 4 = lms, ts, 5 = rm, ts, 6 = lms, rm, ts,
* @param file Datei die importiert werden soll
*/
public EvaluatationHandler(int type, int alg, File file) {
@ -93,27 +86,36 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
this.alg = alg;
}
private Map<Algorithm.Type, Map<String, String>> benchmarkSameEstimator(final Algorithm.Type advanced, final Algorithm.Type naiv) {
Logging.logInfo("AlgorithmComparison with Types: " + advanced.name() + ", " + naiv.name());
AlgorithmComparison comparison = new AlgorithmComparison(Arrays.asList(naiv, advanced), Collections.unmodifiableSet(arrangement.getLines()));
private Map<Algorithm.Type, Map<String, String>> benchmarkSameEstimator(
final Algorithm.Type advanced, final Algorithm.Type naiv) {
Logging
.logInfo("AlgorithmComparison with Types: " + advanced.name() + ", " + naiv.name());
AlgorithmComparison comparison = new AlgorithmComparison(Arrays.asList(naiv, advanced),
Collections.unmodifiableSet(arrangement.getLines()));
ComparisonResult comparisonResult = comparison.compare();
Map<String, String> result = new HashMap<>();
result.putAll(getScaleDependentMeasure(arrangement.getLines(), comparisonResult, advanced));
result.putAll(getScaledErrorBasedMeasure(arrangement.getLines(), comparisonResult, advanced, naiv));
result.putAll(
getScaleDependentMeasure(arrangement.getLines(), comparisonResult, advanced));
result.putAll(
getScaledErrorBasedMeasure(arrangement.getLines(), comparisonResult, advanced,
naiv));
Logging.logInfo("finished with execution of the algorithms.");
this.resultMapping.put(advanced, result);
return this.resultMapping;
}
private Map<Algorithm.Type, Map<String, String>> benchmarkDifferentEstimators(List<Algorithm.Type> types) {
private Map<Algorithm.Type, Map<String, String>> benchmarkDifferentEstimators(
List<Algorithm.Type> types) {
Logging.logInfo("AlgorithmComparison with Types: " + types);
AlgorithmComparison comparison = new AlgorithmComparison(types, Collections.unmodifiableSet(arrangement.getLines()));
AlgorithmComparison comparison = new AlgorithmComparison(types,
Collections.unmodifiableSet(arrangement.getLines()));
ComparisonResult comparisonResult = comparison.compare();
types.forEach(typeEntry -> this.resultMapping.put(typeEntry, getPercentigeErrorBasedMeasure(arrangement.getLines(), comparisonResult, typeEntry)));
types.forEach(typeEntry -> this.resultMapping.put(typeEntry,
getPercentigeErrorBasedMeasure(arrangement.getLines(), comparisonResult,
typeEntry)));
Logging.logInfo("finished with execution of the algorithms.");
return this.resultMapping;
}
@ -129,26 +131,34 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
case 0:
//der alg der gewählt wurde
if (alg == 0) {
result = benchmarkSameEstimator(Algorithm.Type.LMS, Algorithm.Type.NAIV_LMS);
result = benchmarkSameEstimator(Algorithm.Type.LMS,
Algorithm.Type.NAIVE_LMS);
} else if (alg == 1) {
result = benchmarkSameEstimator(Algorithm.Type.RM, Algorithm.Type.NAIV_RM);
result = benchmarkSameEstimator(Algorithm.Type.RM,
Algorithm.Type.NAIVE_RM);
} else {
result = benchmarkSameEstimator(Algorithm.Type.TS, Algorithm.Type.NAIV_TS);
result = benchmarkSameEstimator(Algorithm.Type.TS,
Algorithm.Type.NAIVE_TS);
}
break;
case 1:
switch (alg) {
case 3:
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
break;
case 4:
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
break;
case 5:
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
break;
case 6:
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM, Algorithm.Type.TS));
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM,
Algorithm.Type.TS));
break;
}
break;
@ -176,7 +186,8 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
* @param lines Liste der Geraden
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
private Map<String, String> getScaleDependentMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
private Map<String, String> getScaleDependentMeasure(final Set<Line> lines,
final ComparisonResult comparisonResult, final Algorithm.Type type) {
Logging.logInfo("Calculating ScaleDependentMeasure for " + type);
@ -203,12 +214,15 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
* @param lines Liste der Geraden
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
private Map<String, String> getPercentigeErrorBasedMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
private Map<String, String> getPercentigeErrorBasedMeasure(final Set<Line> lines,
final ComparisonResult comparisonResult, final Algorithm.Type type) {
Logging.logInfo("Calculating PercentigeErrorBasedMeasure for " + type);
Double m = comparisonResult.get(type).getM();
Double b = comparisonResult.get(type).getB();
PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(lines, m, b);
PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(
lines,
m, b);
Map<String, String> ret = new HashMap<>();
ret.put(type + " MAPE", percentageErrorBasedMeasure.mape().toString());
ret.put(type + " MDAPE", percentageErrorBasedMeasure.mdape().toString());
@ -226,7 +240,9 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
* @param lines Liste der Geraden
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
private Map<String, String> getScaledErrorBasedMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type advanced, final Algorithm.Type naiv) {
private Map<String, String> getScaledErrorBasedMeasure(final Set<Line> lines,
final ComparisonResult comparisonResult, final Algorithm.Type advanced,
final Algorithm.Type naiv) {
Logging.logInfo("Calculating ScaledErrorBasedMeasure for " + advanced + ", " + naiv);
@ -237,7 +253,9 @@ public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
Double naivM = comparisonResult.get(naiv).getM();
Double naivB = comparisonResult.get(naiv).getB();
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b, naivM, naivB);
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m,
b,
naivM, naivB);
Map<String, String> ret = new HashMap<>();
ret.put(advanced + " MSE", scaledErrorBasedMeasure.mse().toString());
ret.put(advanced + " RMSE", scaledErrorBasedMeasure.rmse().toString());

View File

@ -2,7 +2,6 @@ package de.wwwu.awolf.presenter.evaluation.measures;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

View File

@ -2,7 +2,6 @@ package de.wwwu.awolf.presenter.evaluation.measures;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@ -86,6 +85,6 @@ public class ScaleDependentMeasure {
*/
public Double mdae() {
return FastElementSelector
.randomizedSelect(new ArrayList<>(errorValues), errorValues.size() * 0.5);
.randomizedSelect(new ArrayList<>(errorValues), errorValues.size() * 0.5);
}
}

View File

@ -2,7 +2,6 @@ package de.wwwu.awolf.presenter.evaluation.measures;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.util.FastElementSelector;
import java.util.ArrayList;
import java.util.Set;
@ -29,7 +28,8 @@ public class ScaledErrorBasedMeasure {
* @param naivSlope naive Steigung
* @param naivInterception naiver y-Achsenabschnitt
*/
public ScaledErrorBasedMeasure(final Set<Line> lines, Double m, Double b, Double naivSlope, Double naivInterception) {
public ScaledErrorBasedMeasure(final Set<Line> lines, Double m, Double b, Double naivSlope,
Double naivInterception) {
this.sampsonError = new ArrayList<>();
this.naivSampsonError = new ArrayList<>();
@ -37,7 +37,9 @@ public class ScaledErrorBasedMeasure {
//Sampson-Fehler der naiven Mehtode
for (Line line : lines) {
Double e = Math.pow(naivSlope * line.getM() - line.getB() + naivInterception, 2) / (Math.pow(naivSlope, 2) + 1);
Double e =
Math.pow(naivSlope * line.getM() - line.getB() + naivInterception, 2) / (
Math.pow(naivSlope, 2) + 1);
naivSampsonError.add(e);
}
@ -100,7 +102,7 @@ public class ScaledErrorBasedMeasure {
*/
public Double mdae() {
return FastElementSelector
.randomizedSelect(scaledError, scaledError.size() * 0.5);
.randomizedSelect(scaledError, scaledError.size() * 0.5);
}
}

View File

@ -8,6 +8,7 @@ package de.wwwu.awolf.presenter.util;
* @Date: 26.06.2017.
*/
public class BinomialCoeffizient {
/**
* Berechnet den Binomialkoeffizient zu der eingabe. Bin(n,k)
*
@ -18,8 +19,9 @@ public class BinomialCoeffizient {
public static Double run(int n, int k) {
int res = 1;
if (k > n - k)
if (k > n - k) {
k = n - k;
}
for (int i = 0; i < k; ++i) {
res *= (n - i);

View File

@ -1,7 +1,6 @@
package de.wwwu.awolf.presenter.util.Comparators;
import de.wwwu.awolf.model.Line;
import java.util.Comparator;
/**

View File

@ -1,7 +1,6 @@
package de.wwwu.awolf.presenter.util.Comparators;
import de.wwwu.awolf.model.Line;
import java.util.Comparator;
/**

View File

@ -3,8 +3,13 @@ package de.wwwu.awolf.presenter.util;
import com.google.common.collect.Lists;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.Point;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
@ -38,26 +43,29 @@ public class IntersectionComputer {
}
/**
* Berechnet zu einer gegebenen Menge von dualen Geraden die Schnittpunkte. Dafür wird ein modifizierter Merge-Sort
* Algorithmus verwendett. Um die Performance zu steigern wird die Berechnung ab einer passenden Größe auf vier
* Threads ausgelagert.
* Berechnet zu einer gegebenen Menge von dualen Geraden die Schnittpunkte. Dafür wird ein modifizierter Merge-Sort Algorithmus verwendett. Um die Performance zu steigern wird die Berechnung ab
* einer passenden Größe auf vier Threads ausgelagert.
*
* @param lower untere Schranke
* @param higher obere Schranke
* @return Liste der Schnittpunkte
*/
public Set<Point> compute(final Collection<Line> lines, final double lower, final double higher) {
public Set<Point> compute(final Collection<Line> lines, final double lower,
final double higher) {
final Set<Line> fullInput = new HashSet<>(lines);
final Set<Line> copyInput = new HashSet<>(lines);
if (lower == higher) {
return Collections.emptySet();
} else {
Logging.logDebug("Open ForkJoinPool: lines: " + lines.size() + " I(" + lower + ", " + higher + "]");
Logging.logDebug(
"Open ForkJoinPool: lines: " + lines.size() + " I(" + lower + ", " + higher
+ "]");
ForkJoinPool pool = ForkJoinPool.commonPool();
RecursiveComputationTask recursiveComputationTask = new RecursiveComputationTask(fullInput, copyInput, lower, higher);
RecursiveComputationTask recursiveComputationTask = new RecursiveComputationTask(
fullInput,
copyInput, lower, higher);
pool.execute(recursiveComputationTask);
Set<Point> join = recursiveComputationTask.join();
return join;
@ -71,7 +79,8 @@ public class IntersectionComputer {
* @param sampledLine eine spezielle Gerade
* @return Liste mit x Koordinaten der Schnittpunkte
*/
public List<Double> calculateIntersectionAbscissas(Collection<Line> set, Line sampledLine, double lower, double upper) {
public List<Double> calculateIntersectionAbscissas(Collection<Line> set, Line sampledLine,
double lower, double upper) {
List<Line> lines = new LinkedList<>(set);
Set<Double> intersections = new HashSet<>();
@ -95,7 +104,8 @@ public class IntersectionComputer {
private final double lower;
private final double upper;
public RecursiveComputationTask(final Set<Line> fullList, final Set<Line> lines, final double lower, final double upper) {
public RecursiveComputationTask(final Set<Line> fullList, final Set<Line> lines,
final double lower, final double upper) {
this.lines = lines;
this.fullList = fullList;
this.lower = lower;
@ -107,7 +117,9 @@ public class IntersectionComputer {
if (this.lines.isEmpty()) {
return Collections.emptySet();
} else if (this.lines.size() > THRESHOLD) {
return ForkJoinTask.invokeAll(createSubTask()).stream().map(ForkJoinTask::join).flatMap(Collection::stream).collect(Collectors.toSet());
return ForkJoinTask.invokeAll(createSubTask()).stream()
.map(ForkJoinTask::join)
.flatMap(Collection::stream).collect(Collectors.toSet());
} else {
return work(this.fullList, this.lines, this.lower, this.upper);
}
@ -130,14 +142,20 @@ public class IntersectionComputer {
}
});
dividedTasks.add(new RecursiveComputationTask(this.fullList, firstSubSet, this.lower, this.upper));
dividedTasks.add(new RecursiveComputationTask(this.fullList, secondSubSet, this.lower, this.upper));
dividedTasks
.add(new RecursiveComputationTask(this.fullList, firstSubSet, this.lower,
this.upper));
dividedTasks
.add(new RecursiveComputationTask(this.fullList, secondSubSet, this.lower,
this.upper));
return dividedTasks;
}
private Set<Point> work(Set<Line> fullList, Set<Line> lines, double lower, double higher) {
private Set<Point> work(Set<Line> fullList, Set<Line> lines, double lower,
double higher) {
Set<Point> points = new HashSet<>();
List<List<Line>> lists = Lists.cartesianProduct(new ArrayList<>(fullList), new ArrayList<>(lines));
List<List<Line>> lists = Lists
.cartesianProduct(new ArrayList<>(fullList), new ArrayList<>(lines));
lists.forEach(entry -> {
if (entry.get(0).doIntersect(entry.get(1), lower, upper)) {
Point intersect = entry.get(0).intersect(entry.get(1));

View File

@ -4,6 +4,7 @@ package de.wwwu.awolf.presenter.util;
import org.apache.log4j.Logger;
public class Logging {
private static Logger logger = Logger.getRootLogger();
private Logging() {
@ -11,7 +12,6 @@ public class Logging {
}
private static Logger getLogger() {
return logger;
}

View File

@ -1,6 +1,5 @@
package de.wwwu.awolf.view;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
@ -8,17 +7,22 @@ import de.wwwu.awolf.presenter.data.DataHandler;
import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.controller.AlgorithmTabController;
import de.wwwu.awolf.view.services.DataService;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -37,15 +41,15 @@ public class ViewController {
private MenuBar menuBar;
private Map<Algorithm.Type, AlgorithmTabController> algorithmTabControllers;
public Map<Algorithm.Type, AlgorithmTabController> getAlgorithmTabControllers() {
return algorithmTabControllers;
}
public ViewController() {
super();
this.algorithmTabControllers = new EnumMap<>(Algorithm.Type.class);
}
public Map<Algorithm.Type, AlgorithmTabController> getAlgorithmTabControllers() {
return algorithmTabControllers;
}
public void initGui() {
initMenuBar();
initTabbedPane();
@ -59,11 +63,11 @@ public class ViewController {
props.put("sdfdsfg", "dsadasd");
props.put("dsfsdfsdf", "dsadasd");
try {
for (Algorithm.Type value : Algorithm.Type.values()) {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(AlgorithmTabController.class.getResource("/views/AlgorithmTab.fxml"));
loader.setLocation(
AlgorithmTabController.class.getResource("/views/AlgorithmTab.fxml"));
Parent parent = loader.load();
AlgorithmTabController controller = loader.getController();
controller.setAlgorithmType(value);
@ -71,7 +75,7 @@ public class ViewController {
controller.setModel(Presenter.getInstance().getModel());
controller.init();
this.algorithmTabControllers.put(value, controller);
Tab tab = new Tab(value.getName(), parent);
Tab tab = new Tab(value.getLabel(), parent);
tab.setId(value.name());
tabPane.getTabs().add(tab);
}
@ -122,7 +126,8 @@ public class ViewController {
MenuItem generationItem = new MenuItem("Generate");
generationItem.setOnAction(actionEvent -> {
new DataService(DataHandler.ActionType.GENERATE, DataHandler.DataType.LINE, 1000).start();
new DataService(DataHandler.ActionType.GENERATE, DataHandler.DataType.LINE, 1000)
.start();
});
MenuItem evaluationItem = new MenuItem("Evaluate");
@ -136,7 +141,6 @@ public class ViewController {
}
/*******************************************************************************************************************
* visualisierungs methoden
******************************************************************************************************************/

View File

@ -4,6 +4,7 @@ import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.LineModel;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.view.services.ButtonClickService;
import java.util.Map;
import javafx.beans.property.BooleanProperty;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
@ -16,22 +17,19 @@ import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import java.util.Map;
public class AlgorithmTabController {
private final XYChart.Series<Double, Double> dataSerie;
private final XYChart.Series<Double, Double> lineSerie;
private Algorithm.Type algorithmType;
private Map<String, String> properties;
private LineModel model;
@FXML
public LineChart<Double, Double> chart;
@FXML
public VBox vBox;
@FXML
public Button startButton;
private Algorithm.Type algorithmType;
private Map<String, String> properties;
private LineModel model;
public AlgorithmTabController() {
dataSerie = new XYChart.Series<>();
@ -72,9 +70,10 @@ public class AlgorithmTabController {
BooleanProperty booleanProperty = startButton.disableProperty();
startButton.setOnAction(event -> {
ButtonClickService buttonClickService = new ButtonClickService(algorithmType, booleanProperty);
buttonClickService.start();
}
ButtonClickService buttonClickService = new ButtonClickService(algorithmType,
booleanProperty);
buttonClickService.start();
}
);
updatePlot(this.model, null);
@ -84,7 +83,9 @@ public class AlgorithmTabController {
public void updatePlot(final LineModel model, final Line pLine) {
dataSerie.getData().clear();
model.getLines().forEach(line -> dataSerie.getData().add(new XYChart.Data<>(line.getM(), line.getB())));
model.getLines()
.forEach(
line -> dataSerie.getData().add(new XYChart.Data<>(line.getM(), line.getB())));
if (pLine != null) {
lineSerie.getData().clear();

View File

@ -24,7 +24,8 @@ public class ButtonClickService extends Service<Boolean> {
@Override
protected Boolean call() throws Exception {
try {
Line line = Presenter.getInstance().executeAlgorithmByType(type, startButtonDisabled);
Line line = Presenter.getInstance()
.executeAlgorithmByType(type, startButtonDisabled);
if (line != null) {
return true;
}

View File

@ -2,11 +2,10 @@ package de.wwwu.awolf.view.services;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.data.DataHandler;
import java.io.File;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import java.io.File;
public class DataService extends Service<Boolean> {
private File file;
@ -14,7 +13,8 @@ public class DataService extends Service<Boolean> {
private DataHandler.ActionType actionType;
private int n;
public DataService(final DataHandler.ActionType actionType, final DataHandler.DataType type, final int n) {
public DataService(final DataHandler.ActionType actionType, final DataHandler.DataType type,
final int n) {
this.type = type;
this.actionType = actionType;
this.n = n;

View File

@ -1,55 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane prefHeight="400.0" prefWidth="600.0" styleClass="algoPane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.wwwu.awolf.view.controller.AlgorithmTabController">
<left>
<VBox fx:id="vBox" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
</children>
<cursor>
<Cursor fx:constant="HAND" />
</cursor>
<BorderPane.margin>
<Insets left="10.0" />
</BorderPane.margin>
<padding>
<Insets top="10.0" />
</padding>
</VBox>
</left>
<top>
<FlowPane hgap="5.0" prefHeight="25.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="startButton" alignment="CENTER" contentDisplay="CENTER" defaultButton="true" pickOnBounds="false" text="Start">
<cursor>
<Cursor fx:constant="HAND" />
</cursor>
</Button>
</children>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</FlowPane>
</top>
<center>
<LineChart fx:id="chart" prefHeight="398.0" prefWidth="390.0" title="Plot" BorderPane.alignment="CENTER">
<xAxis>
<NumberAxis label="X" side="BOTTOM">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding></NumberAxis>
</xAxis>
<yAxis>
<NumberAxis label="Y" side="LEFT">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding></NumberAxis>
</yAxis>
</LineChart>
</center>
<?import javafx.geometry.Insets?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.VBox?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="600.0"
styleClass="algoPane" xmlns="http://javafx.com/javafx/10.0.2-internal"
fx:controller="de.wwwu.awolf.view.controller.AlgorithmTabController">
<center>
<LineChart BorderPane.alignment="CENTER" prefHeight="398.0" prefWidth="390.0" title="Plot"
fx:id="chart">
<xAxis>
<NumberAxis label="X" side="BOTTOM">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</NumberAxis>
</xAxis>
<yAxis>
<NumberAxis label="Y" side="LEFT">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</NumberAxis>
</yAxis>
</LineChart>
</center>
<left>
<VBox BorderPane.alignment="CENTER" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="200.0"
fx:id="vBox">
<BorderPane.margin>
<Insets left="10.0"/>
</BorderPane.margin>
<children>
</children>
<cursor>
<Cursor fx:constant="HAND"/>
</cursor>
<padding>
<Insets top="10.0"/>
</padding>
</VBox>
</left>
<top>
<FlowPane BorderPane.alignment="CENTER" hgap="5.0" prefHeight="25.0" prefWidth="200.0">
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</BorderPane.margin>
<children>
<Button alignment="CENTER" contentDisplay="CENTER" defaultButton="true" pickOnBounds="false"
text="Start" fx:id="startButton">
<cursor>
<Cursor fx:constant="HAND"/>
</cursor>
</Button>
</children>
</FlowPane>
</top>
</BorderPane>

View File

@ -1,18 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane prefHeight="632.0" prefWidth="1118.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.wwwu.awolf.view.ViewController">
<top>
<MenuBar fx:id="menuBar" BorderPane.alignment="CENTER"/>
</top>
<left>
</left>
<center>
<TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER">
<tabs>
</tabs>
</TabPane>
</center>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="632.0" prefWidth="1118.0"
xmlns="http://javafx.com/javafx/10.0.2-internal"
fx:controller="de.wwwu.awolf.view.ViewController">
<center>
<TabPane BorderPane.alignment="CENTER" prefHeight="200.0" prefWidth="200.0"
tabClosingPolicy="UNAVAILABLE"
fx:id="tabPane">
<tabs>
</tabs>
</TabPane>
</center>
<left>
</left>
<top>
<MenuBar BorderPane.alignment="CENTER" fx:id="menuBar"/>
</top>
</BorderPane>

View File

@ -3,10 +3,9 @@ package de.wwwu.awolf.presenter.algorithms.advanced;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.algorithms.AlgorithmHandler;
import org.junit.Before;
import java.util.HashSet;
import java.util.Set;
import org.junit.Before;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -22,11 +21,10 @@ public class LeastMedianOfSquaresEstimatorTest {
private Line line;
@Before
public void setUp(){
public void setUp() {
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
lines = new HashSet<>();
for (int i = 0; i < 5; i++) {

View File

@ -1,10 +1,9 @@
package de.wwwu.awolf.presenter.algorithms.advanced;
import de.wwwu.awolf.model.Line;
import org.junit.Before;
import java.util.LinkedList;
import java.util.List;
import org.junit.Before;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -17,11 +16,10 @@ public class TheilSenEstimatorTest {
@Before
public void setUp(){
public void setUp() {
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
List<Line> lines = new LinkedList<>();
for (int i = 0; i < 5; i++) {

View File

@ -1,12 +1,11 @@
package de.wwwu.awolf.presenter.util;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.

View File

@ -1,14 +1,13 @@
package de.wwwu.awolf.presenter.util;
import static org.junit.Assert.assertEquals;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.LineModel;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -23,18 +22,19 @@ public class IntersectionCounterTest {
@Before
public void setUp() throws Exception {
lineModel = new LineModel();
lineModel.addLine(new Line(3,13,10,3));
lineModel.addLine(new Line(1,9,1,9));
lineModel.addLine(new Line(1,12,4,6));
for (Line l :lineModel.getLines()) {
System.out.println("Steigung: "+l.getM()+"\t y-Achsenabschnitt: "+l.getB());
lineModel.addLine(new Line(3, 13, 10, 3));
lineModel.addLine(new Line(1, 9, 1, 9));
lineModel.addLine(new Line(1, 12, 4, 6));
for (Line l : lineModel.getLines()) {
System.out.println("Steigung: " + l.getM() + "\t y-Achsenabschnitt: " + l.getB());
}
}
@Test
public void run() throws Exception {
IntersectionComputer instance = IntersectionComputer.getInstance();
assertEquals(3, IntersectionComputer.getInstance().compute(new ArrayList<>(lineModel.getLines()), -9999,9999).size());
assertEquals(3, IntersectionComputer.getInstance()
.compute(new ArrayList<>(lineModel.getLines()), -9999, 9999).size());
}
}