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,...).
This commit is contained in:
Armin Wolf 2017-06-29 17:32:54 +02:00
parent 3f405c9fda
commit 266d60da21
12 changed files with 306 additions and 319 deletions

View File

@ -7,13 +7,13 @@ package Model;
* @Email: a_wolf28@uni-muenster.de * @Email: a_wolf28@uni-muenster.de
* @Date: 16.06.2017. * @Date: 16.06.2017.
*/ */
public class Slab { public class Interval {
private double upper; private double upper;
private double lower; private double lower;
private Boolean activity; private Boolean activity;
public Slab(double lower, double upper) { public Interval(double lower, double upper) {
this.upper = upper; this.upper = upper;
this.lower = lower; this.lower = lower;
this.activity = true; this.activity = true;

View File

@ -1,8 +1,8 @@
package Presenter.Algorithms; package Presenter.Algorithms;
import Model.Interval;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Model.Slab;
import Presenter.*; import Presenter.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -31,9 +31,9 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
private double quantileError; private double quantileError;
private int kPlus; private int kPlus;
private int kMinus; private int kMinus;
private PriorityQueue<Slab> slabs; private PriorityQueue<Interval> intervals;
private Slab subSlabU1; private Interval subSlabU1;
private Slab subSlabU2; private Interval subSlabU2;
private Line sigmaMin; private Line sigmaMin;
private double heightsigmaMin; private double heightsigmaMin;
private Double intersectionsPoint; private Double intersectionsPoint;
@ -64,8 +64,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
*/ */
public void run() { public void run() {
//(2.) Let U <- (-inf, inf) be the initial active slabs... //(2.) Let U <- (-inf, inf) be the initial active intervals...
Comparator<Slab> comparator = (o1, o2) -> { Comparator<Interval> comparator = (o1, o2) -> {
if (o1.getDistance() < o2.getDistance()) { if (o1.getDistance() < o2.getDistance()) {
return -1; return -1;
} }
@ -75,30 +75,30 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
return 0; return 0;
} }
}; };
slabs = new PriorityQueue<>(comparator); intervals = new PriorityQueue<>(comparator);
slabs.add(new Slab(-100000, 100000)); intervals.add(new Interval(-100000, 100000));
heightsigmaMin = Double.MAX_VALUE; heightsigmaMin = Double.MAX_VALUE;
LinkedList<Point> tmpIntersections = intersections; LinkedList<Point> 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; boolean active = true;
Slab slab; Interval interval;
while (!this.slabs.isEmpty()) { while (!this.intervals.isEmpty()) {
slab = this.slabs.peek(); interval = this.intervals.peek();
if (slab.getActivity()) { if (interval.getActivity()) {
//(a.) Select any active Slab and calc. the inversions //(a.) Select any active Interval and calc. the inversions
int numberOfIntersections = countInversions(slab); int numberOfIntersections = countInversions(interval);
//(b.) apply plane sweep //(b.) apply plane sweep
if ((constant * n) >= numberOfIntersections) { if ((constant * n) >= numberOfIntersections) {
sigmaMin = planeSweep(slab); sigmaMin = planeSweep(interval);
} else { } else {
//(c.) otherwise.... //(c.) otherwise....
// get random intersections point... // get random intersections point...
Collections.shuffle(tmpIntersections, new Random()); Collections.shuffle(tmpIntersections, new Random());
for (int i = 0; i < tmpIntersections.size(); i++) { for (int i = 0; i < tmpIntersections.size(); i++) {
if (tmpIntersections.get(i).getX() > slab.getLower() if (tmpIntersections.get(i).getX() > interval.getLower()
&& tmpIntersections.get(i).getX() < slab.getUpper()) { && tmpIntersections.get(i).getX() < interval.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX(); intersectionsPoint = tmpIntersections.get(i).getX();
break; break;
} else { } else {
@ -107,7 +107,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
} }
if (intersectionsPoint != null) { if (intersectionsPoint != null) {
splitActiveSlab(intersectionsPoint, slab); splitActiveSlab(intersectionsPoint, interval);
//(d.) this may update sigma min //(d.) this may update sigma min
upperBound(intersectionsPoint); upperBound(intersectionsPoint);
//(e.) for i={1,2}, call lower bound(Ui) //(e.) for i={1,2}, call lower bound(Ui)
@ -115,51 +115,51 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
lowerBound(subSlabU2); lowerBound(subSlabU2);
if (subSlabU1.getActivity()) { if (subSlabU1.getActivity()) {
this.slabs.add(subSlabU1); this.intervals.add(subSlabU1);
} }
if (subSlabU2.getActivity()) { if (subSlabU2.getActivity()) {
this.slabs.add(subSlabU2); this.intervals.add(subSlabU2);
} }
} else { } else {
this.slabs.poll(); this.intervals.poll();
} }
} }
} else { } else {
this.slabs.remove(slab); this.intervals.remove(interval);
} }
} }
} }
/** /**
* @param slab * @param interval
* @return * @return
*/ */
public int countInversions(Slab slab) { public int countInversions(Interval interval) {
int numberOfInversions = 0; int numberOfInversions = 0;
// debug // debug
//for (int i=0;i<listA.size();i++){ //for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i)); // System.out.println(listA.get(i)+", "+listB.get(i));
//} //}
numberOfInversions = invCounter.run(set, slab); numberOfInversions = invCounter.run(set, interval);
return numberOfInversions; return numberOfInversions;
} }
/** /**
* @param slab * @param interval
* @return * @return
*/ */
public Line planeSweep(Slab slab) { public Line planeSweep(Interval interval) {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung //initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
ArrayList<Point> xQueue = new ArrayList<>(); ArrayList<Point> xQueue = new ArrayList<>();
for (Point point : intersections) { 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); xQueue.add(point);
} }
} }
@ -179,21 +179,21 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
} }
} }
slab.setActivity(false); interval.setActivity(false);
return bracelet; 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. * erzeugt.
* *
* @param point x Koordinate an der, der Split geschieht. * @param point x Koordinate an der, der Split geschieht.
*/ */
public void splitActiveSlab(double point, Slab active) { public void splitActiveSlab(double point, Interval active) {
subSlabU1 = new Slab(active.getLower() + 0.01, point); subSlabU1 = new Interval(active.getLower() + 0.01, point);
subSlabU2 = new Slab(point, active.getUpper()); 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 * @param pslab
* @return * @return
*/ */
public void lowerBound(Slab pslab) { public void lowerBound(Interval pslab) {
int[] alpha = new int[n]; int[] alpha = new int[n];
int[] beta = new int[n]; int[] beta = new int[n];
@ -413,19 +413,19 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
this.kMinus = kMinus; this.kMinus = kMinus;
} }
public Slab getSubSlabU1() { public Interval getSubSlabU1() {
return subSlabU1; return subSlabU1;
} }
public void setSubSlabU1(Slab subSlabU1) { public void setSubSlabU1(Interval subSlabU1) {
this.subSlabU1 = subSlabU1; this.subSlabU1 = subSlabU1;
} }
public Slab getSubSlabU2() { public Interval getSubSlabU2() {
return subSlabU2; return subSlabU2;
} }
public void setSubSlabU2(Slab subSlabU2) { public void setSubSlabU2(Interval subSlabU2) {
this.subSlabU2 = subSlabU2; this.subSlabU2 = subSlabU2;
} }

View File

@ -1,7 +1,7 @@
package Presenter.Algorithms; package Presenter.Algorithms;
import Model.Interval;
import Model.Line; import Model.Line;
import Model.Slab;
import Presenter.*; import Presenter.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -25,7 +25,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
private HashMap<Line, ArrayList<Line>> linePairs; private HashMap<Line, ArrayList<Line>> linePairs;
private HashMap<Line, Double> medianIntersections = new HashMap<>(); private HashMap<Line, Double> medianIntersections = new HashMap<>();
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>(); private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
private Slab interval; private Interval interval;
//in der Literatur als L_i, C_i, und R_i bekannt //in der Literatur als L_i, C_i, und R_i bekannt
private ArrayList<Integer> countLeftSlab; private ArrayList<Integer> countLeftSlab;
@ -51,7 +51,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) { public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) {
this.set = set; this.set = set;
this.presenter = presenter; this.presenter = presenter;
interval = new Slab(-10000, 10000); interval = new Interval(-10000, 10000);
n = set.size(); n = set.size();
beta = 0.5; beta = 0.5;
countLeftSlab = new ArrayList<>(); countLeftSlab = new ArrayList<>();
@ -387,11 +387,11 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
this.intersectionAbscissas = intersectionAbscissas; this.intersectionAbscissas = intersectionAbscissas;
} }
public Slab getInterval() { public Interval getInterval() {
return interval; return interval;
} }
public void setInterval(Slab interval) { public void setInterval(Interval interval) {
this.interval = interval; this.interval = interval;
} }

