further clean up
This commit is contained in:
parent
21c072fe7a
commit
a246f8f203
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +1,12 @@
|
|||
package de.wwwu.awolf;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.LineModel;
|
||||
import de.wwwu.awolf.model.Point;
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
||||
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
import de.wwwu.awolf.view.MainFrame;
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
|
@ -49,44 +34,12 @@ public class App {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Methode rechnet für gegebene Größen die Algorithmen durch und gibt jeweils die benötigte Zeit
|
||||
*/
|
||||
public static void benchmark() {
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(6);
|
||||
|
||||
Logging.logInfo("---- Datasetgröße: " + 100 + " ----");
|
||||
DatasetGenerator generator = new DatasetGenerator();
|
||||
LinkedList<Line> lines = generator.generateDataCloud(10000);
|
||||
IntersectionComputer computer = new IntersectionComputer(lines);
|
||||
ArrayList<Point> points = computer.compute();
|
||||
|
||||
executorService.submit(new NaivLeastMedianOfSquaresEstimator(lines));
|
||||
executorService.submit(new NaivRepeatedMedianEstimator(lines));
|
||||
executorService.submit(new NaivTheilSenEstimator(lines));
|
||||
executorService.submit(new LeastMedianOfSquaresEstimator(lines, points));
|
||||
executorService.submit(new RepeatedMedianEstimator(lines));
|
||||
executorService.submit(new TheilSenEstimator(lines, points));
|
||||
}
|
||||
|
||||
/**
|
||||
* Maim Methode
|
||||
*
|
||||
* @param argv
|
||||
*/
|
||||
public static void main(String[] argv) {
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption("benchmark", "Start stresstest");
|
||||
options.addOption("", "default");
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
|
||||
try {
|
||||
CommandLine line = parser.parse(options, argv); // Sensitive
|
||||
String[] args = line.getArgs();
|
||||
if (args.length > 0 && args[0].equals("benchmark")) {
|
||||
benchmark();
|
||||
} else {
|
||||
final Presenter presenter = new Presenter(new LineModel(), null);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
MainFrame view = new MainFrame();
|
||||
|
@ -101,10 +54,7 @@ public class App {
|
|||
view.setActionListeners();
|
||||
presenter.setView(view);
|
||||
});
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
Logging.logError("Error while parsing the command line arguments.", e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,44 @@ 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<Double> oneColumnresult;
|
||||
private List<List<String>> multipleColumnResult;
|
||||
private List<Serializable> oneColumnresult;
|
||||
private Map<Algorithm.Type, Map<String, String>> multipleColumnResult;
|
||||
|
||||
private int rowsPerColumn;
|
||||
private int column;
|
||||
private List<String> labels;
|
||||
|
||||
public int getRowsPerColumn() {
|
||||
return rowsPerColumn;
|
||||
}
|
||||
|
||||
public void setRowsPerColumn(int rowsPerColumn) {
|
||||
this.rowsPerColumn = rowsPerColumn;
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
public void setColumn(int col) {
|
||||
this.column = col;
|
||||
}
|
||||
|
||||
public List<String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public void setLabels(List<String> tableInput) {
|
||||
this.labels = tableInput;
|
||||
}
|
||||
|
||||
public List<Algorithm.Type> getAlgorithmtypes() {
|
||||
return algorithmtypes;
|
||||
}
|
||||
|
@ -20,19 +48,19 @@ public class EvaluationData implements Data {
|
|||
this.algorithmtypes = algorithmtype;
|
||||
}
|
||||
|
||||
public List<Double> getOneColumnresult() {
|
||||
public List<Serializable> getOneColumnresult() {
|
||||
return oneColumnresult;
|
||||
}
|
||||
|
||||
public void setOneColumnresult(List<Double> oneColumnresult) {
|
||||
public void setOneColumnresult(List<Serializable> oneColumnresult) {
|
||||
this.oneColumnresult = oneColumnresult;
|
||||
}
|
||||
|
||||
public List<List<String>> getMultipleColumnResult() {
|
||||
public Map<Algorithm.Type, Map<String, String>> getMultipleColumnResult() {
|
||||
return multipleColumnResult;
|
||||
}
|
||||
|
||||
public void setMultipleColumnResult(List<List<String>> multipleColumnResult) {
|
||||
public void setMultipleColumnResult(Map<Algorithm.Type, Map<String, String>> multipleColumnResult) {
|
||||
this.multipleColumnResult = multipleColumnResult;
|
||||
}
|
||||
|
||||
|
@ -45,12 +73,4 @@ public class EvaluationData implements Data {
|
|||
public void setType(SubscriberType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setColumn(int col) {
|
||||
this.column = col;
|
||||
}
|
||||
|
||||
public void setLabels(List<String> tableInput) {
|
||||
this.labels = tableInput;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package de.wwwu.awolf.model.communication;
|
||||
|
||||
public class ExportData implements Data {
|
||||
|
||||
private SubscriberType type;
|
||||
private String message;
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriberType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(SubscriberType type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -2,17 +2,14 @@ package de.wwwu.awolf.model.communication;
|
|||
|
||||
public enum SubscriberType {
|
||||
|
||||
EVALUATE_DATASET_GENERATED,
|
||||
EVAL_D,
|
||||
EVAL_DS,
|
||||
EVALUATION_TABLE_DATA,
|
||||
EVAL_T,
|
||||
LINES_RES,
|
||||
LINES_RES_MULT,
|
||||
LMS,
|
||||
RM,
|
||||
TS,
|
||||
IMPORT,
|
||||
PICTURE,
|
||||
EXPORT,
|
||||
GENERATOR
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
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;
|
||||
|
||||
public class ComparisonResult {
|
||||
|
||||
private final Map<Algorithm.Type, Line> resultMapping;
|
||||
|
||||
public ComparisonResult() {
|
||||
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||
}
|
||||
|
||||
public void put(final Algorithm.Type type, final Line lineResult) {
|
||||
this.resultMapping.put(type, lineResult);
|
||||
}
|
||||
|
||||
public Line get(final Algorithm.Type type) {
|
||||
return this.resultMapping.get(type);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package de.wwwu.awolf.presenter;
|
|||
|
||||
import de.wwwu.awolf.model.LineModel;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
||||
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
@ -25,6 +26,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
private LineModel model;
|
||||
private MainFrame view;
|
||||
private EvaluateAlgorithms eval;
|
||||
private DataProvider dataProvider;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
|
@ -36,6 +38,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
this.model = model;
|
||||
this.view = view;
|
||||
executor = Executors.newCachedThreadPool();
|
||||
dataProvider = new DataProvider(this);
|
||||
|
||||
}
|
||||
|
||||
|
@ -49,21 +52,9 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
@Override
|
||||
public void onNext(Data data) {
|
||||
switch (data.getType()) {
|
||||
case EVAL_D:
|
||||
evaluatedData(data);
|
||||
break;
|
||||
case EVAL_DS:
|
||||
case EVALUATION_TABLE_DATA:
|
||||
evaluatedDatas(data);
|
||||
break;
|
||||
case EVAL_T:
|
||||
evaluatedTypes(data);
|
||||
break;
|
||||
case LINES_RES:
|
||||
visualizeResults(data);
|
||||
break;
|
||||
case LINES_RES_MULT:
|
||||
visualizeMultipleData(data);
|
||||
break;
|
||||
case LMS:
|
||||
visualizeLmsAlgorithm(data);
|
||||
break;
|
||||
|
@ -73,12 +64,6 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
case TS:
|
||||
visualizeTsAlgorithm(data);
|
||||
break;
|
||||
case IMPORT:
|
||||
handleImport(data);
|
||||
break;
|
||||
case EXPORT:
|
||||
handleExport(data);
|
||||
break;
|
||||
case GENERATOR:
|
||||
Logging.logInfo("Generierung war Erfolgreich");
|
||||
break;
|
||||
|
@ -87,26 +72,14 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void handleExport(Data data);
|
||||
|
||||
protected abstract void handleImport(Data data);
|
||||
|
||||
protected abstract void visualizeTsAlgorithm(Data data);
|
||||
|
||||
protected abstract void visualizeRmAlgorithm(Data data);
|
||||
|
||||
protected abstract void visualizeLmsAlgorithm(Data data);
|
||||
|
||||
protected abstract void visualizeMultipleData(Data data);
|
||||
|
||||
protected abstract void visualizeResults(Data data);
|
||||
|
||||
protected abstract void evaluatedTypes(Data data);
|
||||
|
||||
protected abstract void evaluatedDatas(Data data);
|
||||
|
||||
protected abstract void evaluatedData(Data data);
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
|
||||
|
@ -143,7 +116,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
start = System.currentTimeMillis();
|
||||
startIntersectionCalculation();
|
||||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + (end - start) / 1000);
|
||||
Logging.logInfo("Computing intersections took " + (end - start) / 1000 + "ms");
|
||||
});
|
||||
|
||||
//darstellung der Ergebnisse
|
||||
|
@ -200,7 +173,15 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
|||
this.eval = eval;
|
||||
}
|
||||
|
||||
public DataProvider getDataProvider() {
|
||||
return dataProvider;
|
||||
}
|
||||
|
||||
|
||||
public ExecutorService getExecutor() {
|
||||
if (executor == null)
|
||||
return Executors.newCachedThreadPool();
|
||||
else
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,12 @@ import de.wwwu.awolf.model.Line;
|
|||
import de.wwwu.awolf.model.LineModel;
|
||||
import de.wwwu.awolf.model.communication.AlgorithmData;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.model.communication.ExportData;
|
||||
import de.wwwu.awolf.model.communication.ImportData;
|
||||
import de.wwwu.awolf.model.communication.EvaluationData;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
||||
import de.wwwu.awolf.presenter.evaluation.PictureProcessor;
|
||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
||||
import de.wwwu.awolf.presenter.io.DataExporter;
|
||||
import de.wwwu.awolf.presenter.io.DataImporter;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
import de.wwwu.awolf.view.MainFrame;
|
||||
|
||||
|
@ -36,33 +32,12 @@ public class Presenter extends AbstractPresenter {
|
|||
super(model, view);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleExport(Data data) {
|
||||
ExportData exportData = (ExportData) data;
|
||||
Logging.logInfo(exportData.getMessage());
|
||||
Logging.logInfo("Export der Daten als CSV");
|
||||
Logging.logInfo("Export war Erfolgreich");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleImport(Data data) {
|
||||
ImportData importData = (ImportData) data;
|
||||
double max = importData.getNumberOfLines();
|
||||
double current = importData.getCurrent();
|
||||
Integer progress = (int) (100 * (current / max));
|
||||
//100% erreicht
|
||||
Logging.logInfo("Import war erfolgreich!");
|
||||
SwingUtilities.invokeLater(() -> getView().showImportProgress(progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visualizeTsAlgorithm(Data data) {
|
||||
AlgorithmData algorithmData = (AlgorithmData) data;
|
||||
SwingUtilities.invokeLater(() -> getView().visualizeTS(algorithmData.getLineData()));
|
||||
Logging.logInfo("Theil-Sen Estimator");
|
||||
Logging.logInfo(algorithmData.getLineData().toString());
|
||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,7 +46,6 @@ public class Presenter extends AbstractPresenter {
|
|||
SwingUtilities.invokeLater(() -> getView().visualizeRM(algorithmData.getLineData()));
|
||||
Logging.logInfo("Repeated Median Estimator");
|
||||
Logging.logInfo(algorithmData.getLineData().toString());
|
||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,34 +54,12 @@ public class Presenter extends AbstractPresenter {
|
|||
SwingUtilities.invokeLater(() -> getView().visualizeLMS(algorithmData.getLineData()));
|
||||
Logging.logInfo("Least Median of Squares");
|
||||
Logging.logInfo(algorithmData.getLineData().toString());
|
||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visualizeMultipleData(Data data) {
|
||||
//Result:
|
||||
//0:
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visualizeResults(Data data) {
|
||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void evaluatedTypes(Data data) {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void evaluatedDatas(Data data) {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void evaluatedData(Data data) {
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), false));
|
||||
EvaluationData evaluationData = (EvaluationData) data;
|
||||
SwingUtilities.invokeLater(() -> getView().appendEvalResults(evaluationData.getMultipleColumnResult()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,14 +80,13 @@ public class Presenter extends AbstractPresenter {
|
|||
if (input[0] != null && input[1] != null) {
|
||||
//Parameter für den Algortihmus
|
||||
Double constant = Double.parseDouble(input[0]);
|
||||
Double error = Double.parseDouble(input[1]);
|
||||
double error = Double.parseDouble(input[1]);
|
||||
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||
//setzen der Parameter
|
||||
lms.setConstant(constant);
|
||||
lms.setQuantileError(error);
|
||||
//Presenter soll die Klasse überwachen
|
||||
getExecutor().execute(lms);
|
||||
|
||||
getExecutor().submit(lms);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -151,8 +102,7 @@ public class Presenter extends AbstractPresenter {
|
|||
Double parameter = Double.parseDouble(input);
|
||||
rm.setBeta(parameter);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(rm);
|
||||
getExecutor().submit(rm);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +116,7 @@ public class Presenter extends AbstractPresenter {
|
|||
if (input != null) {
|
||||
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(ts);
|
||||
getExecutor().submit(ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,41 +130,12 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param file importierender Datensatz
|
||||
*/
|
||||
public void startImport(File file) {
|
||||
|
||||
DataImporter importer = new DataImporter(file, this);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Line> importedLines = importer.run();
|
||||
if (importedLines != null) {
|
||||
List<Line> data = getDataProvider().getData(file);
|
||||
if (data != null) {
|
||||
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
|
||||
getModel().setLines(importedLines);
|
||||
getModel().setLines(data);
|
||||
computeIntersections();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Startet den Import eines Bildes.
|
||||
*
|
||||
* @param file importierendes Bild
|
||||
*/
|
||||
public void startPictureDataImport(File file) {
|
||||
PictureProcessor pictureProcessor = new PictureProcessor(this, file);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pictureProcessor.run();
|
||||
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
|
||||
computeIntersections();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -225,15 +145,7 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param file Datei in der die Informationen gespeichert werden sollen
|
||||
*/
|
||||
public void startExport(File file) {
|
||||
DataExporter exporter = new DataExporter(getModel().getLines(), file, this);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
exporter.export();
|
||||
}
|
||||
});
|
||||
getDataProvider().exportData(file, getModel().getLines());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,15 +154,7 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param file Datei in der die Informationen gespeichert werden sollen
|
||||
*/
|
||||
public void startDatasetExportEvaluation(File file) {
|
||||
DataExporter exporter = new DataExporter(getEval().getData(), file, this);
|
||||
//Presenter soll die Klasse überwachen
|
||||
|
||||
getExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
exporter.export();
|
||||
}
|
||||
});
|
||||
getDataProvider().exportData(file, getEval().getData());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,23 +163,11 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param n Größe des Datensatzes
|
||||
* @param type Art der Datensatzes
|
||||
*/
|
||||
public void generateDataset(int n, int type) {
|
||||
DatasetGenerator generator = new DatasetGenerator(this);
|
||||
getExecutor().execute(() -> {
|
||||
switch (type) {
|
||||
case 1:
|
||||
getModel().setLines(generator.generateDataLines(n));
|
||||
break;
|
||||
case 2:
|
||||
getModel().setLines(generator.generateCircle(n));
|
||||
break;
|
||||
default:
|
||||
getModel().setLines(generator.generateDataCloud(n));
|
||||
break;
|
||||
}
|
||||
public void generateDataset(int n, DataProvider.DataType type) {
|
||||
List<Line> data = getDataProvider().getData(type, n);
|
||||
getModel().setLines(data);
|
||||
computeIntersections();
|
||||
getView().enableFunctionality();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,14 +178,10 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param typ Typ der Evaluation
|
||||
* @param n Größe des Datensatzes
|
||||
* @param alg code für die auszuführenden Algorithmen (siehe <code>EvaluationPanel.checkSelection()</code> Method)
|
||||
* @param datasettyp Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
||||
* @param datasetTyp Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
||||
*/
|
||||
public void startEvaluation(int typ, int n, int alg, String datasettyp) {
|
||||
setEval(new EvaluateAlgorithms(typ, n, alg, datasettyp, this));
|
||||
|
||||
getExecutor().submit(() -> {
|
||||
getEval().run();
|
||||
});
|
||||
public void startEvaluation(int typ, int n, int alg, DataProvider.DataType datasetTyp) {
|
||||
getExecutor().submit(new EvaluateAlgorithms(typ, n, alg, datasetTyp, this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,14 +194,6 @@ public class Presenter extends AbstractPresenter {
|
|||
* @param file Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
||||
*/
|
||||
public void startEvaluation(int typ, int alg, File file) {
|
||||
|
||||
EvaluateAlgorithms evaluateAlgorithms = new EvaluateAlgorithms(typ, alg, file);
|
||||
if (evaluateAlgorithms.getData().size() > 0) {
|
||||
setEval(evaluateAlgorithms);
|
||||
|
||||
}
|
||||
getExecutor().submit(() -> {
|
||||
getEval().run();
|
||||
}).isDone();
|
||||
getExecutor().submit(new EvaluateAlgorithms(typ, alg, file, this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package de.wwwu.awolf.presenter.algorithms;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
|
@ -7,7 +11,14 @@ package de.wwwu.awolf.presenter.algorithms;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 28.05.2017.
|
||||
*/
|
||||
public interface Algorithm extends Runnable {
|
||||
public interface Algorithm extends Callable<Line> {
|
||||
|
||||
/**
|
||||
* Startet die Berechnung des jeweiligen Algorithmus.
|
||||
*/
|
||||
@Override
|
||||
Line call();
|
||||
|
||||
|
||||
enum Type {
|
||||
LMS,
|
||||
|
@ -17,16 +28,4 @@ public interface Algorithm extends Runnable {
|
|||
NAIV_RM,
|
||||
NAIV_TS
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Startet die Berechnung des jeweiligen Algorithmus.
|
||||
*/
|
||||
@Override
|
||||
void run();
|
||||
|
||||
/**
|
||||
* Standardisierung der Lösung in Form (m,b), sodass die Geraden Visualisiert werden können.
|
||||
*/
|
||||
void pepareResult();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
|||
import de.wwwu.awolf.presenter.util.IntersectionCounter;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
|
@ -82,7 +81,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
* „A practical approximation algorithm for the LMS line estimator“. 2007
|
||||
* Computational statistics & data Analysis 51.5, S. 2461–2486
|
||||
*/
|
||||
public void run() {
|
||||
@Override
|
||||
public Line call() {
|
||||
|
||||
Logging.logInfo("=== S T A R T - L M S ===");
|
||||
long start;
|
||||
|
@ -103,7 +103,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
intervals = new PriorityQueue<>(comparator);
|
||||
intervals.add(new Interval(-100000, 100000));
|
||||
heightsigmaMin = Double.MAX_VALUE;
|
||||
List<Point> tmpIntersections = intersections;
|
||||
List<Point> tmpIntersections = new ArrayList<>(intersections);
|
||||
|
||||
//(3.) Apply the following steps as long as the exists active intervals
|
||||
boolean active = true;
|
||||
|
@ -120,7 +120,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
} else {
|
||||
//(c.) otherwise....
|
||||
// get random intersections point...
|
||||
Collections.shuffle(tmpIntersections, new SecureRandom());
|
||||
Collections.shuffle(tmpIntersections);
|
||||
boolean found = false;
|
||||
for (Point tmpIntersection : tmpIntersections) {
|
||||
if (tmpIntersection.getX() > interval.getLower()
|
||||
|
@ -156,7 +156,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||
|
||||
pepareResult();
|
||||
return pepareResult();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,8 +367,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
private Line pepareResult() {
|
||||
if (this.subscriber != null) {
|
||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||
|
@ -387,6 +386,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
|
||||
return new Line(getSlope(), getYInterception());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,7 +456,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
|||
/**
|
||||
* @return y-Achsenabschnitt
|
||||
*/
|
||||
public Double getyInterception() {
|
||||
public Double getYInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
|||
* „Efficient Randomized Algorithms for the Repeated Median Line Estimator“. 1998
|
||||
* Algorithmica 20.2, S. 136–150
|
||||
*/
|
||||
public void run() {
|
||||
public Line call() {
|
||||
|
||||
Logging.logInfo("=== S T A R T - R M ===");
|
||||
long start;
|
||||
|
@ -145,7 +145,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
|||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||
|
||||
pepareResult();
|
||||
return pepareResult();
|
||||
}
|
||||
|
||||
|
||||
|
@ -252,8 +252,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
private Line pepareResult() {
|
||||
if (this.subscriber != null) {
|
||||
double m = thetaLow;
|
||||
double b = (-1) * (
|
||||
|
@ -272,6 +271,8 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
|||
slope = m;
|
||||
yInterception = b;
|
||||
}
|
||||
|
||||
return new Line(getSlope(), getyInterception());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -95,7 +95,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
|||
* "Jiri Matousek, Randomized optimal algorithm for slope selection,
|
||||
* Information Processing Letters 39 (1991) 183-187
|
||||
*/
|
||||
public void run() {
|
||||
public Line call() {
|
||||
//damit eine initiale Ordnung herscht
|
||||
//Collections.sort(intervalIntersections);
|
||||
|
||||
|
@ -130,7 +130,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
|||
}
|
||||
}
|
||||
|
||||
pepareResult();
|
||||
return pepareResult();
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,8 +216,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
|||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
private Line pepareResult() {
|
||||
double m, x;
|
||||
double b, y;
|
||||
|
||||
|
@ -248,6 +247,8 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
|||
data.setLineData(new Line(m, b));
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
|
||||
return new Line(getSlope(), getYInterception());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,7 +261,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
|||
/**
|
||||
* @return y-Achsenabschnitt
|
||||
*/
|
||||
public Double getyInterception() {
|
||||
public Double getYInterception() {
|
||||
return yInterception;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
|||
/**
|
||||
* Crude Algorithmus zum berechnen des LSM-Schätzers.
|
||||
*/
|
||||
private void crudeAlg() {
|
||||
private Line crudeAlg() {
|
||||
ds = Double.MAX_VALUE;
|
||||
b = 0d;
|
||||
m = 0d;
|
||||
|
@ -70,6 +70,8 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
|||
}
|
||||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||
|
||||
return new Line(getSlope(), getYInterception());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,26 +90,21 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
crudeAlg();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
|
||||
public Line call() {
|
||||
return crudeAlg();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y-Achsenabschnitt
|
||||
*/
|
||||
public Double getB() {
|
||||
public Double getYInterception() {
|
||||
return b * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Steigung
|
||||
*/
|
||||
public Double getM() {
|
||||
public Double getSlope() {
|
||||
return m * -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public Line call() {
|
||||
//init the List for the slopes
|
||||
Logging.logInfo("=== S T A R T - naiv R M ===");
|
||||
long start;
|
||||
|
@ -87,11 +87,8 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
|||
medianY = FastElementSelector.randomizedSelect(yMedians, yMedians.size() * 0.5);
|
||||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
|
||||
return new Line(getSlope(), getYInterception());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,14 +125,14 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
|||
/**
|
||||
* @return Steigung
|
||||
*/
|
||||
public double getM() {
|
||||
public double getSlope() {
|
||||
return medianX * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y-Achsenabschnitt
|
||||
*/
|
||||
public double getB() {
|
||||
public double getYInterception() {
|
||||
return medianY * -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class NaivTheilSenEstimator implements Algorithm {
|
|||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public Line call() {
|
||||
Logging.logInfo("=== S T A R T - naiv T S ===");
|
||||
long start;
|
||||
long end;
|
||||
|
@ -68,24 +68,22 @@ public class NaivTheilSenEstimator implements Algorithm {
|
|||
yInterception = median2 - slope * median1;
|
||||
end = System.currentTimeMillis();
|
||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||
|
||||
return new Line(getSlope(), getYInterception());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pepareResult() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Steigung
|
||||
*/
|
||||
public double getM() {
|
||||
public double getSlope() {
|
||||
return slope * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y-Achsenabschnitt
|
||||
*/
|
||||
public double getB() {
|
||||
public double getYInterception() {
|
||||
return yInterception * -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package de.wwwu.awolf.presenter.data;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.AbstractPresenter;
|
||||
import de.wwwu.awolf.presenter.data.generator.CircleDatasetGenerator;
|
||||
import de.wwwu.awolf.presenter.data.generator.CloudDatasetGenerator;
|
||||
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.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
|
||||
public class DataProvider {
|
||||
|
||||
private final AbstractPresenter presenter;
|
||||
|
||||
public DataProvider(AbstractPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public List<Line> getData(final File file) {
|
||||
//Presenter soll die Klasse überwachen
|
||||
ExecutorCompletionService<List<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
|
||||
completionService.submit(new DataImporter(file));
|
||||
//wait until future is ready
|
||||
try {
|
||||
return completionService.take().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Logging.logError("Interrupted while importing... ", e);
|
||||
Thread.currentThread().interrupt();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<Line> getData(final DataType type, final int dataSize) {
|
||||
//Presenter soll die Klasse überwachen
|
||||
ExecutorCompletionService<List<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
|
||||
|
||||
switch (type) {
|
||||
case CIRCLE:
|
||||
completionService.submit(new CircleDatasetGenerator(dataSize));
|
||||
break;
|
||||
case LINE:
|
||||
completionService.submit(new LineDatasetGenerator(dataSize));
|
||||
break;
|
||||
case CLOUD:
|
||||
completionService.submit(new CloudDatasetGenerator(dataSize));
|
||||
break;
|
||||
default:
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
return completionService.take().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Logging.logError("Interrupted while generating... ", e);
|
||||
Thread.currentThread().interrupt();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public void exportData(File file, List<Line> lines) {
|
||||
this.presenter.getExecutor().submit(new DataExporter(lines, file));
|
||||
}
|
||||
|
||||
|
||||
public enum DataType {
|
||||
CLOUD,
|
||||
LINE,
|
||||
CIRCLE
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package de.wwwu.awolf.presenter.data.generator;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static de.wwwu.awolf.presenter.data.generator.DatasetGenerator.generateDataLines;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class CircleDatasetGenerator implements Callable<List<Line>> {
|
||||
|
||||
private final int size;
|
||||
|
||||
public CircleDatasetGenerator(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@Override
|
||||
public List<Line> call() throws Exception {
|
||||
List<Line> lines = new LinkedList<>();
|
||||
|
||||
double from = 0;
|
||||
double to = Math.PI * 5;
|
||||
//obere Grenze für die neuen Punkte
|
||||
int n = size / 2 + lines.size();
|
||||
|
||||
//calculate the distance between every two points
|
||||
double distance = (to - from) / ((double) n);
|
||||
|
||||
//create points
|
||||
double currentDistance = from;
|
||||
//an die aktuelle Liste dranhängen
|
||||
for (int i = lines.size(); i < n; i++) {
|
||||
double x = Math.cos(currentDistance);
|
||||
double y = Math.sin(currentDistance);
|
||||
|
||||
Line line = new Line(x, y);
|
||||
line.setId(i + "");
|
||||
lines.add(line);
|
||||
|
||||
//distance for the next iteration
|
||||
currentDistance += distance;
|
||||
}
|
||||
|
||||
int generateSize = (int) (size * 0.5);
|
||||
|
||||
return generateDataLines(lines, generateSize);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package de.wwwu.awolf.presenter.data.generator;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class CloudDatasetGenerator implements Callable<List<Line>> {
|
||||
|
||||
private final int size;
|
||||
|
||||
public CloudDatasetGenerator(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert zu einer gegebenen Größe einen Datensatz des typen: Punktwolke
|
||||
*
|
||||
* @return Liste der Geraden
|
||||
*/
|
||||
public List<Line> generateDataCloud() {
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
SecureRandom random = new SecureRandom();
|
||||
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;
|
||||
signal *= -1;
|
||||
|
||||
Line line = new Line(i, signal - y);
|
||||
line.setId(i - 1 + "");
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Line> call() throws Exception {
|
||||
return generateDataCloud();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package de.wwwu.awolf.presenter.data.generator;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class DatasetGenerator {
|
||||
|
||||
private static SecureRandom random;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*/
|
||||
private DatasetGenerator() {
|
||||
random = new SecureRandom();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public static List<Line> generateDataLines(List<Line> lines, int n) {
|
||||
double m = 5d;
|
||||
double b = 0d;
|
||||
|
||||
int size = 0;
|
||||
Map<Double, Double> points = new HashMap<>();
|
||||
|
||||
//speichere die Koordinaten in einer HashMap, damit keine Punkte
|
||||
//entstehen deren x-Koordinate zu sehr beieinander liegt.
|
||||
while (size < n) {
|
||||
double y = random.nextGaussian();
|
||||
double signal = m * y + b;
|
||||
signal *= -1;
|
||||
|
||||
if (!points.containsKey(y)) {
|
||||
points.put(y, signal);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = lines.size();
|
||||
for (Double d : points.keySet()) {
|
||||
Line line = new Line(d, points.get(d));
|
||||
line.setId(idx + "");
|
||||
lines.add(line);
|
||||
idx++;
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package de.wwwu.awolf.presenter.data.generator;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class LineDatasetGenerator implements Callable<List<Line>> {
|
||||
|
||||
private final int size;
|
||||
|
||||
|
||||
public LineDatasetGenerator(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper Methode zum generieren eines Datensatzes des typen: Gerade
|
||||
*
|
||||
* @return Liste des Geraden
|
||||
*/
|
||||
@Override
|
||||
public List<Line> call() throws Exception {
|
||||
return DatasetGenerator.generateDataLines(new ArrayList<>(), size);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
package de.wwwu.awolf.presenter.io;
|
||||
package de.wwwu.awolf.presenter.data.io;
|
||||
|
||||
import com.opencsv.CSVWriter;
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.model.communication.ExportData;
|
||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
|
@ -20,11 +17,10 @@ import java.util.concurrent.Flow;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 03.08.2017.
|
||||
*/
|
||||
public class DataExporter implements Flow.Publisher<Data> {
|
||||
public class DataExporter implements Runnable {
|
||||
|
||||
private List<Line> lines;
|
||||
private File file;
|
||||
private Flow.Subscriber<? super Data> subscriber;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
|
@ -32,10 +28,9 @@ public class DataExporter implements Flow.Publisher<Data> {
|
|||
* @param lines Liste der Geraden
|
||||
* @param file Datei in die, die Informationen exportiert werden sollen
|
||||
*/
|
||||
public DataExporter(List<Line> lines, File file, Flow.Subscriber<Data> subscriber) {
|
||||
public DataExporter(List<Line> lines, File file) {
|
||||
this.file = file;
|
||||
this.lines = lines;
|
||||
subscribe(subscriber);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +38,8 @@ public class DataExporter implements Flow.Publisher<Data> {
|
|||
* 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.
|
||||
*/
|
||||
public void export() {
|
||||
@Override
|
||||
public void run() {
|
||||
CSVWriter writer = null;
|
||||
|
||||
try {
|
||||
|
@ -57,20 +53,11 @@ public class DataExporter implements Flow.Publisher<Data> {
|
|||
writer.writeNext(entries);
|
||||
}
|
||||
writer.close();
|
||||
String[] ret = {"export", "Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert."};
|
||||
|
||||
ExportData data = new ExportData();
|
||||
data.setType(SubscriberType.EXPORT);
|
||||
data.setMessage("Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert.");
|
||||
this.subscriber.onNext(data);
|
||||
} catch (IOException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
||||
this.subscriber = subscriber;
|
||||
Logging.logInfo("The model has been successfully saved under: " + file.getAbsolutePath() + ".");
|
||||
}
|
||||
}
|
|
@ -1,10 +1,7 @@
|
|||
package de.wwwu.awolf.presenter.io;
|
||||
package de.wwwu.awolf.presenter.data.io;
|
||||
|
||||
import com.opencsv.CSVReader;
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.model.communication.ImportData;
|
||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -14,7 +11,7 @@ import java.io.FileReader;
|
|||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Flow;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -24,18 +21,16 @@ import java.util.concurrent.Flow;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 21.06.2017.
|
||||
*/
|
||||
public class DataImporter implements Flow.Publisher<Data> {
|
||||
public class DataImporter implements Callable<List<Line>> {
|
||||
|
||||
private CSVReader reader;
|
||||
private Flow.Subscriber<? super Data> subscriber;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param file Datei aus der die Informationen imortiert werden sollen.
|
||||
*/
|
||||
public DataImporter(File file, Flow.Subscriber<? super Data> subscriber) {
|
||||
subscribe(subscriber);
|
||||
public DataImporter(File file) {
|
||||
|
||||
try {
|
||||
this.reader = new CSVReader(new FileReader(file));
|
||||
|
@ -51,7 +46,8 @@ public class DataImporter implements Flow.Publisher<Data> {
|
|||
*
|
||||
* @return Liste der Geraden
|
||||
*/
|
||||
public List<Line> run() {
|
||||
@Override
|
||||
public List<Line> call() throws Exception {
|
||||
List<Line> list = new LinkedList<>();
|
||||
try {
|
||||
List<String[]> lines = reader.readAll();
|
||||
|
@ -69,9 +65,6 @@ public class DataImporter implements Flow.Publisher<Data> {
|
|||
counter++;
|
||||
result[2] = counter + "";
|
||||
Thread.sleep(10);
|
||||
|
||||
|
||||
communicate(counter, lines.size());
|
||||
} else if (nextLine.length == 2) {
|
||||
double x = Double.parseDouble(nextLine[1]);
|
||||
double y = Double.parseDouble(nextLine[2]) * (-1);
|
||||
|
@ -84,8 +77,6 @@ public class DataImporter implements Flow.Publisher<Data> {
|
|||
counter++;
|
||||
result[2] = counter + "";
|
||||
Thread.sleep(10);
|
||||
|
||||
communicate(counter, lines.size());
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(null, "Diese Datei kann nicht importiert werden." +
|
||||
"Es müssen mindestens zwei Spalten enthalten sein (x,y).", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||
|
@ -101,18 +92,4 @@ public class DataImporter implements Flow.Publisher<Data> {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void communicate(int counter, int size) {
|
||||
// communication
|
||||
ImportData data = new ImportData();
|
||||
data.setType(SubscriberType.IMPORT);
|
||||
data.setCurrent(counter);
|
||||
data.setNumberOfLines(size);
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
||||
this.subscriber = subscriber;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package de.wwwu.awolf.presenter.evaluation;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.Point;
|
||||
import de.wwwu.awolf.model.evaluation.ComparisonResult;
|
||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class AlgorithmComparison {
|
||||
|
||||
private final List<Algorithm.Type> types;
|
||||
private final ExecutorService executorService;
|
||||
private final Map<Algorithm.Type, Algorithm> algorithmMap;
|
||||
private final CompletionService<Line> completionService;
|
||||
|
||||
public AlgorithmComparison(List<Algorithm.Type> types, List<Line> lines, List<Point> nodes) {
|
||||
this.types = types;
|
||||
this.executorService = Executors.newFixedThreadPool(3);
|
||||
completionService = new ExecutorCompletionService<>(this.executorService);
|
||||
|
||||
algorithmMap = new EnumMap<>(Algorithm.Type.class);
|
||||
algorithmMap.put(Algorithm.Type.LMS, new LeastMedianOfSquaresEstimator(lines, nodes));
|
||||
algorithmMap.put(Algorithm.Type.RM, new RepeatedMedianEstimator(lines));
|
||||
algorithmMap.put(Algorithm.Type.TS, new TheilSenEstimator(lines, nodes));
|
||||
algorithmMap.put(Algorithm.Type.NAIV_LMS, new NaivLeastMedianOfSquaresEstimator(lines));
|
||||
algorithmMap.put(Algorithm.Type.NAIV_RM, new NaivRepeatedMedianEstimator(lines));
|
||||
algorithmMap.put(Algorithm.Type.NAIV_TS, new NaivTheilSenEstimator(lines));
|
||||
}
|
||||
|
||||
public ComparisonResult compare() {
|
||||
|
||||
ComparisonResult comparisonResult = new ComparisonResult();
|
||||
|
||||
getTypes().forEach(tye -> {
|
||||
completionService.submit(algorithmMap.get(tye));
|
||||
});
|
||||
|
||||
for (Algorithm.Type value : getTypes()) {
|
||||
Algorithm.Type type;
|
||||
synchronized (types) {
|
||||
type = value;
|
||||
}
|
||||
try {
|
||||
Line line = completionService.take().get();
|
||||
comparisonResult.put(type, line);
|
||||
} catch (InterruptedException interupted) {
|
||||
Logging.logError("Error while waiting for the Line result. Type: " + type, interupted);
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException e) {
|
||||
Logging.logError("Execution failed. Type: " + type, e);
|
||||
}
|
||||
}
|
||||
return comparisonResult;
|
||||
}
|
||||
|
||||
private List<Algorithm.Type> getTypes() {
|
||||
return types;
|
||||
}
|
||||
}
|
|
@ -2,27 +2,22 @@ package de.wwwu.awolf.presenter.evaluation;
|
|||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.LineModel;
|
||||
import de.wwwu.awolf.model.Point;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.model.communication.EvaluationData;
|
||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
||||
import de.wwwu.awolf.model.evaluation.ComparisonResult;
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
||||
import de.wwwu.awolf.presenter.io.DataImporter;
|
||||
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||
import de.wwwu.awolf.presenter.data.generator.DatasetGenerator;
|
||||
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.IntersectionComputer;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
/**
|
||||
|
@ -32,30 +27,17 @@ import java.util.concurrent.Flow;
|
|||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||
public class EvaluateAlgorithms implements Runnable, Flow.Publisher<Data> {
|
||||
|
||||
private LineModel arrangement;
|
||||
|
||||
private List<Line> lmsL;
|
||||
private List<Line> rmL;
|
||||
private List<Line> tsL;
|
||||
|
||||
private List<Point> lmsP;
|
||||
private List<Point> tsP;
|
||||
|
||||
private Thread lmsThread;
|
||||
private Thread rmThread;
|
||||
private Thread tsThread;
|
||||
|
||||
private DatasetGenerator generator;
|
||||
|
||||
private String[][] names = {{"MSE", "RMSE", "MAE", "MDAE", "Steigung", "y-Achsenabschnitt", "S-MSE", "S-RMSE", "S-MAE", "S-MDAE", "Brute-force Steigung", "Brute-force y-Achsenabschnitt"}, {"MAPE", "MDAPE", "RMSPE", "RMDSPE", "Steigung", "y-Achsenabschnitt"}};
|
||||
|
||||
//übergebene Parameter
|
||||
private int type;
|
||||
private int iterations;
|
||||
private int alg;
|
||||
private Flow.Subscriber<? super Data> subscriber;
|
||||
private Map<Algorithm.Type, Map<String, String>> resultMapping;
|
||||
|
||||
/**
|
||||
* Konstruktor zur evaluation
|
||||
|
@ -71,34 +53,23 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
|||
* 6 = lms, rm, ts,
|
||||
* @param datasettyp typ der zu generierenden Datensatz
|
||||
*/
|
||||
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp, Presenter presenter) {
|
||||
public EvaluateAlgorithms(int type, int n, int alg, DataProvider.DataType datasettyp, Presenter presenter) {
|
||||
subscribe(presenter);
|
||||
this.arrangement = new LineModel();
|
||||
generator = new DatasetGenerator(presenter);
|
||||
switch (datasettyp) {
|
||||
case "Punktwolke":
|
||||
arrangement.setLines(generator.generateDataCloud(n));
|
||||
break;
|
||||
case "Gerade":
|
||||
arrangement.setLines(generator.generateDataLines(n));
|
||||
break;
|
||||
case "Kreis und Gerade":
|
||||
arrangement.setLines(generator.generateCircle(n));
|
||||
break;
|
||||
}
|
||||
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||
|
||||
List<Line> data = presenter.getDataProvider().getData(datasettyp, n);
|
||||
Logging.logInfo("Starting the Benchmark...");
|
||||
arrangement.setLines(data);
|
||||
|
||||
Logging.logInfo("Benchmark on Dataset: " + datasettyp + " with " + n + " points");
|
||||
|
||||
this.type = type;
|
||||
this.iterations = n;
|
||||
this.alg = alg;
|
||||
|
||||
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
||||
arrangement.setNodes(computer.compute());
|
||||
|
||||
lmsL = new LinkedList<>(arrangement.getLines());
|
||||
rmL = new LinkedList<>(arrangement.getLines());
|
||||
tsL = new LinkedList<>(arrangement.getLines());
|
||||
|
||||
lmsP = new ArrayList<>(arrangement.getNodes());
|
||||
tsP = new ArrayList<>(arrangement.getNodes());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,225 +85,81 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
|||
* 6 = lms, rm, ts,
|
||||
* @param file Datei die importiert werden soll
|
||||
*/
|
||||
public EvaluateAlgorithms(int type, int alg, File file) {
|
||||
this.arrangement = new LineModel();
|
||||
|
||||
DataImporter importer = new DataImporter(file, this.subscriber);
|
||||
|
||||
List<Line> importedLines = importer.run();
|
||||
if (importedLines != null)
|
||||
arrangement.setLines(importedLines);
|
||||
public EvaluateAlgorithms(int type, int alg, File file, Presenter presenter) {
|
||||
subscribe(presenter);
|
||||
presenter.startImport(file);
|
||||
this.arrangement = presenter.getModel();
|
||||
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||
|
||||
this.type = type;
|
||||
this.alg = alg;
|
||||
|
||||
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
||||
arrangement.setNodes(computer.compute());
|
||||
|
||||
|
||||
lmsL = new LinkedList<>(arrangement.getLines());
|
||||
rmL = new LinkedList<>(arrangement.getLines());
|
||||
tsL = new LinkedList<>(arrangement.getLines());
|
||||
|
||||
lmsP = new ArrayList<>(arrangement.getNodes());
|
||||
tsP = new ArrayList<>(arrangement.getNodes());
|
||||
}
|
||||
|
||||
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.unmodifiableList(arrangement.getLines()), Collections.unmodifiableList(arrangement.getNodes()));
|
||||
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));
|
||||
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) {
|
||||
Logging.logInfo("AlgorithmComparison with Types: " + types);
|
||||
AlgorithmComparison comparison = new AlgorithmComparison(types, Collections.unmodifiableList(arrangement.getLines()), Collections.unmodifiableList(arrangement.getNodes()));
|
||||
ComparisonResult comparisonResult = comparison.compare();
|
||||
|
||||
Map<String, String> multipleResults = new HashMap<>();
|
||||
types.forEach(type -> this.resultMapping.put(type, getPercentigeErrorBasedMeasure(arrangement.getLines(), comparisonResult, type)));
|
||||
Logging.logInfo("finished with execution of the algorithms.");
|
||||
return this.resultMapping;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Startet die Evaluation zu den passenden Typ. Bei beendigung wird der Beobachter informiert.
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
List<String> result;
|
||||
List<List<String>> multipleResults = new ArrayList<>();
|
||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
|
||||
|
||||
Map<Algorithm.Type, Map<String, String>> result = new EnumMap<>(Algorithm.Type.class);
|
||||
switch (type) {
|
||||
case 0:
|
||||
//der alg der gewählt wurde
|
||||
if (alg == 0) {
|
||||
final Line naivEstimator = new Line(0,0);
|
||||
final Line advancedEstimator = new Line(0,0);
|
||||
executorService.submit(() -> {
|
||||
NaivLeastMedianOfSquaresEstimator l = new NaivLeastMedianOfSquaresEstimator(arrangement.getLines());
|
||||
l.run();
|
||||
naivEstimator.setM(l.getM());
|
||||
naivEstimator.setB(l.getB());
|
||||
});
|
||||
executorService.submit(() -> {
|
||||
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lmsL, lmsP);
|
||||
lmsAlg.run();
|
||||
lmsAlg.pepareResult();
|
||||
advancedEstimator.setM(lmsAlg.getSlope());
|
||||
advancedEstimator.setB(lmsAlg.getyInterception());
|
||||
});
|
||||
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), advancedEstimator.getM(), advancedEstimator.getB());
|
||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), advancedEstimator.getM(), advancedEstimator.getB(), naivEstimator.getM(), naivEstimator.getB()));
|
||||
Double[] tmp = {advancedEstimator.getM(), advancedEstimator.getB(), naivEstimator.getM(), naivEstimator.getB()};
|
||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.LMS);
|
||||
result = benchmarkSameEstimator(Algorithm.Type.LMS, Algorithm.Type.NAIV_LMS);
|
||||
} else if (alg == 1) {
|
||||
final double[] m = new double[1];
|
||||
final double[] b = new double[1];
|
||||
Thread t = new Thread(() -> {
|
||||
NaivRepeatedMedianEstimator r = new NaivRepeatedMedianEstimator(arrangement.getLines());
|
||||
r.run();
|
||||
m[0] = r.getM();
|
||||
b[0] = r.getB();
|
||||
});
|
||||
t.start();
|
||||
try {
|
||||
startRM();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]));
|
||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]), m[0], b[0]));
|
||||
Double[] tmp = {Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]), m[0], b[0]};
|
||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.NAIV_RM);
|
||||
result = benchmarkSameEstimator(Algorithm.Type.RM, Algorithm.Type.NAIV_RM);
|
||||
} else {
|
||||
final double[] m = new double[1];
|
||||
final double[] b = new double[1];
|
||||
Thread t = new Thread(() -> {
|
||||
NaivTheilSenEstimator ts = new NaivTheilSenEstimator(arrangement.getLines());
|
||||
ts.run();
|
||||
m[0] = ts.getM();
|
||||
b[0] = ts.getB();
|
||||
});
|
||||
t.start();
|
||||
try {
|
||||
startTS();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
result = benchmarkSameEstimator(Algorithm.Type.TS, Algorithm.Type.NAIV_TS);
|
||||
}
|
||||
result = getScaleDependentMeasure(arrangement.getLines(), Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]));
|
||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]), m[0], b[0]));
|
||||
Double[] tmp = { Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]), m[0], b[0]};
|
||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.NAIV_TS);
|
||||
}
|
||||
sendTableApproximationTypes();
|
||||
sendTableApproximationData(result, alg);
|
||||
break;
|
||||
case 1:
|
||||
List<List<String>> lineRes;
|
||||
switch (alg) {
|
||||
case 3:
|
||||
try {
|
||||
startLMS();
|
||||
startRM();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = fillPseudoResults();
|
||||
multipleResults.add(result);
|
||||
|
||||
lineRes = new ArrayList<>();
|
||||
lineRes.add(Arrays.asList(lmsRes));
|
||||
lineRes.add(Arrays.asList(rmRes));
|
||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
|
||||
|
||||
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
|
||||
break;
|
||||
case 4:
|
||||
try {
|
||||
startLMS();
|
||||
startTS();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = fillPseudoResults();
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
||||
multipleResults.add(result);
|
||||
|
||||
lineRes = new ArrayList<>();
|
||||
lineRes.add(Arrays.asList(lmsRes));
|
||||
lineRes.add(Arrays.asList(tsRes));
|
||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
|
||||
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
|
||||
break;
|
||||
case 5:
|
||||
try {
|
||||
startRM();
|
||||
startTS();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
result = fillPseudoResults();
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
||||
multipleResults.add(result);
|
||||
|
||||
lineRes = new ArrayList<>();
|
||||
lineRes.add(Arrays.asList(rmRes));
|
||||
lineRes.add(Arrays.asList(tsRes));
|
||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
|
||||
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
|
||||
break;
|
||||
case 6:
|
||||
try {
|
||||
startLMS();
|
||||
startRM();
|
||||
startTS();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.logError(e.getMessage(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
||||
multipleResults.add(result);
|
||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
||||
multipleResults.add(result);
|
||||
|
||||
lineRes = new ArrayList<>();
|
||||
lineRes.add(Arrays.asList(lmsRes));
|
||||
lineRes.add(Arrays.asList(rmRes));
|
||||
lineRes.add(Arrays.asList(tsRes));
|
||||
sendPloteLineResults(lineRes, 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;
|
||||
}
|
||||
|
||||
sendTableApproximationData(multipleResults);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Die berechneten Ergebnisse werden an den Beobachter übermittelt um dann visualisiert zu werden.
|
||||
*
|
||||
* @param result Ergebnisse
|
||||
* @param col Spalte
|
||||
*/
|
||||
public void sendTableApproximationData(List<String> result, int col) {
|
||||
List<String> tableInput = new ArrayList<>();
|
||||
for (int i = 0; i < names[type].length; i++) {
|
||||
tableInput.add(result.get(i));
|
||||
}
|
||||
tableInput.add("");
|
||||
EvaluationData data = new EvaluationData();
|
||||
data.setColumn(col);
|
||||
data.setLabels(tableInput);
|
||||
tableInput.clear();
|
||||
sendTableApproximationData(result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,145 +167,38 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
|||
*
|
||||
* @param result Ergebnisse
|
||||
*/
|
||||
public void sendTableApproximationData(List<List<String>> result) {
|
||||
List<String> tableInput = new ArrayList<>();
|
||||
|
||||
//TODO Hääää? xD
|
||||
//iteration über die ApproximationsGüten -- Zeilen
|
||||
for (int j = 0; j <= result.get(0).size(); j++) {
|
||||
tableInput.add("eval-ds");
|
||||
if (j != result.get(0).size()) {
|
||||
|
||||
tableInput.add(names[type][j]);
|
||||
//iteration über die alg. -- Spalten
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tableInput.add(result.get(i).get(j));
|
||||
}
|
||||
} else {
|
||||
tableInput.add("");
|
||||
tableInput.add("");
|
||||
tableInput.add("");
|
||||
tableInput.add("");
|
||||
}
|
||||
private void sendTableApproximationData(Map<Algorithm.Type, Map<String, String>> result) {
|
||||
|
||||
EvaluationData data = new EvaluationData();
|
||||
data.setType(SubscriberType.EVAL_DS);
|
||||
data.setType(SubscriberType.EVALUATION_TABLE_DATA);
|
||||
data.setMultipleColumnResult(result);
|
||||
data.setRowsPerColumn(result.keySet().size());
|
||||
this.subscriber.onNext(data);
|
||||
|
||||
tableInput.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Art der Ergebnisse (MSE, RMSE,...) wird an der Beobachter übermittelt.
|
||||
*/
|
||||
public void sendTableApproximationTypes() {
|
||||
EvaluationData data = new EvaluationData();
|
||||
data.setType(SubscriberType.EVAL_T);
|
||||
data.setLabels(Arrays.asList(names[type]));
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zur visualisierung der berechneten Geraden wird die Steigung und der y-Achsenabschnitt an den
|
||||
* Beobachter übermittelt.
|
||||
*
|
||||
* @param res Feld mit den Werten für die Steigung und dern y-Achsenabschnitt
|
||||
* @param alg code für welchen Algorithmus sich die Werte beziehen
|
||||
*/
|
||||
public void sendPlotLineResults(List<Double> res, Algorithm.Type alg) {
|
||||
EvaluationData data = new EvaluationData();
|
||||
data.setType(SubscriberType.LINES_RES);
|
||||
data.setAlgorithmtypes(Collections.singletonList(alg));
|
||||
data.setOneColumnresult(res);
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zur visualisierung der berechneten Geraden wird die Steigung und der y-Achsenabschnitt an den
|
||||
* Beobachter übermittelt.
|
||||
*
|
||||
* @param res Feld mit den Werten für die Steigung und dern y-Achsenabschnitt (alle)
|
||||
* @param algs codes für welchen Algorithmus sich die Werte beziehen (alle)
|
||||
*/
|
||||
public void sendPloteLineResults(List<List<String>> res, List<Algorithm.Type> algs) {
|
||||
EvaluationData data = new EvaluationData();
|
||||
data.setType(SubscriberType.LINES_RES_MULT);
|
||||
data.setAlgorithmtypes(algs);
|
||||
data.setMultipleColumnResult(res);
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Startet die Berechnung des Alg. zum LMS-Schätzer
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void startLMS() throws InterruptedException {
|
||||
lmsThread = new Thread(() -> {
|
||||
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lmsL, lmsP);
|
||||
lmsAlg.run();
|
||||
lmsAlg.pepareResult();
|
||||
lmsRes[0] = lmsAlg.getSlope();
|
||||
lmsRes[1] = lmsAlg.getyInterception();
|
||||
|
||||
});
|
||||
lmsThread.start();
|
||||
lmsThread.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* Startet die Berechnung des Alg. zum RM-Schätzer
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void startRM() throws InterruptedException {
|
||||
rmThread = new Thread(() -> {
|
||||
RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(rmL);
|
||||
rmAlg.run();
|
||||
rmAlg.pepareResult();
|
||||
rmRes[0] = rmAlg.getSlope();
|
||||
rmRes[1] = rmAlg.getyInterception();
|
||||
});
|
||||
rmThread.start();
|
||||
rmThread.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* Startet die Berechnung des Alg. zum TS-Schätzer
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void startTS() throws InterruptedException {
|
||||
tsThread = new Thread(() -> {
|
||||
TheilSenEstimator tsAlg = new TheilSenEstimator(tsL, tsP);
|
||||
tsAlg.run();
|
||||
tsAlg.pepareResult();
|
||||
tsRes[0] = tsAlg.getSlope();
|
||||
tsRes[1] = tsAlg.getyInterception();
|
||||
});
|
||||
tsThread.start();
|
||||
tsThread.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* Startet die Berechnung der skalierungsabbhängigen Maße.
|
||||
*
|
||||
* @param lines Liste der Geraden
|
||||
* @param m Steigung
|
||||
* @param b y-Achsenabschnitt
|
||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||
*/
|
||||
public List<String> getScaleDependentMeasure(final List<Line> lines, final Double m, final Double b) {
|
||||
private Map<String, String> getScaleDependentMeasure(final List<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
|
||||
|
||||
Logging.logInfo("Calculating ScaleDependentMeasure for " + type);
|
||||
|
||||
Double m = comparisonResult.get(type).getM();
|
||||
Double b = comparisonResult.get(type).getB();
|
||||
|
||||
ScaleDependentMeasure scaleDependentMeasure = new ScaleDependentMeasure(lines, m, b);
|
||||
List<String> ret = new ArrayList<>();
|
||||
ret.add(scaleDependentMeasure.mse().toString());
|
||||
ret.add(scaleDependentMeasure.rmse().toString());
|
||||
ret.add(scaleDependentMeasure.mae().toString());
|
||||
ret.add(scaleDependentMeasure.mdae().toString());
|
||||
ret.add(m.toString());
|
||||
ret.add(b.toString());
|
||||
Map<String, String> ret = new HashMap<>();
|
||||
ret.put(type + " MSE", scaleDependentMeasure.mse().toString());
|
||||
ret.put(type + " RMSE", scaleDependentMeasure.rmse().toString());
|
||||
ret.put(type + " MAE", scaleDependentMeasure.mae().toString());
|
||||
ret.put(type + " MDAE", scaleDependentMeasure.mdae().toString());
|
||||
ret.put(type + " SLOPE", m.toString());
|
||||
ret.put(type + " y-INTERCEPTION", b.toString());
|
||||
|
||||
Logging.logInfo("finished calculating ScaleDependentMeasure.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -487,19 +207,22 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
|||
* Startet die Berechnung der Maße die auf dem prozentualen Fehler basieren.
|
||||
*
|
||||
* @param lines Liste der Geraden
|
||||
* @param m Steigung
|
||||
* @param b y-Achsenabschnitt
|
||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||
*/
|
||||
public List<String> getPercentigeErrorBasedMeasure(final List<Line> lines, final Double m, final Double b) {
|
||||
private Map<String, String> getPercentigeErrorBasedMeasure(final List<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);
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
ret.add(percentageErrorBasedMeasure.mape().toString());
|
||||
ret.add(percentageErrorBasedMeasure.mdape().toString());
|
||||
ret.add(percentageErrorBasedMeasure.rmspe().toString());
|
||||
ret.add(percentageErrorBasedMeasure.rmdspe().toString());
|
||||
ret.add(m.toString());
|
||||
ret.add(b.toString());
|
||||
Map<String, String> ret = new HashMap<>();
|
||||
ret.put(type + " MAPE", percentageErrorBasedMeasure.mape().toString());
|
||||
ret.put(type + " MDAPE", percentageErrorBasedMeasure.mdape().toString());
|
||||
ret.put(type + " RMSPE", percentageErrorBasedMeasure.rmspe().toString());
|
||||
ret.put(type + " RMDSPE", percentageErrorBasedMeasure.rmdspe().toString());
|
||||
ret.put(type + " SLOPE", m.toString());
|
||||
ret.put(type + " y-INTERCEPTION", b.toString());
|
||||
Logging.logInfo("finished calculating PercentigeErrorBasedMeasure.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -507,36 +230,30 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
|||
* Startet die Berechnung der skalierungsunabbhängigen Maße.
|
||||
*
|
||||
* @param lines Liste der Geraden
|
||||
* @param m Steigung
|
||||
* @param b y-Achsenabschnitt
|
||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||
*/
|
||||
public List<String> getScaledErrorBasedMeasure(final List<Line> lines, final Double m, final Double b, final Double nM, final Double nB) {
|
||||
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b, nM, nB);
|
||||
List<String> ret = new ArrayList<>();
|
||||
ret.add(scaledErrorBasedMeasure.mse().toString());
|
||||
ret.add(scaledErrorBasedMeasure.rmse().toString());
|
||||
ret.add(scaledErrorBasedMeasure.mae().toString());
|
||||
ret.add(scaledErrorBasedMeasure.mdae().toString());
|
||||
ret.add(nM.toString());
|
||||
ret.add(nB.toString());
|
||||
return ret;
|
||||
}
|
||||
private Map<String, String> getScaledErrorBasedMeasure(final List<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type advanced, final Algorithm.Type naiv) {
|
||||
|
||||
/**
|
||||
* Damit es bei der Visualisierung trennende Zeilen gibt.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<String> fillPseudoResults() {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
result.add(" ");
|
||||
return result;
|
||||
Logging.logInfo("Calculating ScaledErrorBasedMeasure for " + advanced + ", " + naiv);
|
||||
|
||||
//first
|
||||
Double m = comparisonResult.get(advanced).getM();
|
||||
Double b = comparisonResult.get(advanced).getB();
|
||||
//second
|
||||
Double naivM = comparisonResult.get(naiv).getM();
|
||||
Double naivB = comparisonResult.get(naiv).getB();
|
||||
|
||||
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());
|
||||
ret.put(advanced + " MAE", scaledErrorBasedMeasure.mae().toString());
|
||||
ret.put(advanced + " MDAE", scaledErrorBasedMeasure.mdae().toString());
|
||||
ret.put(advanced + " Naiv-SLOPE", naivM.toString());
|
||||
ret.put(advanced + " Naiv-y-INTERCEPTION", naivB.toString());
|
||||
|
||||
Logging.logInfo("finished calculating ScaledErrorBasedMeasure.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package de.wwwu.awolf.presenter.evaluation;
|
||||
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,4 +1,4 @@
|
|||
package de.wwwu.awolf.presenter.evaluation;
|
||||
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
|
@ -1,4 +1,4 @@
|
|||
package de.wwwu.awolf.presenter.evaluation;
|
||||
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,4 +1,4 @@
|
|||
package de.wwwu.awolf.presenter.evaluation;
|
||||
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,175 +0,0 @@
|
|||
package de.wwwu.awolf.presenter.generator;
|
||||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.model.communication.Data;
|
||||
import de.wwwu.awolf.model.communication.GeneratorData;
|
||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 01.08.2017.
|
||||
*/
|
||||
public class DatasetGenerator implements Flow.Publisher<Data> {
|
||||
|
||||
private Double m;
|
||||
private Double b;
|
||||
private SecureRandom random;
|
||||
private Flow.Subscriber<? super Data> subscriber;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*/
|
||||
public DatasetGenerator(Presenter presenter) {
|
||||
random = new SecureRandom();
|
||||
this.subscribe(presenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*/
|
||||
public DatasetGenerator() {
|
||||
random = new SecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert zu einer gegebenen Größe einen Datensatz des typen: Punktwolke
|
||||
*
|
||||
* @param size Größe des Datensatzes
|
||||
* @return Liste der Geraden
|
||||
*/
|
||||
public LinkedList<Line> generateDataCloud(int size) {
|
||||
LinkedList<Line> lines = new LinkedList<>();
|
||||
m = 1 + random.nextDouble();
|
||||
b = random.nextDouble();
|
||||
|
||||
|
||||
for (int i = 1; i < (size + 1); i++) {
|
||||
double y = (random.nextGaussian() * 100) % 100;
|
||||
double signal = m * i + b;
|
||||
signal *= -1;
|
||||
|
||||
Line line = new Line(i, signal - y);
|
||||
line.setId(i - 1 + "");
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
communicate("Es wurden " + size + " Daten generiert mit den Parametern", m, b);
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper Methode zum generieren eines Datensatzes des typen: Gerade
|
||||
*
|
||||
* @param size Größe des Datensatzes
|
||||
* @return Liste des Geraden
|
||||
*/
|
||||
public List<Line> generateDataLines(int size) {
|
||||
List<Line> lines = new LinkedList<>();
|
||||
return generateDataLines(lines, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine
|
||||
* übergebene Liste hinzugefügt.
|
||||
*
|
||||
* @param lines Liste der Geraden
|
||||
* @param n Größe des Datensatzes
|
||||
* @return Liste des Geraden
|
||||
*/
|
||||
private List<Line> generateDataLines(List<Line> lines, int n) {
|
||||
m = 5d;
|
||||
b = 0d;
|
||||
|
||||
int size = 0;
|
||||
Map<Double, Double> points = new HashMap<>();
|
||||
|
||||
//speichere die Koordinaten in einer HashMap, damit keine Punkte
|
||||
//entstehen deren x-Koordinate zu sehr beieinander liegt.
|
||||
while (size < n) {
|
||||
double y = random.nextGaussian();
|
||||
double signal = m * y + b;
|
||||
signal *= -1;
|
||||
|
||||
if (!points.containsKey(y)) {
|
||||
points.put(y, signal);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = lines.size();
|
||||
for (Double d : points.keySet()) {
|
||||
Line line = new Line(d, points.get(d));
|
||||
line.setId(idx + "");
|
||||
lines.add(line);
|
||||
idx++;
|
||||
}
|
||||
|
||||
communicate("Es wurden " + n + " Daten generiert mit den Parametern", m, b);
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param size Größe des Datensatzes
|
||||
* @return Liste der Geraden
|
||||
*/
|
||||
public List<Line> generateCircle(int size) {
|
||||
List<Line> lines = new LinkedList<>();
|
||||
|
||||
double from = 0;
|
||||
double to = Math.PI * 5;
|
||||
//obere Grenze für die neuen Punkte
|
||||
int n = size / 2 + lines.size();
|
||||
|
||||
//calculate the distance between every two points
|
||||
double distance = (to - from) / ((double) n);
|
||||
|
||||
//create points
|
||||
double currentDistance = from;
|
||||
//an die aktuelle Liste dranhängen
|
||||
for (int i = lines.size(); i < n; i++) {
|
||||
double x = Math.cos(currentDistance);
|
||||
double y = Math.sin(currentDistance);
|
||||
|
||||
Line line = new Line(x, y);
|
||||
line.setId(i + "");
|
||||
lines.add(line);
|
||||
|
||||
//distance for the next iteration
|
||||
currentDistance += distance;
|
||||
}
|
||||
|
||||
return generateDataLines(lines, size / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
||||
|
||||
}
|
||||
|
||||
private void communicate(final String message, final double m, final double b) {
|
||||
if (this.subscriber != null) {
|
||||
GeneratorData data = new GeneratorData();
|
||||
data.setType(SubscriberType.GENERATOR);
|
||||
data.setMessage(message);
|
||||
data.setM(m);
|
||||
data.setB(b);
|
||||
this.subscriber.onNext(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ package de.wwwu.awolf.view;
|
|||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.AbstractPresenter;
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
import de.wwwu.awolf.view.listener.*;
|
||||
import de.wwwu.awolf.view.panels.DualityPanel;
|
||||
|
@ -19,9 +20,10 @@ import javax.imageio.ImageIO;
|
|||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
|
@ -244,21 +246,14 @@ public class MainFrame extends JFrame {
|
|||
}
|
||||
|
||||
/**
|
||||
* Fügt der Evaluations-Tabelle eine Spalte mit Daten hinzu
|
||||
* Fügt der Evaluations-Tabelle eine Zeile mit Daten hinzu
|
||||
*
|
||||
* @param res Daten der Spalte
|
||||
* @param col Spalte
|
||||
* @param isApprCol <code>true</code>, falls es sich um die Überschirften der Approximationsgüten handelt
|
||||
* @param tableEntries Data of the Table
|
||||
*/
|
||||
public void appendEvalResult(Object[] res, int col, boolean isApprCol) {
|
||||
public void appendEvalResult(Map<Algorithm.Type, Map<String, String>> tableEntries) {
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.copyOfRange(res, 2, res.length);
|
||||
if (isApprCol) {
|
||||
evaluationPanel.setCurrentRow(tmp.length);
|
||||
evaluationPanel.addColumn(tmp, col, true);
|
||||
} else {
|
||||
evaluationPanel.addColumn(tmp, col + 1, false);
|
||||
}
|
||||
evaluationPanel.addRow(tableEntries);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
|
@ -269,65 +264,8 @@ public class MainFrame extends JFrame {
|
|||
*
|
||||
* @param res Daten der Spalte
|
||||
*/
|
||||
public void appendEvalResult(Object[] res) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] tmp = Arrays.copyOfRange(res, 1, res.length);
|
||||
evaluationPanel.addRow(tmp);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualisiert die Ausgleichsgerade zu gegebenen Algorithmen
|
||||
*
|
||||
* @param res Steigungen und y-Achsenabschnitte
|
||||
* @param alg Kodierung der Alg.
|
||||
*/
|
||||
public void drawLineResult(Object[] res, int alg) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.copyOfRange(res, 2, res.length);
|
||||
evaluationPanel.drawLines(result, alg);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualisiert die Ausgleichsgerade zu einem gegebenen Algorithmus
|
||||
*
|
||||
* @param res Steigungen und y-Achsenabschnitte
|
||||
*/
|
||||
public void drawLineResults(Object[] res) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Object[] result = Arrays.copyOfRange(res, 1, res.length);
|
||||
List<Double[]> algs = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < (result.length + 1) / 3; i++) {
|
||||
String name = (String) result[(3 * i)];
|
||||
String m = (String) result[(3 * i) + 1];
|
||||
String b = (String) result[(3 * i) + 2];
|
||||
Double[] tmp = {Double.parseDouble(name), Double.parseDouble(m), Double.parseDouble(b)};
|
||||
algs.add(tmp);
|
||||
}
|
||||
|
||||
evaluationPanel.drawLines(algs);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluations-Datensätze werden Visualisiert
|
||||
*
|
||||
* @param lines Liste der Geraden
|
||||
*/
|
||||
public void addEvalDataset(List<Line> lines) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
evaluationPanel.setDualPoints(lines);
|
||||
evaluationPanel.repaint();
|
||||
evaluationPanel.revalidate();
|
||||
});
|
||||
public void appendEvalResults(Map<Algorithm.Type, Map<String, String>> res) {
|
||||
appendEvalResult(res);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import de.wwwu.awolf.presenter.Presenter;
|
|||
import de.wwwu.awolf.view.listener.ExportDataListener;
|
||||
import de.wwwu.awolf.view.listener.GenerateDataListener;
|
||||
import de.wwwu.awolf.view.listener.ImportDataListener;
|
||||
import de.wwwu.awolf.view.listener.PictureImportListener;
|
||||
import de.wwwu.awolf.view.panels.AboutPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -31,7 +30,6 @@ public class MenuBar {
|
|||
private JMenuItem generateItem;
|
||||
private JMenuItem evaluateItem;
|
||||
private JMenuItem aboutItem;
|
||||
private JMenuItem importPicture;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
|
@ -48,7 +46,6 @@ public class MenuBar {
|
|||
|
||||
this.exitItem = new JMenuItem("Exit");
|
||||
this.importItem = new JMenuItem("Import");
|
||||
this.importPicture = new JMenuItem("Bildimport");
|
||||
this.exportItem = new JMenuItem("Export");
|
||||
this.generateItem = new JMenuItem("Generiere...");
|
||||
this.aboutItem = new JMenuItem("Über das Programm");
|
||||
|
@ -61,7 +58,6 @@ public class MenuBar {
|
|||
fileMenu.add(exportItem);
|
||||
|
||||
toolsMenu.add(generateItem);
|
||||
toolsMenu.add(importPicture);
|
||||
toolsMenu.add(evaluateItem);
|
||||
|
||||
|
||||
|
@ -95,7 +91,6 @@ public class MenuBar {
|
|||
dialog.setVisible(true);
|
||||
});
|
||||
});
|
||||
this.importPicture.addActionListener(new PictureImportListener((Presenter) view.getPresenter(), view));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package de.wwwu.awolf.view.listener;
|
||||
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
@ -57,8 +58,8 @@ public class GenerateDataListener implements ActionListener {
|
|||
dialog.add(aproveButton);
|
||||
aproveButton.addActionListener(e1 -> {
|
||||
int n = Integer.parseInt(textField.getText());
|
||||
int type = datasetTypeComboBox.getSelectedIndex();
|
||||
Thread t = new Thread(() -> presenter.generateDataset(n, type));
|
||||
int index = datasetTypeComboBox.getSelectedIndex();
|
||||
Thread t = new Thread(() -> presenter.generateDataset(n, DataProvider.DataType.values()[index]));
|
||||
t.start();
|
||||
dialog.dispose();
|
||||
});
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package de.wwwu.awolf.view.listener;
|
||||
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||
*
|
||||
* @Author: Armin Wolf
|
||||
* @Email: a_wolf28@uni-muenster.de
|
||||
* @Date: 17.09.2017.
|
||||
*/
|
||||
public class PictureImportListener implements ActionListener {
|
||||
private Presenter presenter;
|
||||
private Container component;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param presenter Presenter
|
||||
* @param component visuelle Elternkomponente
|
||||
*/
|
||||
public PictureImportListener(Presenter presenter, Container component) {
|
||||
this.presenter = presenter;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
File file = null;
|
||||
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
||||
chooser.setPreferredSize(new Dimension(800, 700));
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Bilder", "tiff", "png", "jpg", "jpeg"));
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
|
||||
if (chooser.showOpenDialog(component) == JFileChooser.APPROVE_OPTION) {
|
||||
//Logging.logInfo ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
||||
file = chooser.getSelectedFile();
|
||||
final File input = file;
|
||||
Thread t = new Thread(() -> presenter.startPictureDataImport(input));
|
||||
t.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -2,25 +2,23 @@ package de.wwwu.awolf.view.panels;
|
|||
|
||||
import de.wwwu.awolf.model.Line;
|
||||
import de.wwwu.awolf.presenter.Presenter;
|
||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||
import de.wwwu.awolf.presenter.util.Logging;
|
||||
import de.wwwu.awolf.view.MainFrame;
|
||||
import de.wwwu.awolf.view.custom.ButtonGroupAtLeastTwo;
|
||||
import de.wwwu.awolf.view.custom.ColorColumnRenderer;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumn;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by
|
||||
|
@ -59,6 +57,7 @@ public class EvaluationPanel extends JPanel {
|
|||
private int currentRowOfTypes;
|
||||
private JPanel buttonPanel;
|
||||
private PlotPanel plotPanel;
|
||||
private Map<Algorithm.Type, Color> colorMap;
|
||||
private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"};
|
||||
|
||||
/**
|
||||
|
@ -71,6 +70,13 @@ public class EvaluationPanel extends JPanel {
|
|||
this.view = view;
|
||||
this.setLayout(new BorderLayout());
|
||||
this.currentRowOfTypes = 0;
|
||||
this.colorMap = new HashMap<>();
|
||||
this.colorMap.put(Algorithm.Type.LMS, Color.ORANGE);
|
||||
this.colorMap.put(Algorithm.Type.RM, Color.RED);
|
||||
this.colorMap.put(Algorithm.Type.TS, Color.MAGENTA);
|
||||
this.colorMap.put(Algorithm.Type.NAIV_LMS, Color.BLUE);
|
||||
this.colorMap.put(Algorithm.Type.NAIV_RM, Color.GREEN);
|
||||
this.colorMap.put(Algorithm.Type.NAIV_TS, Color.CYAN);
|
||||
|
||||
init();
|
||||
addListener();
|
||||
|
@ -157,7 +163,6 @@ public class EvaluationPanel extends JPanel {
|
|||
comp.setBorder(new TitledBorder("Konfiguration"));
|
||||
|
||||
//Tabelle
|
||||
model.setColumnIdentifiers(selections);
|
||||
table.setDragEnabled(true);
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
scrollPane.setWheelScrollingEnabled(true);
|
||||
|
@ -182,14 +187,6 @@ public class EvaluationPanel extends JPanel {
|
|||
|
||||
this.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
TableColumn tm = table.getColumnModel().getColumn(0);
|
||||
tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue));
|
||||
for (int i = 1; i < 4; i++) {
|
||||
DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
|
||||
rightRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
rightRenderer.setFont(new FontUIResource("Courier", Font.PLAIN, 12));
|
||||
table.getColumnModel().getColumn(i).setCellRenderer(rightRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,7 +225,7 @@ public class EvaluationPanel extends JPanel {
|
|||
});
|
||||
|
||||
} else {
|
||||
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, datatyp);
|
||||
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, DataProvider.DataType.values()[datasetType.getSelectedIndex()]);
|
||||
}
|
||||
clearTable.setEnabled(true);
|
||||
exportData.setEnabled(true);
|
||||
|
@ -303,13 +300,14 @@ public class EvaluationPanel extends JPanel {
|
|||
* @param col Spalte
|
||||
* @param isLabel <code>true</code>, falls es sich um die Approximations Überschriften handelt
|
||||
*/
|
||||
public void addColumn(Object[] data, int col, boolean isLabel) {
|
||||
public void addColumn(final List<? extends Serializable> data, final int col, final boolean isLabel) {
|
||||
if (isLabel) {
|
||||
addBlankRows(data.length);
|
||||
addBlankRows(data.size());
|
||||
}
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int row = currentRowOfTypes - data.length + i;
|
||||
model.setValueAt(data[i], row, col);
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
int row = currentRowOfTypes - data.size() + i;
|
||||
model.setValueAt(data.get(i), row, col);
|
||||
}
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
|
@ -318,55 +316,41 @@ public class EvaluationPanel extends JPanel {
|
|||
/**
|
||||
* Fügt der Tabelle eine Zeile hinzu
|
||||
*
|
||||
* @param data Daten der Zeile
|
||||
* @param tableEntries Daten der Tabelle
|
||||
*/
|
||||
public void addRow(Object[] data) {
|
||||
addBlankRows(1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
model.setValueAt(data[i], currentRowOfTypes, i);
|
||||
}
|
||||
public void addRow(Map<Algorithm.Type, Map<String, String>> tableEntries) {
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
|
||||
Set<Algorithm.Type> types = tableEntries.keySet();
|
||||
List<String> columnlabels = new ArrayList<>();
|
||||
|
||||
types.forEach(type -> {
|
||||
columnlabels.add(" ");
|
||||
});
|
||||
model.setColumnIdentifiers(columnlabels.toArray());
|
||||
tableEntries.entrySet().forEach(row -> {
|
||||
model.addRow(row.getValue().keySet().toArray());
|
||||
model.addRow(row.getValue().values().toArray());
|
||||
});
|
||||
|
||||
currentRowOfTypes++;
|
||||
this.repaint();
|
||||
this.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visualisierung der Ausgleichsgeraden
|
||||
*
|
||||
* @param alg Steigung und y-Achsenabschnitt der Geraden, bestimmt durch die Schätzer
|
||||
*/
|
||||
public void drawLines(List<Double[]> alg) {
|
||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
||||
String[] name = {"LMS", "RM", "TS"};
|
||||
|
||||
for (Double[] o : alg) {
|
||||
int i = o[0].intValue();
|
||||
Double m = o[1];
|
||||
Double b = o[2];
|
||||
plotPanel.addLineToPlot(m, b, color[i], name[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Visualisierung der Ausgleichsgerade
|
||||
*
|
||||
* @param results Steigung und y-Achsenabschnitt der Gerade, bestimmt durch die Schätzer
|
||||
* @param lines the lines
|
||||
* @param alg identifizierung des Alg.
|
||||
*/
|
||||
public void drawLines(Object[] results, int alg) {
|
||||
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
|
||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
||||
String[] name = {"LMS", "RM", "TS"};
|
||||
String[] nName = {"Brute-force LMS", "Brute-force RM", "Brute-force TS"};
|
||||
|
||||
double m = Double.parseDouble(castedResults[0]);
|
||||
double b = Double.parseDouble(castedResults[1]);
|
||||
plotPanel.addLineToPlot(m, b, color[alg], name[alg]);
|
||||
|
||||
double nM = Double.parseDouble(castedResults[2]);
|
||||
double nB = Double.parseDouble(castedResults[3]);
|
||||
plotPanel.addLineToPlot(nM, nB, Color.BLACK, nName[alg]);
|
||||
public void drawLines(final List<Line> lines, final Algorithm.Type alg) {
|
||||
for (Line line : lines) {
|
||||
plotPanel.addLineToPlot(line.getM(), line.getB(), colorMap.get(alg), alg.name());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue