package Presenter.Evaluation; import Model.Interval; import Model.Line; import Model.LineModel; import Presenter.Algorithms.*; import Presenter.Generator.DatasetGenerator; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Observable; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * * @Author: Armin Wolf * @Email: a_wolf28@uni-muenster.de * @Date: 01.08.2017. */ public class EvaluateAlgorithms extends Observable { private Double m; private Double b; private Integer iterationCount; private LineModel arrangement; private Object[] lmsResult; private Object[] rmResult; private Object[] tsResult; private Thread lmsThread; private Thread rmThread; private Thread tsThread; public EvaluateAlgorithms(Double m, Double b, Integer iterationCount) { this.m = m; this.b = b; this.iterationCount = iterationCount; } public EvaluateAlgorithms(){ this.m = null; this.b = null; this.iterationCount = 1; } public void run() throws InterruptedException { for (int i = 0; i < iterationCount; i++) { this.arrangement = new LineModel(); DatasetGenerator generator; if (m != null && b != null) { generator = new DatasetGenerator(m, b); } else { generator = new DatasetGenerator(); } arrangement.setLines(generator.generateDataset()); IntersectionCounter counter = new IntersectionCounter(); counter.run(arrangement.getLines(), new Interval(-99999, 99999)); counter.calculateIntersectionAbscissas(arrangement); lmsThread = new Thread(() -> { LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(arrangement.getLines() , arrangement.getNodes()); lmsAlg.run(); lmsAlg.getResult(); List errors = sampsonError(arrangement.getLines(), lmsAlg.getSlope(), lmsAlg.getyInterception()); lmsResult = getResults(errors, "Least Median of Squares"); setChanged(); notifyObservers(lmsResult); }); rmThread = new Thread(() -> { RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(arrangement.getLines()); rmAlg.run(); rmAlg.getResult(); List errors = sampsonError(arrangement.getLines(), rmAlg.getSlope(), rmAlg.getyInterception()); rmResult = getResults(errors, "Repeated-Median"); setChanged(); notifyObservers(rmResult); }); tsThread = new Thread(() -> { TheilSenEstimator tsAlg = new TheilSenEstimator(arrangement.getLines(), arrangement.getNodes()); tsAlg.run(); tsAlg.getResult(); List errors = sampsonError(arrangement.getLines(), tsAlg.getSlope(), tsAlg.getyInterception()); tsResult = getResults(errors, "Theil-Sen"); setChanged(); notifyObservers(tsResult); }); lmsThread.start(); rmThread.start(); tsThread.start(); lmsThread.join(); rmThread.join(); tsThread.join(); } } public String[] getResults(List errorValues, String name) { ArrayList ret = new ArrayList<>(); ret.add("eval"); ret.add(name); ret.add(mse(errorValues).toString()); ret.add(rmse(errorValues).toString()); ret.add(mae(errorValues).toString()); ret.add(mdae(errorValues).toString()); return ret.stream().toArray(String[]::new); } /* Skalierungs Abhängige Approximationsgüten */ public Double mse(List errorValues) { double error = 0; for (Double d : errorValues) { error += Math.pow(d, 2); } error /= errorValues.size(); return error; } public Double rmse(List errorValues) { return Math.sqrt(mse(errorValues)); } public Double mae(List errorValues) { double error = 0; for (Double d : errorValues) { error += Math.abs(d); } error /= errorValues.size(); return error; } public Double mdae(List errorValues) { return FastElementSelector.randomizedSelect((ArrayList) errorValues, errorValues.size() * 0.5); } public List sampsonError(final LinkedList lines, Double m, Double b) { //Liste mit den Fehler zu jedem Punkt List sampsonerror = new ArrayList<>(); for (Line line : lines) { Double error = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1); sampsonerror.add(error); } return sampsonerror; } }