View File

@ -2,11 +2,12 @@ package Presenter.Algorithms;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Model.Slab; import Model.Interval;
import Presenter.*; import Presenter.BinomialCoeffizient;
import Presenter.Presenter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Observable; import java.util.Observable;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@ -20,198 +21,233 @@ import java.util.concurrent.ThreadLocalRandom;
*/ */
public class TheilSenEstimator extends Observable implements Algorithm { public class TheilSenEstimator extends Observable implements Algorithm {
private Presenter presenter; private final Double POSITIV_INF = 99999.0;
private ArrayList<Line> setOfLines; private final Double NEGATIV_INF = -99999.0;
private ArrayList<Point> setOfIntersections;
private ArrayList<Point> intervalIntersections;
private ArrayList<Double> yCoordinates;
private ArrayList<Double> 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<Double> sampledIntersections;
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections, Presenter presenter) { private Presenter presenter;
this.presenter = presenter; private ArrayList<Line> setOfLines;
this.setOfLines = new ArrayList<>(setOfLines); private ArrayList<Point> setOfIntersections;
this.setOfIntersections = new ArrayList<>(setOfIntersections); private ArrayList<Point> intervalIntersections;
this.intervalIntersections = new ArrayList<>(setOfIntersections); private ArrayList<Double> 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){ //wird benötigt um den y Achsenabschnitt zu Berechnen
yCoordinates.add(l.getY()); private ArrayList<Double> yCoordinates;
xCoordinates.add(l.getX()); private ArrayList<Double> xCoordinates;
}
}
/**
*
*/
public void run(){
a = -90000d; //Hilfsvariablen (siehe original Paper)
b = 90000d; 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){ public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections, Presenter presenter) {
break; this.presenter = presenter;
} else { this.setOfLines = new ArrayList<>(setOfLines);
r = Double.valueOf(n); 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)); 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 { //Koordinaten werden gespeichert damit am ende
sampledIntersections = randomSampleOfIntersections(intervalIntersections, r); //der y Achsenabschnitt berechnet werden kann
Collections.sort(sampledIntersections); for (Point l : setOfIntersections) {
aVariant = sampledIntersections.get(jA); yCoordinates.add(l.getY());
bVariant = sampledIntersections.get(jB); xCoordinates.add(l.getX());
} 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 <code>r</code> 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<Double> randomSampleOfIntersections(ArrayList<Point> set, Double r){
ArrayList<Double> 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);
} }
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);
/** //Randomized Interpolating Search
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und <code>b</code> j = (r / N) * (double) (k - numberOfIntersections);
* enthalten sind. 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))));
* @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<Point> 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 <code>a</code> und <code>b</code> /* Suche nach einem passenderen und kleineren Intervall
* enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste festgehalten und diese werden Schleife terminiert wenn die das k-te Elemnet zwischen aVariant und bVariant liegt und
* zurückgeliefert. das Intrvall weniger als 11*N / sqrt(r) Elemente besitzt */
* do {
* @param a untere Grenze des Intervals //zufällige Stichprobe
* @param b obere Grenze des Intrvals sampledIntersections = randomSampleOfIntersections(intervalIntersections, r);
* @return Liste der Schnittpunkte die im Interval [a,b) vertreten sind //TODO: hier vlt. Randomized Select?!
*/ Collections.sort(sampledIntersections);
public ArrayList<Point> getKleftMostIntersection(double a, double b){ aVariant = sampledIntersections.get(jA);
ArrayList<Point> list = new ArrayList<>(); bVariant = sampledIntersections.get(jB);
for (Point x : intervalIntersections){ } while (!checkCondition());
if (x.getX() >= a && x.getX() < b){
list.add(x); interval.setLower(aVariant);
} interval.setUpper(bVariant);
N = Double.valueOf(getIntervalSize(interval.getLower(), interval.getUpper()));
intervalIntersections = getIntervalElements(interval.getLower(), interval.getUpper());
}
}
} }
return list;
} /**
* Diese Funktion überprüft ob die Bedingung für das Interval erfüllt ist. Dabei muss der k-te
@Override * Schnittpunkt in diesem Interval enthalten sein. des weiteren soll die Anzahl der Schnittpunkte
public void getResult() { * im Interval kleiner oder gleich dem Term: (11*N)/sqrt(r) sein.
if (presenter != null) { *
setChanged(); * @return Boolscher Wert ob die Bedingung erfüllt ist
*/
double m,x; private Boolean checkCondition() {
double b,y; Boolean cond1 = (setOfIntersections.get(k - 1).getX() >= aVariant) && (
setOfIntersections.get(k - 1).getX() < bVariant);
Collections.sort(xCoordinates); Boolean cond2 = (getIntervalSize(aVariant, bVariant, intervalIntersections) <= ((11 * N) / Math.sqrt(r)));
Collections.sort(yCoordinates); return cond1 && cond2;
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<Point> 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 gibt eine <code>r</code> 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<Double> randomSampleOfIntersections(ArrayList<Point> set, Double r) {
ArrayList<Double> 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 <code>a</code> und <code>b</code>
* 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<Point> 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 <code>a</code> und <code>b</code>
* 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<intervalIntersections.size();i++) {
Point x = intervalIntersections.get(i);
if (x.getX() >= a && x.getX() < b) {
counter++;
}
}
return counter;
}
/**
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und <code>b</code>
* enthalten sind. Zusätzlich werden diese Schnittpunkte in einer Liste festgehalten und diese werden
* zurückgeliefert.
*
* @param a untere Grenze des Intervals
* @param b obere Grenze des Intrvals
* @return Liste der Schnittpunkte die im Interval [a,b) vertreten sind
*/
public ArrayList<Point> getIntervalElements(double a, double b) {
ArrayList<Point> list = new ArrayList<>();
for (int i=0;i<intervalIntersections.size();i++) {
Point x = intervalIntersections.get(i);
if (x.getX() >= 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<Point> 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);
}
}
} }

