From 266d60da212b455463aa35e249ca4841bf1dfecd Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Thu, 29 Jun 2017 17:32:54 +0200 Subject: [PATCH] WIP: TS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nach der Besprechung bei Prof. Vahrenhold konnte der Theil-Sen Schätzer gefixt werden. Die Allgemeine Formel wie im paper gilt a einer Größe von n>36. Bei kleineren Werten eine Eingrezung benötigt Math.max(0,...) und Math.min(r-1,...). --- .../java/Model/{Slab.java => Interval.java} | 4 +- .../LeastMedianOfSquaresEstimator.java | 80 ++-- .../Algorithms/RepeatedMedianEstimator.java | 10 +- .../Algorithms/TheilSenEstimator.java | 390 ++++++++++-------- .../java/Presenter/Import/DataImporter.java | 4 +- .../java/Presenter/IntersectionCounter.java | 19 +- src/main/java/Presenter/Presenter.java | 5 +- .../java/Presenter/RandomLineSampler.java | 3 +- src/main/java/View/ArrangementDialog.java | 29 +- src/main/java/View/MainFrame.java | 50 +-- src/main/java/View/Panels/TSPanel.java | 23 +- .../LeastMedianOfSquaresEstimatorTest.java | 8 +- 12 files changed, 306 insertions(+), 319 deletions(-) rename src/main/java/Model/{Slab.java => Interval.java} (91%) diff --git a/src/main/java/Model/Slab.java b/src/main/java/Model/Interval.java similarity index 91% rename from src/main/java/Model/Slab.java rename to src/main/java/Model/Interval.java index 44d67eb..89263c1 100644 --- a/src/main/java/Model/Slab.java +++ b/src/main/java/Model/Interval.java @@ -7,13 +7,13 @@ package Model; * @Email: a_wolf28@uni-muenster.de * @Date: 16.06.2017. */ -public class Slab { +public class Interval { private double upper; private double lower; private Boolean activity; - public Slab(double lower, double upper) { + public Interval(double lower, double upper) { this.upper = upper; this.lower = lower; this.activity = true; diff --git a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java index 6df4dd5..0426d81 100644 --- a/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java +++ b/src/main/java/Presenter/Algorithms/LeastMedianOfSquaresEstimator.java @@ -1,8 +1,8 @@ package Presenter.Algorithms; +import Model.Interval; import Model.Line; import Model.Point; -import Model.Slab; import Presenter.*; import java.util.ArrayList; import java.util.Collections; @@ -31,9 +31,9 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit private double quantileError; private int kPlus; private int kMinus; - private PriorityQueue slabs; - private Slab subSlabU1; - private Slab subSlabU2; + private PriorityQueue intervals; + private Interval subSlabU1; + private Interval subSlabU2; private Line sigmaMin; private double heightsigmaMin; private Double intersectionsPoint; @@ -64,8 +64,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit */ public void run() { - //(2.) Let U <- (-inf, inf) be the initial active slabs... - Comparator comparator = (o1, o2) -> { + //(2.) Let U <- (-inf, inf) be the initial active intervals... + Comparator comparator = (o1, o2) -> { if (o1.getDistance() < o2.getDistance()) { return -1; } @@ -75,30 +75,30 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit return 0; } }; - slabs = new PriorityQueue<>(comparator); - slabs.add(new Slab(-100000, 100000)); + intervals = new PriorityQueue<>(comparator); + intervals.add(new Interval(-100000, 100000)); heightsigmaMin = Double.MAX_VALUE; LinkedList tmpIntersections = intersections; - //(3.) Apply the following steps as long as the exists active slabs + //(3.) Apply the following steps as long as the exists active intervals boolean active = true; - Slab slab; - while (!this.slabs.isEmpty()) { - slab = this.slabs.peek(); - if (slab.getActivity()) { - //(a.) Select any active Slab and calc. the inversions - int numberOfIntersections = countInversions(slab); + Interval interval; + while (!this.intervals.isEmpty()) { + interval = this.intervals.peek(); + if (interval.getActivity()) { + //(a.) Select any active Interval and calc. the inversions + int numberOfIntersections = countInversions(interval); //(b.) apply plane sweep if ((constant * n) >= numberOfIntersections) { - sigmaMin = planeSweep(slab); + sigmaMin = planeSweep(interval); } else { //(c.) otherwise.... // get random intersections point... Collections.shuffle(tmpIntersections, new Random()); for (int i = 0; i < tmpIntersections.size(); i++) { - if (tmpIntersections.get(i).getX() > slab.getLower() - && tmpIntersections.get(i).getX() < slab.getUpper()) { + if (tmpIntersections.get(i).getX() > interval.getLower() + && tmpIntersections.get(i).getX() < interval.getUpper()) { intersectionsPoint = tmpIntersections.get(i).getX(); break; } else { @@ -107,7 +107,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit } if (intersectionsPoint != null) { - splitActiveSlab(intersectionsPoint, slab); + splitActiveSlab(intersectionsPoint, interval); //(d.) this may update sigma min upperBound(intersectionsPoint); //(e.) for i={1,2}, call lower bound(Ui) @@ -115,51 +115,51 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit lowerBound(subSlabU2); if (subSlabU1.getActivity()) { - this.slabs.add(subSlabU1); + this.intervals.add(subSlabU1); } if (subSlabU2.getActivity()) { - this.slabs.add(subSlabU2); + this.intervals.add(subSlabU2); } } else { - this.slabs.poll(); + this.intervals.poll(); } } } else { - this.slabs.remove(slab); + this.intervals.remove(interval); } } } /** - * @param slab + * @param interval * @return */ - public int countInversions(Slab slab) { + public int countInversions(Interval interval) { int numberOfInversions = 0; // debug //for (int i=0;i xQueue = new ArrayList<>(); for (Point point : intersections) { - if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) { + if (point.getX() >= interval.getLower() && point.getX() < interval.getUpper()) { xQueue.add(point); } } @@ -179,21 +179,21 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit } } - slab.setActivity(false); + interval.setActivity(false); return bracelet; } /** - * Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs + * Diese Methode spaltet den aktiven Interval an der x Koordinate point. Es werden zwei neue Slabs * erzeugt. * * @param point x Koordinate an der, der Split geschieht. */ - public void splitActiveSlab(double point, Slab active) { - subSlabU1 = new Slab(active.getLower() + 0.01, point); - subSlabU2 = new Slab(point, active.getUpper()); + public void splitActiveSlab(double point, Interval active) { + subSlabU1 = new Interval(active.getLower() + 0.01, point); + subSlabU2 = new Interval(point, active.getUpper()); - this.slabs.remove(active); + this.intervals.remove(active); } /** @@ -231,7 +231,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit * @param pslab * @return */ - public void lowerBound(Slab pslab) { + public void lowerBound(Interval pslab) { int[] alpha = new int[n]; int[] beta = new int[n]; @@ -413,19 +413,19 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit this.kMinus = kMinus; } - public Slab getSubSlabU1() { + public Interval getSubSlabU1() { return subSlabU1; } - public void setSubSlabU1(Slab subSlabU1) { + public void setSubSlabU1(Interval subSlabU1) { this.subSlabU1 = subSlabU1; } - public Slab getSubSlabU2() { + public Interval getSubSlabU2() { return subSlabU2; } - public void setSubSlabU2(Slab subSlabU2) { + public void setSubSlabU2(Interval subSlabU2) { this.subSlabU2 = subSlabU2; } diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java index 72e042b..37f76e7 100644 --- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java +++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java @@ -1,7 +1,7 @@ package Presenter.Algorithms; +import Model.Interval; import Model.Line; -import Model.Slab; import Presenter.*; import java.util.ArrayList; import java.util.Collections; @@ -25,7 +25,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm { private HashMap> linePairs; private HashMap medianIntersections = new HashMap<>(); private HashMap> intersectionAbscissas = new HashMap<>(); - private Slab interval; + private Interval interval; //in der Literatur als L_i, C_i, und R_i bekannt private ArrayList countLeftSlab; @@ -51,7 +51,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm { public RepeatedMedianEstimator(LinkedList set, Presenter presenter) { this.set = set; this.presenter = presenter; - interval = new Slab(-10000, 10000); + interval = new Interval(-10000, 10000); n = set.size(); beta = 0.5; countLeftSlab = new ArrayList<>(); @@ -387,11 +387,11 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm { this.intersectionAbscissas = intersectionAbscissas; } - public Slab getInterval() { + public Interval getInterval() { return interval; } - public void setInterval(Slab interval) { + public void setInterval(Interval interval) { this.interval = interval; } diff --git a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java index f2c7b89..d8df8d0 100644 --- a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java +++ b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java @@ -2,11 +2,12 @@ package Presenter.Algorithms; import Model.Line; import Model.Point; -import Model.Slab; -import Presenter.*; +import Model.Interval; +import Presenter.BinomialCoeffizient; +import Presenter.Presenter; + import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.LinkedList; import java.util.Observable; import java.util.concurrent.ThreadLocalRandom; @@ -20,198 +21,233 @@ import java.util.concurrent.ThreadLocalRandom; */ public class TheilSenEstimator extends Observable implements Algorithm { - private Presenter presenter; - private ArrayList setOfLines; - private ArrayList setOfIntersections; - private ArrayList intervalIntersections; - private ArrayList yCoordinates; - private ArrayList xCoordinates; - private Slab interval; - - private Double j; - private Integer jA; - private Integer jB; - private Double r; - private Integer n; - private Double N; - private Integer k; - - private Double a; - private Double b; - private Double aVariant; - private Double bVariant; - private ArrayList sampledIntersections; + private final Double POSITIV_INF = 99999.0; + private final Double NEGATIV_INF = -99999.0; - public TheilSenEstimator(LinkedList setOfLines, LinkedList setOfIntersections, Presenter presenter) { - this.presenter = presenter; - this.setOfLines = new ArrayList<>(setOfLines); - this.setOfIntersections = new ArrayList<>(setOfIntersections); - this.intervalIntersections = new ArrayList<>(setOfIntersections); + private Presenter presenter; + private ArrayList setOfLines; + private ArrayList setOfIntersections; + private ArrayList intervalIntersections; + private ArrayList sampledIntersections; - this.n = setOfLines.size(); - this.sampledIntersections = new ArrayList<>(); - this.yCoordinates = new ArrayList<>(); - this.xCoordinates = new ArrayList<>(); - this.N = BinomialCoeffizient.run(n, 2); - this.k = Integer.valueOf((int) (N * 0.5)); - for (Point l : setOfIntersections){ - yCoordinates.add(l.getY()); - xCoordinates.add(l.getX()); - } - } + //wird benötigt um den y Achsenabschnitt zu Berechnen + private ArrayList yCoordinates; + private ArrayList xCoordinates; - /** - * - */ - public void run(){ - a = -90000d; - b = 90000d; + //Hilfsvariablen (siehe original Paper) + private Double j; + private Integer jA; + private Integer jB; + private Double r; + private Integer n; + private Double N; + private Integer k; - Collections.sort(setOfIntersections); + //Intervall und die temporaeren Grenzen + private Interval interval; + private Double aVariant; + private Double bVariant; - interval = new Slab(a,b); - while (true){ - if (this.N <= n){ - break; - } else { - r = Double.valueOf(n); + public TheilSenEstimator(LinkedList setOfLines, LinkedList setOfIntersections, Presenter presenter) { + this.presenter = presenter; + this.setOfLines = new ArrayList<>(setOfLines); + this.setOfIntersections = new ArrayList<>(setOfIntersections); + this.intervalIntersections = new ArrayList<>(setOfIntersections); + + this.n = setOfLines.size(); + this.sampledIntersections = new ArrayList<>(); + this.yCoordinates = new ArrayList<>(); + this.xCoordinates = new ArrayList<>(); + this.N = BinomialCoeffizient.run(n, 2); this.k = Integer.valueOf((int) (N * 0.5)); - System.out.println("#number: "+N); - int numberOfIntersections = checkNumberOfIntersectionInInterval(-90000,a, setOfIntersections); - j = (r /N) * (k - numberOfIntersections); - jA = (int) Math.floor(j - (3 * Math.sqrt(r))); - jB = (int) Math.floor(j + (3 * Math.sqrt(r))); - do { - sampledIntersections = randomSampleOfIntersections(intervalIntersections, r); - Collections.sort(sampledIntersections); - aVariant = sampledIntersections.get(jA); - bVariant = sampledIntersections.get(jB); - } while (!checkCondition()); - - a = aVariant; - b = bVariant; - interval.setLower(a); - interval.setUpper(b); - N = Double.valueOf(checkNumberOfIntersectionInInterval(a,b, intervalIntersections)); - intervalIntersections = getKleftMostIntersection(a,b); - } - } - } - - - /** - * Diese Funktion überprüft ob die Bedingung für das Interval erfüllt ist. Dabei muss der k-te - * Schnittpunkt in diesem Interval enthalten sein. des weiteren soll die Anzahl der Schnittpunkte - * im Interval kleiner oder gleich dem Term: (11*N)/sqrt(r) sein. - * - * @return Boolscher Wert ob die Bedingung erfüllt ist - */ - private Boolean checkCondition(){ - Collections.sort(intervalIntersections); - Boolean cond1 = (intervalIntersections.get(k-1).getX() >= aVariant) && ( - intervalIntersections.get(k-1).getX() < bVariant); - Boolean cond2 = (checkNumberOfIntersectionInInterval(aVariant,bVariant, intervalIntersections) <= ((11 * N) / Math.sqrt(r))); - return cond1 && cond2; - } - - /** - * Diese Funktion gibt eine r Elementige Stichprobe aus der überegebenene Menge an - * Schnittpunkten. Diese Stichprobe soll zufällig sein. Es können aus gleiche Werte in der Rückgabe - * vertreten sein. - * - * @param set Menge an Schnittpunkten - * @param r Stichprobengröße - * @return Stichprobe - */ - public ArrayList randomSampleOfIntersections(ArrayList set, Double r){ - ArrayList sampledLines = new ArrayList<>(); - - while (sampledLines.size() < r){ - Double x = set.get(ThreadLocalRandom.current().nextInt(0, set.size())).getX(); - if (!sampledLines.contains(x)) - sampledLines.add(x); + //Koordinaten werden gespeichert damit am ende + //der y Achsenabschnitt berechnet werden kann + for (Point l : setOfIntersections) { + yCoordinates.add(l.getY()); + xCoordinates.add(l.getX()); + } } - return sampledLines; + /** + * Randomisierter Algorithmus zur Berechnung des Theil-Sen Schätzers. + * Algorithmus stammt aus dem Paper: + * "Jiri Matousek, Randomized optimal algorithm for slope selection, + * Information Processing Letters 39 (1991) 183-187 + */ + public void run() { + //damit eine initiale Ordnung herscht + Collections.sort(intervalIntersections); - } + interval = new Interval(NEGATIV_INF, POSITIV_INF); + while (true) { + if (this.N <= n) { + break; + } else { + r = Double.valueOf(n); + //Anzahl der Schnittpunkte im Intervall [-Inf, a) + int numberOfIntersections = getIntervalSize(NEGATIV_INF, interval.getLower(), setOfIntersections); - /** - * Berechne wieviele von den Schnittpunkten in dem Interval zwischen a und b - * enthalten sind. - * - * @param a untere Grenze des Intervals - * @param b obere Grenze des Intrvals - * @return Anzahl der Schnittpunkte im Interval [a,b) - */ - public int checkNumberOfIntersectionInInterval(double a, double b, ArrayList set){ - int counter = 0; - for (Point x : set){ - if (x.getX() >= a && x.getX() < b){ - counter++; - } - } - return counter; - } + //Randomized Interpolating Search + j = (r / N) * (double) (k - numberOfIntersections); + jA = (int) Math.max(0, Math.floor(j - (1.5 * Math.sqrt(r)))); + jB = (int) Math.min(r-1, Math.floor(j + (1.5 * Math.sqrt(r)))); - /** - * Berechne wieviele von den Schnittpunkten in dem Interval zwischen a und b - * enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste festgehalten und diese werden - * zurückgeliefert. - * - * @param a untere Grenze des Intervals - * @param b obere Grenze des Intrvals - * @return Liste der Schnittpunkte die im Interval [a,b) vertreten sind - */ - public ArrayList getKleftMostIntersection(double a, double b){ - ArrayList list = new ArrayList<>(); - for (Point x : intervalIntersections){ - if (x.getX() >= a && x.getX() < b){ - list.add(x); - } + + /* Suche nach einem passenderen und kleineren Intervall + Schleife terminiert wenn die das k-te Elemnet zwischen aVariant und bVariant liegt und + das Intrvall weniger als 11*N / sqrt(r) Elemente besitzt */ + do { + //zufällige Stichprobe + sampledIntersections = randomSampleOfIntersections(intervalIntersections, r); + //TODO: hier vlt. Randomized Select?! + Collections.sort(sampledIntersections); + aVariant = sampledIntersections.get(jA); + bVariant = sampledIntersections.get(jB); + } while (!checkCondition()); + + interval.setLower(aVariant); + interval.setUpper(bVariant); + N = Double.valueOf(getIntervalSize(interval.getLower(), interval.getUpper())); + intervalIntersections = getIntervalElements(interval.getLower(), interval.getUpper()); + } + } } - return list; - } - - @Override - public void getResult() { - if (presenter != null) { - setChanged(); - - double m,x; - double b,y; - - Collections.sort(xCoordinates); - Collections.sort(yCoordinates); - int n = xCoordinates.size(); - if (n % 2 == 0){ - x = 0.5 * (xCoordinates.get((n/2)-1) + xCoordinates.get((n/2))); - y = 0.5 * (yCoordinates.get((n/2)-1) + yCoordinates.get((n/2))); - } else { - x = xCoordinates.get(((n+1)/2)-1); - y = yCoordinates.get(((n+1)/2)-1); - } - - ArrayList resultSt = getKleftMostIntersection(a, this.b); - int size = resultSt.size(); - if (size % 2 == 0){ - m = 0.5 * (resultSt.get((size/2)-1).getX() + resultSt.get((size/2)).getX()); - } else { - m = resultSt.get(((size+1)/2)-1).getX(); - } - m *= -1; - b = (x * m) + y; - - - String[] result = new String[]{"ts", m+"", b+""}; - notifyObservers(result); + /** + * Diese Funktion überprüft ob die Bedingung für das Interval erfüllt ist. Dabei muss der k-te + * Schnittpunkt in diesem Interval enthalten sein. des weiteren soll die Anzahl der Schnittpunkte + * im Interval kleiner oder gleich dem Term: (11*N)/sqrt(r) sein. + * + * @return Boolscher Wert ob die Bedingung erfüllt ist + */ + private Boolean checkCondition() { + Boolean cond1 = (setOfIntersections.get(k - 1).getX() >= aVariant) && ( + setOfIntersections.get(k - 1).getX() < bVariant); + Boolean cond2 = (getIntervalSize(aVariant, bVariant, intervalIntersections) <= ((11 * N) / Math.sqrt(r))); + return cond1 && cond2; } - } + + + /** + * Diese Funktion gibt eine r Elementige Stichprobe aus der überegebenene Menge an + * Schnittpunkten. Diese Stichprobe soll zufällig sein. Es können aus gleiche Werte in der Rückgabe + * vertreten sein. + * + * @param set Menge an Schnittpunkten + * @param r Stichprobengröße + * @return Stichprobe + */ + public ArrayList randomSampleOfIntersections(ArrayList set, Double r) { + ArrayList sampledLines = new ArrayList<>(); + + while (sampledLines.size() < r) { + Double x = set.get(ThreadLocalRandom.current().nextInt(0, set.size())).getX(); + sampledLines.add(x); + } + + return sampledLines; + + } + + /** + * Berechne wieviele von den Schnittpunkten in dem Interval zwischen a und b + * enthalten sind. + * + * @param a untere Grenze des Intervals + * @param b obere Grenze des Intrvals + * @return Anzahl der Schnittpunkte im Interval [a,b) + */ + public int getIntervalSize(double a, double b, ArrayList set) { + int counter = 0; + for (Point x : set) { + if (x.getX() >= a && x.getX() < b) { + counter++; + } + } + return counter; + } + + /** + * Berechne wieviele von den Schnittpunkten in dem Interval zwischen a und b + * enthalten sind. + * + * @param a untere Grenze des Intervals + * @param b obere Grenze des Intrvals + * @return Anzahl der Schnittpunkte im Interval [a,b) + */ + public int getIntervalSize(double a, double b) { + int counter = 0; + for (int i=0;i= a && x.getX() < b) { + counter++; + } + } + return counter; + } + + /** + * Berechne wieviele von den Schnittpunkten in dem Interval zwischen a und b + * enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste festgehalten und diese werden + * zurückgeliefert. + * + * @param a untere Grenze des Intervals + * @param b obere Grenze des Intrvals + * @return Liste der Schnittpunkte die im Interval [a,b) vertreten sind + */ + public ArrayList getIntervalElements(double a, double b) { + ArrayList list = new ArrayList<>(); + for (int i=0;i= a && x.getX() < b) { + list.add(x); + } + } + + return list; + + } + + @Override + public void getResult() { + if (presenter != null) { + setChanged(); + + double m, x; + double b, y; + + Collections.sort(xCoordinates); + Collections.sort(yCoordinates); + int n = xCoordinates.size(); + if (n % 2 == 0) { + x = 0.5 * (xCoordinates.get((n / 2) - 1) + xCoordinates.get((n / 2))); + y = 0.5 * (yCoordinates.get((n / 2) - 1) + yCoordinates.get((n / 2))); + } else { + x = xCoordinates.get(((n + 1) / 2) - 1); + y = yCoordinates.get(((n + 1) / 2) - 1); + } + + ArrayList resultSt = getIntervalElements(interval.getLower(), interval.getUpper()); + int size = resultSt.size(); + if (size % 2 == 0) { + m = 0.5 * (resultSt.get((size / 2) - 1).getX() + resultSt.get((size / 2)).getX()); + } else { + m = resultSt.get(((size + 1) / 2) - 1).getX(); + } + m *= -1; + b = (x * m) + y; + + + String[] result = new String[]{"ts", m + "", b + ""}; + notifyObservers(result); + } + } + + } diff --git a/src/main/java/Presenter/Import/DataImporter.java b/src/main/java/Presenter/Import/DataImporter.java index 5ebd349..5555e5e 100644 --- a/src/main/java/Presenter/Import/DataImporter.java +++ b/src/main/java/Presenter/Import/DataImporter.java @@ -4,14 +4,13 @@ import Model.Arrangement; import Model.Line; import Presenter.Presenter; import com.opencsv.CSVReader; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.List; import java.util.Observable; -import java.util.concurrent.ThreadLocalRandom; -import javax.swing.JOptionPane; /** @@ -73,4 +72,5 @@ public class DataImporter extends Observable{ } } + } diff --git a/src/main/java/Presenter/IntersectionCounter.java b/src/main/java/Presenter/IntersectionCounter.java index 18f4881..97d2bc7 100644 --- a/src/main/java/Presenter/IntersectionCounter.java +++ b/src/main/java/Presenter/IntersectionCounter.java @@ -2,7 +2,7 @@ package Presenter; import Model.Line; import Model.Pair; -import Model.Slab; +import Model.Interval; import Presenter.Comparators.YOrderLineComparatorBegin; import Presenter.Comparators.YOrderLineComparatorEnd; import java.util.ArrayList; @@ -10,7 +10,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import org.jfree.xml.factory.objects.DoubleObjectDescription; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -70,14 +69,14 @@ public class IntersectionCounter { * in der Liste und den Endpunkten des Intervalls entstehen. * * @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen - * @param slab Interval + * @param interval Interval * @return Anzahl an Inversionen */ - public int run(List set, Slab slab) { + public int run(List set, Interval interval) { ArrayList listA = new ArrayList<>(); ArrayList listB = new ArrayList<>(); - prepareData(set, slab, listA, listB); + prepareData(set, interval, listA, listB); return run(listA, listB); } @@ -87,12 +86,12 @@ public class IntersectionCounter { * Werte haben die selbe x Koordinate aber verschiedene y Koordinaten. * * @param set Liste mit Werten m,b - * @param slab Interval + * @param interval Interval * @param listA Schnittpunkte bzgl. unteren Grenze * @param listB Schnittpunkte bzgl. oberen Grenze */ - private void prepareData(List set, Slab slab, ArrayList listA, - ArrayList listB) { + private void prepareData(List set, Interval interval, ArrayList listA, + ArrayList listB) { secondaryDictionaryTO = new HashMap<>(); secondaryDictionaryBACK = new HashMap<>(); this.set = set; @@ -101,8 +100,8 @@ public class IntersectionCounter { for (Line p : set) { //vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet - tmpLine = new Line(p.getM(), p.getM(), slab.getLower() * p.getM() + p.getB(), - slab.getUpper() * p.getM() + p.getB()); + tmpLine = new Line(p.getM(), p.getM(), interval.getLower() * p.getM() + p.getB(), + interval.getUpper() * p.getM() + p.getB()); //wird benötigt um späer die Schnittpunkte ermitteln zu können tmpLine.setB(p.getB()); tmpLine.setM(p.getM()); diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index acea1d1..3b08043 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -8,13 +8,12 @@ import Presenter.Algorithms.RepeatedMedianEstimator; import Presenter.Algorithms.TheilSenEstimator; import Presenter.Import.DataImporter; import View.MainFrame; + +import javax.swing.*; import java.io.File; import java.util.LinkedList; -import java.util.List; import java.util.Observable; import java.util.Observer; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; /** diff --git a/src/main/java/Presenter/RandomLineSampler.java b/src/main/java/Presenter/RandomLineSampler.java index fd27df6..731c37e 100644 --- a/src/main/java/Presenter/RandomLineSampler.java +++ b/src/main/java/Presenter/RandomLineSampler.java @@ -1,8 +1,7 @@ package Presenter; import Model.Line; -import Model.Point; -import Model.Slab; + import java.util.ArrayList; import java.util.concurrent.ThreadLocalRandom; diff --git a/src/main/java/View/ArrangementDialog.java b/src/main/java/View/ArrangementDialog.java index a829259..3001d97 100644 --- a/src/main/java/View/ArrangementDialog.java +++ b/src/main/java/View/ArrangementDialog.java @@ -2,25 +2,6 @@ package View; import Model.Line; import Model.Point; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; -import java.util.LinkedList; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.JTextPane; -import javax.swing.border.Border; -import javax.swing.text.Style; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -33,6 +14,14 @@ import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.util.ShapeUtilities; +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.util.LinkedList; + /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -131,7 +120,7 @@ public class ArrangementDialog extends JPanel { this.setFocusable(true); JTextArea info = new JTextArea(); - info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung) und Mausrad verwendett werden."); + info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden."); Font font = new Font("Serif", Font.ITALIC, 12); info.setFont(font); info.setForeground(Color.DARK_GRAY); diff --git a/src/main/java/View/MainFrame.java b/src/main/java/View/MainFrame.java index 03b50c1..ee0eb62 100644 --- a/src/main/java/View/MainFrame.java +++ b/src/main/java/View/MainFrame.java @@ -2,41 +2,16 @@ package View; import Presenter.Presenter; -import View.Panels.LMSPanel; -import View.Panels.MenuPanel; -import View.Panels.OutputPanel; -import View.Panels.RMPanel; -import View.Panels.TSPanel; -import java.awt.BorderLayout; -import java.awt.ComponentOrientation; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Image; +import View.Panels.*; + +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.util.Arrays; import java.util.List; -import javax.imageio.ImageIO; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.SwingUtilities; -import javax.swing.border.Border; -import javax.swing.filechooser.FileFilter; -import javax.swing.filechooser.FileNameExtensionFilter; -import sun.misc.IOUtils; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -158,7 +133,7 @@ public class MainFrame extends JFrame { * init GUI ******************************************************************************************************************/ private void setTitles() { - this.setTitle("MainFrame"); + this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden"); importButton.setText("Import"); arrangementButton.setText("Dualraum"); } @@ -200,7 +175,7 @@ public class MainFrame extends JFrame { } private void setDimensions() { - this.setMinimumSize(new Dimension(1900,1000)); + //this.setMinimumSize(new Dimension(1366,768)); this.setExtendedState(JFrame.MAXIMIZED_BOTH); lmsPanel.setMinimumSize(new Dimension(400, 500)); rmPanel.setMinimumSize(new Dimension(400, 500)); @@ -251,6 +226,7 @@ public class MainFrame extends JFrame { arrangementButton.setIcon(new ImageIcon(imgPlot)); lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart)); rmPanel.getStartButton().setIcon(new ImageIcon(imgStart)); + tsPanel.getStartButton().setIcon(new ImageIcon(imgStart)); } catch (IOException e) { e.printStackTrace(); } @@ -279,11 +255,9 @@ public class MainFrame extends JFrame { }); tsPanel.getStartButton().addActionListener((ActionEvent e) -> { - if (tsPanel.getInput() != null){ - Thread t = new Thread( - () -> this.getPresenter().calculateTS(tsPanel.getInput())); - t.start(); - } + Thread t = new Thread( + () -> this.getPresenter().calculateTS("")); + t.start(); }); importButton.addActionListener((ActionEvent e) -> { diff --git a/src/main/java/View/Panels/TSPanel.java b/src/main/java/View/Panels/TSPanel.java index e9688e5..e7bb8c0 100644 --- a/src/main/java/View/Panels/TSPanel.java +++ b/src/main/java/View/Panels/TSPanel.java @@ -2,18 +2,10 @@ package View.Panels; import View.PlotDialog; import com.sun.istack.internal.Nullable; -import java.awt.BorderLayout; -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; + +import javax.swing.*; import javax.swing.border.TitledBorder; +import java.awt.*; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -50,16 +42,15 @@ public class TSPanel extends JPanel{ this.gbc.anchor = GridBagConstraints.NORTH; this.gbc.fill = GridBagConstraints.HORIZONTAL; - addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5); - + //addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); this.startButton = new JButton("Start"); this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16)); - gbc.insets = new Insets(30, 0, 10, 0); + gbc.insets = new Insets(10, 0, 10, 0); gbc.gridx = 0; - gbc.gridy = 2; + gbc.gridy = 0; gbc.weightx = 0.05; gbc.weighty = 0.05; buttonPanel.add(startButton); @@ -84,7 +75,7 @@ public class TSPanel extends JPanel{ gbc.weighty = 0.05; continer.add(this.labels, gbc); - gbc.gridx = 1; + gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.9; gbc.weighty = 0.05; diff --git a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java index b451d3d..7a3d874 100644 --- a/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java +++ b/src/test/java/Presenter/Algorithms/LeastMedianOfSquaresEstimatorTest.java @@ -7,7 +7,7 @@ import static org.junit.Assert.assertTrue; import Model.Line; import Model.Point; -import Model.Slab; +import Model.Interval; import Presenter.IntersectionCounter; import java.util.ArrayList; import java.util.LinkedList; @@ -110,9 +110,9 @@ public class LeastMedianOfSquaresEstimatorTest { Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d}; lms.setHeightsigmaMin(500); - Slab slab = new Slab(-2, 0); - lms.lowerBound(slab); - assertTrue(slab.getActivity()); + Interval interval = new Interval(-2, 0); + lms.lowerBound(interval); + assertTrue(interval.getActivity()); }