WIP: TS
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:
parent
3f405c9fda
commit
266d60da21
|
@ -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;
|
|
@ -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<Slab> slabs;
|
||||
private Slab subSlabU1;
|
||||
private Slab subSlabU2;
|
||||
private PriorityQueue<Interval> 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<Slab> comparator = (o1, o2) -> {
|
||||
//(2.) Let U <- (-inf, inf) be the initial active intervals...
|
||||
Comparator<Interval> 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<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;
|
||||
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<listA.size();i++){
|
||||
// System.out.println(listA.get(i)+", "+listB.get(i));
|
||||
//}
|
||||
numberOfInversions = invCounter.run(set, slab);
|
||||
numberOfInversions = invCounter.run(set, interval);
|
||||
|
||||
return numberOfInversions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param slab
|
||||
* @param interval
|
||||
* @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
|
||||
ArrayList<Point> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Line, ArrayList<Line>> linePairs;
|
||||
private HashMap<Line, Double> medianIntersections = 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
|
||||
private ArrayList<Integer> countLeftSlab;
|
||||
|
@ -51,7 +51,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
|
|||
public RepeatedMedianEstimator(LinkedList<Line> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Line> setOfLines;
|
||||
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;
|
||||
private final Double POSITIV_INF = 99999.0;
|
||||
private final Double NEGATIV_INF = -99999.0;
|
||||
|
||||
|
||||
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> 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<Line> setOfLines;
|
||||
private ArrayList<Point> setOfIntersections;
|
||||
private ArrayList<Point> intervalIntersections;
|
||||
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){
|
||||
yCoordinates.add(l.getY());
|
||||
xCoordinates.add(l.getX());
|
||||
}
|
||||
}
|
||||
//wird benötigt um den y Achsenabschnitt zu Berechnen
|
||||
private ArrayList<Double> yCoordinates;
|
||||
private ArrayList<Double> 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<Line> setOfLines, LinkedList<Point> 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 <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);
|
||||
//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 <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 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;
|
||||
}
|
||||
//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 <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> getKleftMostIntersection(double a, double b){
|
||||
ArrayList<Point> 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<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 ü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 <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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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{
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Line> set, Slab slab) {
|
||||
public int run(List<Line> set, Interval interval) {
|
||||
ArrayList<Integer> listA = new ArrayList<>();
|
||||
ArrayList<Integer> 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<Line> set, Slab slab, ArrayList<Integer> listA,
|
||||
ArrayList<Integer> listB) {
|
||||
private void prepareData(List<Line> set, Interval interval, ArrayList<Integer> listA,
|
||||
ArrayList<Integer> 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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package Presenter;
|
||||
|
||||
import Model.Line;
|
||||
import Model.Point;
|
||||
import Model.Slab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) -> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue