diff --git a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java index 96c6eb2..eadec10 100644 --- a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java +++ b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java @@ -23,6 +23,8 @@ public class TheilSenEstimator extends Observable implements Algorithm { private Presenter presenter; private ArrayList set; private ArrayList intersectionSet; + private ArrayList yCoordinates; + private ArrayList xCoordinates; private Integer numberOfLinesOnLeft; private Slab interval; @@ -51,14 +53,16 @@ public class TheilSenEstimator extends Observable implements Algorithm { this.sampledIntersections = new ArrayList<>(); Double bin = BinomialCoeffizient.run(n, 2); this.numberOfLinesOnLeft = 0; + this.yCoordinates = new ArrayList<>(); + this.xCoordinates = new ArrayList<>(); - for (Line l : set){ - ymin = ymin > l.getB() ? l.getB() : ymin; - ymax = ymax < l.getB() ? l.getB() : ymax; + for (Point l : intersectionSet){ + yCoordinates.add(l.getX()); + xCoordinates.add(l.getY()); } this.k = Integer.valueOf((int) (bin / 2)); - this.N = bin; + this.N = BinomialCoeffizient.run(n, 2); } public void run(){ @@ -75,41 +79,63 @@ public class TheilSenEstimator extends Observable implements Algorithm { r = Double.valueOf(n); IntersectionCounter counter = new IntersectionCounter(); int numberOfIntersections = counter.run(set, new Slab(-10000,a)); + k = (int) (BinomialCoeffizient.run(n, 2)/2); j = (r /N) * (k - numberOfIntersections); - jA = (int) Math.floor(j - (3 * Math.sqrt(r))); - jB = (int) Math.floor(j + (3 * Math.sqrt(r))); + 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)))); do { sampledIntersections = randomSampleOfIntersections(intersectionSet, r); - Collections.sort(sampledIntersections); + //Collections.sort(sampledIntersections); aVariant = sampledIntersections.get(jA); bVariant = sampledIntersections.get(jB); } - while (!checkCondition(sampledIntersections)); + while (!checkCondition()); a = aVariant; b = bVariant; - N = Double.valueOf(checkNumberOfIntersectionInInterval(a,b,sampledIntersections)); + interval.setLower(a); + interval.setUpper(b); + N = Double.valueOf(checkNumberOfIntersectionInInterval(a,b)); } } 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+""}; + + double m,x; + double b,y; + + Collections.sort(xCoordinates); + 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); + } else { + x = xCoordinates.get(((n+1)/2)-1); + y = yCoordinates.get(((n+1)/2)-1); + } + + ArrayList resultSt = getKleftMostIntersection(a, this.b); + int size = resultSt.size(); + if (n % 2 == 0){ + m = resultSt.get((size/2)-1).getX() + resultSt.get((size/2)-2).getX(); + } else { + m = resultSt.get(((size+1)/2)-1).getX()* (-1); + } + + b = (x * m) + y; + m *= -1; + + String[] result = {"ts", m+"", b+""}; notifyObservers(result); } - System.out.println(interval.getLower()+" <=> "+interval.getUpper()); } - private Boolean checkCondition(ArrayList intersections){ - Boolean cond1 = (intersections.get(k) >= aVariant) && (intersections.get(k) < bVariant); - Boolean cond2 = (checkNumberOfIntersectionInInterval(aVariant,bVariant,intersections) <= ((11 * N) / Math.sqrt(r))); + 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; } @@ -126,13 +152,26 @@ public class TheilSenEstimator extends Observable implements Algorithm { } - public int checkNumberOfIntersectionInInterval(double a, double b, ArrayList intersections){ + public int checkNumberOfIntersectionInInterval(double a, double b){ int counter = 0; - for (Double x : intersections){ - if (x >= a && x < b){ + for (Point x : intersectionSet){ + if (x.getX() >= a && x.getX() < b){ counter++; } } return counter; } + + + public ArrayList getKleftMostIntersection(double a, double b){ + ArrayList list = new ArrayList<>(); + for (Point x : intersectionSet){ + if (x.getX() >= a && x.getX() < b){ + list.add(x); + } + } + + return list; + + } } diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index 971294c..5f4a924 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -39,19 +39,19 @@ public class Presenter implements Observer { this.view = view; // Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d}; // Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d}; -// Double[] x = {18d, 24d, 30d, 34d, 38d}; -// Double[] y = {18d, 26d, 30d, 40d, 70d}; + Double[] x = {18d, 24d, 30d, 34d, 38d}; + Double[] y = {18d, 26d, 30d, 40d, 70d}; // Double[] x = {1d,3d,4d,5d,8d}; // Double[] y = {4d,2d,1d,0d,0d}; -// view.logHeading("Duale Darstellung der Punkte als Geraden:"); -// for (int j = 0; j < x.length; j++) { -// Line p = new Line(x[j], y[j]); -// p.setId(j+""); -// view.log("f(x) = " + p.getM() + "x + " + p.getB()); -// this.model.addLine(p); -// } + view.logHeading("Duale Darstellung der Punkte als Geraden:"); + for (int j = 0; j < x.length; j++) { + Line p = new Line(x[j], y[j]); + p.setId(j+""); + view.log("f(x) = " + p.getM() + "x + " + p.getB()); + this.model.addLine(p); + } // -// calcArrangementNodes(); + calcArrangementNodes(); // //print // List heading = new LinkedList<>(); // List> rows = new LinkedList<>();