View File

@ -4,14 +4,13 @@ import Model.Arrangement;
import Model.Line; import Model.Line;
import Presenter.Presenter; import Presenter.Presenter;
import com.opencsv.CSVReader; import com.opencsv.CSVReader;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.concurrent.ThreadLocalRandom;
import javax.swing.JOptionPane;
/** /**
@ -73,4 +72,5 @@ public class DataImporter extends Observable{
} }
} }
} }

View File

@ -2,7 +2,7 @@ package Presenter;
import Model.Line; import Model.Line;
import Model.Pair; import Model.Pair;
import Model.Slab; import Model.Interval;
import Presenter.Comparators.YOrderLineComparatorBegin; import Presenter.Comparators.YOrderLineComparatorBegin;
import Presenter.Comparators.YOrderLineComparatorEnd; import Presenter.Comparators.YOrderLineComparatorEnd;
import java.util.ArrayList; import java.util.ArrayList;
@ -10,7 +10,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.jfree.xml.factory.objects.DoubleObjectDescription;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -70,14 +69,14 @@ public class IntersectionCounter {
* in der Liste und den Endpunkten des Intervalls entstehen. * in der Liste und den Endpunkten des Intervalls entstehen.
* *
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen * @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
* @param slab Interval * @param interval Interval
* @return Anzahl an Inversionen * @return Anzahl an Inversionen
*/ */
public int run(List<Line> set, Slab slab) { public int run(List<Line> set, Interval interval) {
ArrayList<Integer> listA = new ArrayList<>(); ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>(); ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, slab, listA, listB); prepareData(set, interval, listA, listB);
return run(listA, listB); return run(listA, listB);
} }
@ -87,12 +86,12 @@ public class IntersectionCounter {
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten. * Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
* *
* @param set Liste mit Werten m,b * @param set Liste mit Werten m,b
* @param slab Interval * @param interval Interval
* @param listA Schnittpunkte bzgl. unteren Grenze * @param listA Schnittpunkte bzgl. unteren Grenze
* @param listB Schnittpunkte bzgl. oberen Grenze * @param listB Schnittpunkte bzgl. oberen Grenze
*/ */
private void prepareData(List<Line> set, Slab slab, ArrayList<Integer> listA, private void prepareData(List<Line> set, Interval interval, ArrayList<Integer> listA,
ArrayList<Integer> listB) { ArrayList<Integer> listB) {
secondaryDictionaryTO = new HashMap<>(); secondaryDictionaryTO = new HashMap<>();
secondaryDictionaryBACK = new HashMap<>(); secondaryDictionaryBACK = new HashMap<>();
this.set = set; this.set = set;
@ -101,8 +100,8 @@ public class IntersectionCounter {
for (Line p : set) { for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet //vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
tmpLine = new Line(p.getM(), p.getM(), slab.getLower() * p.getM() + p.getB(), tmpLine = new Line(p.getM(), p.getM(), interval.getLower() * p.getM() + p.getB(),
slab.getUpper() * p.getM() + p.getB()); interval.getUpper() * p.getM() + p.getB());
//wird benötigt um späer die Schnittpunkte ermitteln zu können //wird benötigt um späer die Schnittpunkte ermitteln zu können
tmpLine.setB(p.getB()); tmpLine.setB(p.getB());
tmpLine.setM(p.getM()); tmpLine.setM(p.getM());

View File

@ -8,13 +8,12 @@ import Presenter.Algorithms.RepeatedMedianEstimator;
import Presenter.Algorithms.TheilSenEstimator; import Presenter.Algorithms.TheilSenEstimator;
import Presenter.Import.DataImporter; import Presenter.Import.DataImporter;
import View.MainFrame; import View.MainFrame;
import javax.swing.*;
import java.io.File; import java.io.File;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/** /**

View File

@ -1,8 +1,7 @@
package Presenter; package Presenter;
import Model.Line; import Model.Line;
import Model.Point;
import Model.Slab;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;

View File

@ -2,25 +2,6 @@ package View;
import Model.Line; import Model.Line;
import Model.Point; 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.ChartFactory;
import org.jfree.chart.ChartPanel; import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart; import org.jfree.chart.JFreeChart;
@ -33,6 +14,14 @@ import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection; import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities; 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. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -131,7 +120,7 @@ public class ArrangementDialog extends JPanel {
this.setFocusable(true); this.setFocusable(true);
JTextArea info = new JTextArea(); 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); Font font = new Font("Serif", Font.ITALIC, 12);
info.setFont(font); info.setFont(font);
info.setForeground(Color.DARK_GRAY); info.setForeground(Color.DARK_GRAY);

View File

@ -2,41 +2,16 @@ package View;
import Presenter.Presenter; import Presenter.Presenter;
import View.Panels.LMSPanel; import View.Panels.*;
import View.Panels.MenuPanel;
import View.Panels.OutputPanel; import javax.imageio.ImageIO;
import View.Panels.RMPanel; import javax.swing.*;
import View.Panels.TSPanel; import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.BorderLayout; import java.awt.*;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; 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. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -158,7 +133,7 @@ public class MainFrame extends JFrame {
* init GUI * init GUI
******************************************************************************************************************/ ******************************************************************************************************************/
private void setTitles() { private void setTitles() {
this.setTitle("MainFrame"); this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
importButton.setText("Import"); importButton.setText("Import");
arrangementButton.setText("Dualraum"); arrangementButton.setText("Dualraum");
} }
@ -200,7 +175,7 @@ public class MainFrame extends JFrame {
} }
private void setDimensions() { private void setDimensions() {
this.setMinimumSize(new Dimension(1900,1000)); //this.setMinimumSize(new Dimension(1366,768));
this.setExtendedState(JFrame.MAXIMIZED_BOTH); this.setExtendedState(JFrame.MAXIMIZED_BOTH);
lmsPanel.setMinimumSize(new Dimension(400, 500)); lmsPanel.setMinimumSize(new Dimension(400, 500));
rmPanel.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)); arrangementButton.setIcon(new ImageIcon(imgPlot));
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart)); lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart)); rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -279,11 +255,9 @@ public class MainFrame extends JFrame {
}); });
tsPanel.getStartButton().addActionListener((ActionEvent e) -> { tsPanel.getStartButton().addActionListener((ActionEvent e) -> {
if (tsPanel.getInput() != null){ Thread t = new Thread(
Thread t = new Thread( () -> this.getPresenter().calculateTS(""));
() -> this.getPresenter().calculateTS(tsPanel.getInput())); t.start();
t.start();
}
}); });
importButton.addActionListener((ActionEvent e) -> { importButton.addActionListener((ActionEvent e) -> {

View File

@ -2,18 +2,10 @@ package View.Panels;
import View.PlotDialog; import View.PlotDialog;
import com.sun.istack.internal.Nullable; import com.sun.istack.internal.Nullable;
import java.awt.BorderLayout;
import java.awt.FlowLayout; import javax.swing.*;
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.border.TitledBorder; import javax.swing.border.TitledBorder;
import java.awt.*;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -50,16 +42,15 @@ public class TSPanel extends JPanel{
this.gbc.anchor = GridBagConstraints.NORTH; this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL; 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(); JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.startButton = new JButton("Start"); this.startButton = new JButton("Start");
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16)); 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.gridx = 0;
gbc.gridy = 2; gbc.gridy = 0;
gbc.weightx = 0.05; gbc.weightx = 0.05;
gbc.weighty = 0.05; gbc.weighty = 0.05;
buttonPanel.add(startButton); buttonPanel.add(startButton);
@ -84,7 +75,7 @@ public class TSPanel extends JPanel{
gbc.weighty = 0.05; gbc.weighty = 0.05;
continer.add(this.labels, gbc); continer.add(this.labels, gbc);
gbc.gridx = 1; gbc.gridx = 0;
gbc.gridy = row; gbc.gridy = row;
gbc.weightx = 0.9; gbc.weightx = 0.9;
gbc.weighty = 0.05; gbc.weighty = 0.05;

View File

@ -7,7 +7,7 @@ import static org.junit.Assert.assertTrue;
import Model.Line; import Model.Line;
import Model.Point; import Model.Point;
import Model.Slab; import Model.Interval;
import Presenter.IntersectionCounter; import Presenter.IntersectionCounter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
@ -110,9 +110,9 @@ public class LeastMedianOfSquaresEstimatorTest {
Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d}; Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
lms.setHeightsigmaMin(500); lms.setHeightsigmaMin(500);
Slab slab = new Slab(-2, 0); Interval interval = new Interval(-2, 0);
lms.lowerBound(slab); lms.lowerBound(interval);
assertTrue(slab.getActivity()); assertTrue(interval.getActivity());
} }