139 lines
3.9 KiB
Java
139 lines
3.9 KiB
Java
package Presenter.Algorithms;
|
|
|
|
import Model.Line;
|
|
import Model.Point;
|
|
import Model.Slab;
|
|
import Presenter.*;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.Observable;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
/**
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
*
|
|
* @Author: Armin Wolf
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
* @Date: 28.05.2017.
|
|
*/
|
|
public class TheilSenEstimator extends Observable implements Algorithm {
|
|
|
|
private Presenter presenter;
|
|
private ArrayList<Line> set;
|
|
private ArrayList<Point> intersectionSet;
|
|
private Integer numberOfLinesOnLeft;
|
|
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 Double ymin = Double.MAX_VALUE;
|
|
private Double ymax = Double.MIN_VALUE;
|
|
|
|
public TheilSenEstimator(LinkedList<Line> set, LinkedList<Point> intersectionSet, Presenter presenter) {
|
|
this.presenter = presenter;
|
|
this.intersectionSet = new ArrayList<>(intersectionSet);
|
|
this.set = new ArrayList<>(set);
|
|
this.n = set.size();
|
|
this.sampledIntersections = new ArrayList<>();
|
|
Double bin = BinomialCoeffizient.run(n, 2);
|
|
this.numberOfLinesOnLeft = 0;
|
|
|
|
for (Line l : set){
|
|
ymin = ymin > l.getB() ? l.getB() : ymin;
|
|
ymax = ymax < l.getB() ? l.getB() : ymax;
|
|
}
|
|
|
|
this.k = Integer.valueOf((int) (bin / 2));
|
|
this.N = bin;
|
|
}
|
|
|
|
public void run(){
|
|
|
|
a = -10000d;
|
|
b = 10000d;
|
|
|
|
interval = new Slab(a,b);
|
|
while (true){
|
|
|
|
if (this.N <= n){
|
|
break;
|
|
} else {
|
|
r = Double.valueOf(n);
|
|
IntersectionCounter counter = new IntersectionCounter();
|
|
int numberOfIntersections = counter.run(set, new Slab(-10000,a));
|
|
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(intersectionSet, r);
|
|
Collections.sort(sampledIntersections);
|
|
aVariant = sampledIntersections.get(jA);
|
|
bVariant = sampledIntersections.get(jB);
|
|
}
|
|
while (!checkCondition(sampledIntersections));
|
|
|
|
a = aVariant;
|
|
b = bVariant;
|
|
N = Double.valueOf(checkNumberOfIntersectionInInterval(a,b,sampledIntersections));
|
|
}
|
|
}
|
|
|
|
if (presenter != null) {
|
|
setChanged();
|
|
double m = (interval.getLower() + interval.getUpper()) * (-0.5);
|
|
double min = Collections.min(sampledIntersections);
|
|
double max = Collections.max(sampledIntersections);
|
|
double avgx = (min + max) *0.5;
|
|
double avgy = (ymin + ymax) * 0.5;
|
|
double b = ((avgx * m) + avgy);
|
|
String[] result = {"rm", m+"", b+""};
|
|
notifyObservers(result);
|
|
}
|
|
System.out.println(interval.getLower()+" <=> "+interval.getUpper());
|
|
}
|
|
|
|
private Boolean checkCondition(ArrayList<Double> intersections){
|
|
Boolean cond1 = (intersections.get(k) >= aVariant) && (intersections.get(k) < bVariant);
|
|
Boolean cond2 = (checkNumberOfIntersectionInInterval(aVariant,bVariant,intersections) <= ((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, ArrayList<Double> intersections){
|
|
int counter = 0;
|
|
for (Double x : intersections){
|
|
if (x >= a && x < b){
|
|
counter++;
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
}
|