package presenter.evaluation; import model.Interval; import model.Line; import model.LineModel; import presenter.algorithms.IntersectionCounter; import presenter.algorithms.LeastMedianOfSquaresEstimator; import presenter.algorithms.RepeatedMedianEstimator; import presenter.algorithms.TheilSenEstimator; import presenter.generator.DatasetGenerator; import java.util.ArrayList; import java.util.LinkedList; 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 LineModel arrangement; private Thread lmsThread; private Thread rmThread; private Thread tsThread; private Double[] tsRes = new Double[2]; private Double[] rmRes = new Double[2]; private Double[] lmsRes = new Double[2]; private DatasetGenerator generator; private String[][] names = {{"MSE", "RMSE", "MAE", "MDAE"}, {"MAPE", "MDAPE", "RMSPE", "RMDSPE"}}; //übergebene Parameter private int type; private int iterations; private int alg; /** * Konstruktor zur evaluation * * @param type Typ der evaluation * @param n Größe des Datensatzes * @param alg 0 = lms, * 1 = rm, * 2 = ts, * 3 = lms, rm, * 4 = lms, ts, * 5 = rm, ts, * 6 = lms, rm, ts, */ public EvaluateAlgorithms(int type, int n, int alg, String datasettyp) { this.arrangement = new LineModel(); generator = new DatasetGenerator(); 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.type = type; this.iterations = n; this.alg = alg; IntersectionCounter counter = new IntersectionCounter(); counter.run(arrangement.getLines(), new Interval(-99999, 99999)); counter.calculateIntersectionAbscissas(arrangement); } public void run() throws InterruptedException { setChanged(); String[] msg = {"eval-dataset-generated"}; notifyObservers(msg); ArrayList result; ArrayList> multipleResults = new ArrayList<>(); switch (type) { case 0: result = new ArrayList<>(); //der alg der gewählt wurde if (alg == 0) { startLMS(); result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]); sendPlotLineResults(lmsRes, 0); } else if (alg == 1) { startRM(); result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]); sendPlotLineResults(rmRes, 1); } else { startTS(); result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]); sendPlotLineResults(tsRes, 2); } sendTableApproximationTypes(); sendTableApproximationData(result, alg); break; case 1: result = new ArrayList<>(); ArrayList lineRes; switch (alg) { case 3: startLMS(); startRM(); 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(lmsRes); lineRes.add(rmRes); sendPloteLineResults(lineRes, new Integer[]{0, 1}); break; case 4: startLMS(); startTS(); 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(lmsRes); lineRes.add(tsRes); sendPloteLineResults(lineRes, new Integer[]{0, 2}); break; case 5: startRM(); startTS(); 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(rmRes); lineRes.add(tsRes); sendPloteLineResults(lineRes, new Integer[]{1, 2}); break; case 6: startLMS(); startRM(); startTS(); 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(lmsRes); lineRes.add(rmRes); lineRes.add(tsRes); sendPloteLineResults(lineRes, new Integer[]{0, 1, 2}); break; } sendTableApproximationData(multipleResults); break; } } public void sendTableApproximationData(ArrayList result, int col) { ArrayList tableInput = new ArrayList<>(); tableInput.add("eval-d"); tableInput.add("" + col); for (int i = 0; i < names[type].length; i++) { tableInput.add(result.get(i)); } tableInput.add(""); setChanged(); notifyObservers(tableInput.stream().toArray(String[]::new)); tableInput.clear(); } public void sendTableApproximationData(ArrayList> result) { ArrayList tableInput = new ArrayList<>(); //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(""); } setChanged(); notifyObservers(tableInput.stream().toArray(String[]::new)); tableInput.clear(); } } public void sendTableApproximationTypes() { ArrayList tableInput = new ArrayList<>(); tableInput.add("eval-t"); tableInput.add("" + 0); for (int i = 0; i < names[type].length; i++) { tableInput.add(names[type][i]); } tableInput.add(""); setChanged(); notifyObservers(tableInput.stream().toArray(String[]::new)); tableInput.clear(); } public void sendPlotLineResults(Double[] res, int alg) { //visualisiere m,b ArrayList lines = new ArrayList<>(); lines.add("lines-res"); lines.add("" + alg); //lms res lines.add(res[0] + ""); lines.add(res[1] + ""); setChanged(); notifyObservers(lines.stream().toArray(String[]::new)); } public void sendPloteLineResults(ArrayList res, Integer[] algs) { ArrayList lines = new ArrayList<>(); lines.add("lines-res-mult"); for (int i = 0; i < algs.length; i++) { lines.add("" + algs[i]); //lms res Double[] tmp = res.get(i); lines.add(tmp[0] + ""); lines.add(tmp[1] + ""); } setChanged(); notifyObservers(lines.stream().toArray(String[]::new)); } public void startLMS() throws InterruptedException { lmsThread = new Thread(() -> { LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(arrangement.getLines(), arrangement.getNodes()); lmsAlg.run(); lmsAlg.getResult(); lmsRes[0] = lmsAlg.getSlope(); lmsRes[1] = lmsAlg.getyInterception(); }); lmsThread.start(); lmsThread.join(); } public void startRM() throws InterruptedException { rmThread = new Thread(() -> { RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(arrangement.getLines()); rmAlg.run(); rmAlg.getResult(); rmRes[0] = rmAlg.getSlope(); rmRes[1] = rmAlg.getyInterception(); }); rmThread.start(); rmThread.join(); } public void startTS() throws InterruptedException { tsThread = new Thread(() -> { TheilSenEstimator tsAlg = new TheilSenEstimator(arrangement.getLines(), arrangement.getNodes()); tsAlg.run(); tsAlg.getResult(); tsRes[0] = tsAlg.getSlope(); tsRes[1] = tsAlg.getyInterception(); }); tsThread.start(); tsThread.join(); } public ArrayList getScaleDependentMeasure(LinkedList lines, Double m, Double b) { ScaleDependentMeasure scaleDependentMeasure = new ScaleDependentMeasure(lines, m, b); ArrayList ret = new ArrayList<>(); ret.add(scaleDependentMeasure.mse().toString()); ret.add(scaleDependentMeasure.rmse().toString()); ret.add(scaleDependentMeasure.mae().toString()); ret.add(scaleDependentMeasure.mdae().toString()); return ret; } public ArrayList getPercentigeErrorBasedMeasure(LinkedList lines, Double m, Double b) { PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(lines, m, b); ArrayList ret = new ArrayList<>(); ret.add(percentageErrorBasedMeasure.mape().toString()); ret.add(percentageErrorBasedMeasure.mdape().toString()); ret.add(percentageErrorBasedMeasure.rmspe().toString()); ret.add(percentageErrorBasedMeasure.rmdspe().toString()); return ret; } public ArrayList getScaledErrorBasedMeasure(LinkedList lines, Double m, Double b) { ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b); ArrayList ret = new ArrayList<>(); ret.add(scaledErrorBasedMeasure.mse().toString()); ret.add(scaledErrorBasedMeasure.rmse().toString()); ret.add(scaledErrorBasedMeasure.mae().toString()); ret.add(scaledErrorBasedMeasure.mdae().toString()); return ret; } private ArrayList fillPseudoResults() { ArrayList result = new ArrayList<>(); result.add(" "); result.add(" "); result.add(" "); result.add(" "); return result; } public LinkedList getData() { return arrangement.getLines(); } }