JavaDoc ergänzt, WIP: TS

This commit is contained in:
Armin Wolf 2017-06-29 13:10:15 +02:00
parent 96b6ec887b
commit 3f405c9fda
7 changed files with 210 additions and 157 deletions

View File

@ -9,5 +9,6 @@ package Presenter.Algorithms;
*/
public interface Algorithm {
void run();
void getResult();
}

View File

@ -65,17 +65,14 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
public void run() {
//(2.) Let U <- (-inf, inf) be the initial active slabs...
Comparator<Slab> comparator = new Comparator<Slab>() {
@Override
public int compare(Slab o1, Slab o2) {
if (o1.getDistance() < o2.getDistance()) {
return -1;
}
if (o1.getDistance() > o2.getDistance()) {
return 1;
} else {
return 0;
}
Comparator<Slab> comparator = (o1, o2) -> {
if (o1.getDistance() < o2.getDistance()) {
return -1;
}
if (o1.getDistance() > o2.getDistance()) {
return 1;
} else {
return 0;
}
};
slabs = new PriorityQueue<>(comparator);
@ -134,13 +131,6 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
this.slabs.remove(slab);
}
}
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5;
String[] result = {"lms", m+"", b+""};
notifyObservers(result);
}
}
/**
@ -359,6 +349,17 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5;
String[] result = {"lms", m+"", b+""};
notifyObservers(result);
}
}
/**
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
* JUnit Testfällen.

View File

@ -113,16 +113,6 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
contractIntervals();
}
if (presenter != null) {
setChanged();
double m = thetaLow * (-1);
double b = (
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
.getB());
String[] result = {"rm", m+"", b+""};
notifyObservers(result);
}
}
/**
@ -347,6 +337,19 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm {
}
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = thetaLow * (-1);
double b = (
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
.getB());
String[] result = new String[]{"rm", m+"", b+""};
notifyObservers(result);
}
}
/*******************************************************************************************************************
* Getter und Setter Methoden

View File

@ -6,7 +6,7 @@ import Model.Slab;
import Presenter.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.concurrent.ThreadLocalRandom;
@ -21,11 +21,11 @@ import java.util.concurrent.ThreadLocalRandom;
public class TheilSenEstimator extends Observable implements Algorithm {
private Presenter presenter;
private ArrayList<Line> set;
private ArrayList<Point> intersectionSet;
private ArrayList<Line> setOfLines;
private ArrayList<Point> setOfIntersections;
private ArrayList<Point> intervalIntersections;
private ArrayList<Double> yCoordinates;
private ArrayList<Double> xCoordinates;
private Integer numberOfLinesOnLeft;
private Slab interval;
private Double j;
@ -42,33 +42,35 @@ public class TheilSenEstimator extends Observable implements Algorithm {
private Double bVariant;
private ArrayList<Double> sampledIntersections;
private Double ymin = Double.MAX_VALUE;
private Double ymax = Double.MIN_VALUE;
public TheilSenEstimator(LinkedList<Line> set, LinkedList<Point> intersectionSet, Presenter presenter) {
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections, Presenter presenter) {
this.presenter = presenter;
this.intersectionSet = new ArrayList<>(intersectionSet);
this.set = new ArrayList<>(set);
this.n = set.size();
this.setOfLines = new ArrayList<>(setOfLines);
this.setOfIntersections = new ArrayList<>(setOfIntersections);
this.intervalIntersections = new ArrayList<>(setOfIntersections);
this.n = setOfLines.size();
this.sampledIntersections = new ArrayList<>();
Double bin = BinomialCoeffizient.run(n, 2);
this.numberOfLinesOnLeft = 0;
this.yCoordinates = new ArrayList<>();
this.xCoordinates = new ArrayList<>();
for (Point l : intersectionSet){
yCoordinates.add(l.getX());
xCoordinates.add(l.getY());
}
this.k = Integer.valueOf((int) (bin / 2));
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());
}
}
/**
*
*/
public void run(){
a = -10000d;
b = 10000d;
a = -90000d;
b = 90000d;
Collections.sort(setOfIntersections);
interval = new Slab(a,b);
while (true){
@ -77,29 +79,109 @@ public class TheilSenEstimator extends Observable implements Algorithm {
break;
} else {
r = Double.valueOf(n);
IntersectionCounter counter = new IntersectionCounter();
int numberOfIntersections = counter.run(set, new Slab(-10000,a));
k = (int) (BinomialCoeffizient.run(n, 2)/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.max(1,Math.floor(j - (3 * Math.sqrt(r))));
jB = (int) Math.min(r-1,Math.floor(j + (3 * Math.sqrt(r))));
jA = (int) Math.floor(j - (3 * Math.sqrt(r)));
jB = (int) Math.floor(j + (3 * Math.sqrt(r)));
do {
sampledIntersections = randomSampleOfIntersections(intersectionSet, r);
//Collections.sort(sampledIntersections);
sampledIntersections = randomSampleOfIntersections(intervalIntersections, r);
Collections.sort(sampledIntersections);
aVariant = sampledIntersections.get(jA);
bVariant = sampledIntersections.get(jB);
}
while (!checkCondition());
} while (!checkCondition());
a = aVariant;
b = bVariant;
interval.setLower(a);
interval.setUpper(b);
N = Double.valueOf(checkNumberOfIntersectionInInterval(a,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;
}
/**
* 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;
}
/**
* 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);
}
}
return list;
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
@ -110,8 +192,8 @@ public class TheilSenEstimator extends Observable implements Algorithm {
Collections.sort(yCoordinates);
int n = xCoordinates.size();
if (n % 2 == 0){
x = xCoordinates.get((n/2)-1) + xCoordinates.get((n/2)-2);
y = yCoordinates.get((n/2)-1) + yCoordinates.get((n/2)-2);
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);
@ -119,59 +201,17 @@ public class TheilSenEstimator extends Observable implements Algorithm {
ArrayList<Point> resultSt = getKleftMostIntersection(a, this.b);
int size = resultSt.size();
if (n % 2 == 0){
m = resultSt.get((size/2)-1).getX() + resultSt.get((size/2)-2).getX();
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()* (-1);
m = resultSt.get(((size+1)/2)-1).getX();
}
b = (x * m) + y;
m *= -1;
b = (x * m) + y;
String[] result = {"ts", m+"", b+""};
String[] result = new String[]{"ts", m+"", b+""};
notifyObservers(result);
}
}
private Boolean checkCondition(){
Boolean cond1 = (intersectionSet.get(k).getX() >= aVariant) && (intersectionSet.get(k).getX() < bVariant);
Boolean cond2 = (checkNumberOfIntersectionInInterval(aVariant,bVariant) <= ((11 * N) / Math.sqrt(r)));
return cond1 && cond2;
}
public ArrayList<Double> randomSampleOfIntersections(ArrayList<Point> set, Double r){
ArrayList<Double> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, set.size()-1)).getX());
}
return sampledLines;
}
public int checkNumberOfIntersectionInInterval(double a, double b){
int counter = 0;
for (Point x : intersectionSet){
if (x.getX() >= a && x.getX() < b){
counter++;
}
}
return counter;
}
public ArrayList<Point> getKleftMostIntersection(double a, double b){
ArrayList<Point> list = new ArrayList<>();
for (Point x : intersectionSet){
if (x.getX() >= a && x.getX() < b){
list.add(x);
}
}
return list;
}
}

View File

@ -32,7 +32,14 @@ public class IntersectionCounter {
private HashMap<Integer, Line> secondaryDictionaryBACK;
private ArrayList<Line> umin;
/**
* Berechnet die Inversionen zwischen zwei Listen mit Integer Werten. Diese Methode dient als
* Wrapper Methode. Die Logik steht in der <code>countInversions</code> Funktion.
*
* @param a Liste
* @param b Liste
* @return Anzahl an Inversionen
*/
public int run(List<Integer> a, List<Integer> b) {
dictionaryTO = new HashMap<>();
@ -58,6 +65,14 @@ public class IntersectionCounter {
return ret;
}
/**
* Wrapper Methode um herauszufinden wieviele Inversionen zwischen den Schnittpunkten der Werte
* in der Liste und den Endpunkten des Intervalls entstehen.
*
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
* @param slab Interval
* @return Anzahl an Inversionen
*/
public int run(List<Line> set, Slab slab) {
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
@ -66,7 +81,16 @@ public class IntersectionCounter {
return run(listA, listB);
}
/**
* Methode die, die Daten für die Funktion <code>run</code> vorbereitet. Es werden die Schnittpunkte
* bzgl. der unteren und oberen Grenze des Intervals und den Werten der Liste (m,b) berechnet. Diese
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
*
* @param set Liste mit Werten m,b
* @param slab 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) {
secondaryDictionaryTO = new HashMap<>();
@ -108,11 +132,11 @@ public class IntersectionCounter {
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
*
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
@ -149,7 +173,11 @@ public class IntersectionCounter {
return invCount;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*
* @return Map mit Schnittpunkt Paaren.
*/
public HashMap<Line, ArrayList<Line>> getIntersectionLinePairs() {
ArrayList<Pair> result = new ArrayList<>();
HashMap<Line, ArrayList<Line>> ret = new HashMap<>();
@ -192,6 +220,11 @@ public class IntersectionCounter {
return ret;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*
* @return x Koordinaten der Schnittpunkte
*/
public HashMap<Double,Double> calculateIntersectionAbscissas(){
ArrayList<Pair> result = new ArrayList<>();
HashMap<Double,Double> ret = new HashMap<>();
@ -214,8 +247,13 @@ public class IntersectionCounter {
return ret;
}
/**
* Berechnet die Schnittpunkte zwischen einer gegebenen Gerade und einer Menge an Geraden.
*
* @param set Menge an Geraden
* @param sampledLine eine spezielle Gerade
* @return Liste mit x Koordinaten der Schnittpunkte
*/
public ArrayList<Double> calculateIntersectionAbscissas(ArrayList<Line> set, Line sampledLine){
LinkedList<Line> lines = new LinkedList<>(set);
ArrayList<Double> intersections = new ArrayList<>();

View File

@ -29,11 +29,6 @@ public class Presenter implements Observer {
private Arrangement model;
private MainFrame view;
private LeastMedianOfSquaresEstimator lms;
private Double max;
private Double min;
public Presenter(Arrangement model, MainFrame view) {
this.model = model;
this.view = view;
@ -134,11 +129,12 @@ public class Presenter implements Observer {
if (input[0] != null && input[1] != null){
Double constant = Double.parseDouble(input[0]);
Double error = Double.parseDouble(input[1]);
lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
lms.setConstant(constant);
lms.setQuantileError(error);
lms.addObserver(this);
lms.run();
lms.getResult();
}
}
@ -149,6 +145,7 @@ public class Presenter implements Observer {
rm.setBeta(parameter);
rm.addObserver(this);
rm.run();
rm.getResult();
}
}
@ -158,6 +155,7 @@ public class Presenter implements Observer {
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(),this);
ts.addObserver(this);
ts.run();
ts.getResult();
}
}
@ -285,19 +283,4 @@ public class Presenter implements Observer {
this.model.setLines(lines);
}
public Double getMax() {
return max;
}
public void setMax(Double max) {
this.max = max;
}
public Double getMin() {
return min;
}
public void setMin(Double min) {
this.min = min;
}
}

View File

@ -16,10 +16,10 @@ import java.util.concurrent.ThreadLocalRandom;
public class RandomLineSampler {
/**
*
* @param set
* @param r
* @return
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe an Geraden.
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
* @param r Anzahl der zu wählenden Geraden
* @return <code>r</code> Elementige zufällige Stichprobe an Geraden
*/
public static ArrayList<Line> run(ArrayList<Line> set, Double r, Integer indexOfEnd) {
@ -31,17 +31,4 @@ public class RandomLineSampler {
return sampledLines;
}
/**
*
* @param set
* @param r
* @return
*/
public static ArrayList<Line> run(ArrayList<Line> set, Integer r) {
return run(set,Double.valueOf(r), set.size());
}
}