diff --git a/src/main/java/Model/Arrangement.java b/src/main/java/Model/Arrangement.java index 7e5b4e2..7f18235 100644 --- a/src/main/java/Model/Arrangement.java +++ b/src/main/java/Model/Arrangement.java @@ -1,5 +1,6 @@ package Model; +import java.util.Collections; import java.util.LinkedList; /** @@ -23,6 +24,26 @@ public class Arrangement { lines = new LinkedList<>(); } + public void setXbounds(){ + LinkedList xlist = new LinkedList<>(); + for (Point p : nodes){ + xlist.add(p.getX()); + } + + xMaximum = Collections.max(xlist); + xMinimum = Collections.min(xlist); + } + + public void setYbounds(){ + LinkedList ylist = new LinkedList<>(); + for (Point p : nodes){ + ylist.add(p.getY()); + } + + yMaximum = Collections.max(ylist); + yMinimum = Collections.min(ylist); + } + public void addNode(Point node) { this.nodes.add(node); } diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java index 37f76e7..1c0cb9d 100644 --- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java +++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java @@ -3,14 +3,11 @@ package Presenter.Algorithms; import Model.Interval; import Model.Line; 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.Random; + +import java.util.*; import java.util.concurrent.ThreadLocalRandom; + /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * @@ -101,8 +98,8 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm { // System.err.print("#medianIntersectionAbscissa: "+medianIntersectionAbscissas.size()+"\t\t klow: "+kLow+" kHigh: "+kHigh+"\n\n"); //Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi - thetaLow = randomizedSelect(medianIntersectionAbscissas, kLow); - thetaHigh = randomizedSelect(medianIntersectionAbscissas, kHigh); + thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow); + thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh); //For each dual Line in C count the number of intersection abscissas that lie //in each of the intervals. @@ -180,81 +177,7 @@ public class RepeatedMedianEstimator extends Observable implements Algorithm { ); } - /** - * - * @param a - * @param i - * @return - */ - public Double randomizedSelect(ArrayList a, double i) { - int start = 0; - int end = a.size()-1; - if (i >= end+1){ - return a.get(end); - } - while(true){ - if(start == end){ - return a.get(start); - } - int q = randomizedPartition(a, start, end); - int k = q-start+1; - - if(i == k){ - return a.get(q); - } - else{ - if(i a, int start, int end) { - int i = 0; - Random random = new Random(System.currentTimeMillis()); - - //alternative: ThreadLocalRandom.current() - if(start < end){ - i = start + random.nextInt(end-start); - }else{ - i = end + random.nextInt(start-end); - } - - Collections.swap(a, end, i); - return partition(a, start, end); - } - - /** - * - * @param a - * @param start - * @param end - * @return - */ - public int partition(ArrayList a, int start, int end) { - Double x = a.get(end); - int i = start - 1; - for (int j = start; j <= end-1; j++) { - if (a.get(j) <= x) { - i++; - Collections.swap(a, i, j); - } - } - Collections.swap(a, i+1, end); - return i+1; - } /** * diff --git a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java index d8df8d0..7c33b63 100644 --- a/src/main/java/Presenter/Algorithms/TheilSenEstimator.java +++ b/src/main/java/Presenter/Algorithms/TheilSenEstimator.java @@ -1,16 +1,13 @@ package Presenter.Algorithms; +import Model.Interval; import Model.Line; import Model.Point; -import Model.Interval; import Presenter.BinomialCoeffizient; +import Presenter.FastElementSelector; import Presenter.Presenter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.Observable; -import java.util.concurrent.ThreadLocalRandom; +import java.util.*; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. @@ -94,8 +91,8 @@ public class TheilSenEstimator extends Observable implements Algorithm { //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)))); + jA = (int) Math.max(1, Math.floor(j - (1.5 * Math.sqrt(r)))); + jB = (int) Math.min(r, Math.floor(j + (1.5 * Math.sqrt(r)))); /* Suche nach einem passenderen und kleineren Intervall @@ -105,9 +102,11 @@ public class TheilSenEstimator extends Observable implements Algorithm { //zufällige Stichprobe sampledIntersections = randomSampleOfIntersections(intervalIntersections, r); //TODO: hier vlt. Randomized Select?! - Collections.sort(sampledIntersections); + /*Collections.sort(sampledIntersections); aVariant = sampledIntersections.get(jA); - bVariant = sampledIntersections.get(jB); + bVariant = sampledIntersections.get(jB);*/ + aVariant = FastElementSelector.randomizedSelect(sampledIntersections, jA); + bVariant = FastElementSelector.randomizedSelect(sampledIntersections, jB); } while (!checkCondition()); interval.setLower(aVariant); @@ -127,8 +126,10 @@ public class TheilSenEstimator extends Observable implements Algorithm { * @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); + Double kthElement = FastElementSelector.randomizedSelect(xCoordinates, k); + + Boolean cond1 = (kthElement >= aVariant) && ( + kthElement < bVariant); Boolean cond2 = (getIntervalSize(aVariant, bVariant, intervalIntersections) <= ((11 * N) / Math.sqrt(r))); return cond1 && cond2; } @@ -145,10 +146,12 @@ public class TheilSenEstimator extends Observable implements Algorithm { */ public ArrayList randomSampleOfIntersections(ArrayList set, Double r) { ArrayList sampledLines = new ArrayList<>(); + Random random = new Random(System.currentTimeMillis()); while (sampledLines.size() < r) { - Double x = set.get(ThreadLocalRandom.current().nextInt(0, set.size())).getX(); + Double x = set.get(random.nextInt(set.size())).getX(); sampledLines.add(x); + } return sampledLines; @@ -240,9 +243,9 @@ public class TheilSenEstimator extends Observable implements Algorithm { } else { m = resultSt.get(((size + 1) / 2) - 1).getX(); } - m *= -1; - b = (x * m) + y; + b = y - (x * m); + m *= -1; String[] result = new String[]{"ts", m + "", b + ""}; notifyObservers(result); diff --git a/src/main/java/Presenter/FastElementSelector.java b/src/main/java/Presenter/FastElementSelector.java new file mode 100644 index 0000000..d1d52f5 --- /dev/null +++ b/src/main/java/Presenter/FastElementSelector.java @@ -0,0 +1,89 @@ +package Presenter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Random; + +/** + * Created by armin on 29.06.17. + */ +public class FastElementSelector { + + /** + * + * @param a + * @param i + * @return + */ + public static Double randomizedSelect(ArrayList a, double i) { + int start = 0; + int end = a.size()-1; + + if (i >= end+1){ + return a.get(end); + } + + while(true){ + + if(start == end){ + return a.get(start); + } + int q = randomizedPartition(a, start, end); + int k = q-start+1; + + if(i == k){ + return a.get(q); + } + else{ + if(i a, int start, int end) { + int i = 0; + Random random = new Random(System.currentTimeMillis()); + + //alternative: ThreadLocalRandom.current() + if(start < end){ + i = start + random.nextInt(end-start); + }else{ + i = end + random.nextInt(start-end); + } + + Collections.swap(a, end, i); + return partition(a, start, end); + } + + /** + * + * @param a + * @param start + * @param end + * @return + */ + private static int partition(ArrayList a, int start, int end) { + Double x = a.get(end); + int i = start - 1; + for (int j = start; j <= end-1; j++) { + if (a.get(j) <= x) { + i++; + Collections.swap(a, i, j); + } + } + Collections.swap(a, i+1, end); + return i+1; + } +} diff --git a/src/main/java/Presenter/IntersectionCounter.java b/src/main/java/Presenter/IntersectionCounter.java index 97d2bc7..834fb2b 100644 --- a/src/main/java/Presenter/IntersectionCounter.java +++ b/src/main/java/Presenter/IntersectionCounter.java @@ -1,8 +1,6 @@ package Presenter; -import Model.Line; -import Model.Pair; -import Model.Interval; +import Model.*; import Presenter.Comparators.YOrderLineComparatorBegin; import Presenter.Comparators.YOrderLineComparatorEnd; import java.util.ArrayList; @@ -207,43 +205,41 @@ public class IntersectionCounter { linePairs.add(l2); ret.put(l1, linePairs); } + /*System.out.println("----------------------------------------------------------"); + for (Line outerLine : ret.keySet()){ + System.out.println("Linie: "+outerLine); + for (Line innerLine : ret.get(outerLine)){ + System.out.println("\t\t -> "+innerLine); + } + } + System.out.println("----------------------------------------------------------");*/ -// System.out.println("----------------------------------------------------------"); -// for (Line outerLine : ret.keySet()){ -// System.out.println("Linie: "+outerLine); -// for (Line innerLine : ret.get(outerLine)){ -// System.out.println("\t\t -> "+innerLine); -// } -// } -// System.out.println("----------------------------------------------------------"); return ret; } /** * Diese Methode liefert nur nach dem Ausführen der run Funktion Sinnvolle Werte. * - * @return x Koordinaten der Schnittpunkte + * */ - public HashMap calculateIntersectionAbscissas(){ + public void calculateIntersectionAbscissas(Arrangement model){ ArrayList result = new ArrayList<>(); - HashMap ret = new HashMap<>(); for (int i = 0; i < inversions.size(); i++) { result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()), dictionaryBACK.get(inversions.get(i).getP2()))); } - ArrayList linePairs; for (Pair p : result) { Line line = secondaryDictionaryBACK.get(p.getP1()); Line sampledLine = secondaryDictionaryBACK.get(p.getP2()); if (!line.equals(sampledLine)){ double intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); - ret.put(intersection, intersection); + double yintercept = sampledLine.getM() * intersection + sampledLine.getB(); + model.addNode(new Point(intersection, yintercept)); } } - return ret; } /** diff --git a/src/main/java/Presenter/Presenter.java b/src/main/java/Presenter/Presenter.java index 3b08043..658b945 100644 --- a/src/main/java/Presenter/Presenter.java +++ b/src/main/java/Presenter/Presenter.java @@ -1,6 +1,7 @@ package Presenter; import Model.Arrangement; +import Model.Interval; import Model.Line; import Model.Point; import Presenter.Algorithms.LeastMedianOfSquaresEstimator; @@ -200,21 +201,24 @@ public class Presenter implements Observer { public void calcArrangementNodes() { try { Thread thread = new Thread(() -> { - Double xMinimum = Double.MAX_VALUE; + /*Double xMinimum = Double.MAX_VALUE; Double xMaximum = Double.MIN_VALUE; Double yMinimum = Double.MAX_VALUE; Double yMaximum = Double.MIN_VALUE; + for (int i = 0; i < getLines().size(); i++) { for (int j = i; j < getLines().size(); j++) { if (i != j) { Point intersection = calcIntersection(getLines().get(j), getLines().get(i)); - model.addNode(intersection); + if (intersection.getX() != Double.POSITIVE_INFINITY && intersection.getX() != Double.NEGATIVE_INFINITY && intersection.getY() != Double.POSITIVE_INFINITY && intersection.getY() != Double.NEGATIVE_INFINITY ){ xMinimum = xMinimum > intersection.getX() ? intersection.getX() : xMinimum; xMaximum = xMaximum < intersection.getX() ? intersection.getX() : xMaximum; yMinimum = yMinimum > intersection.getY() ? intersection.getY() : yMinimum; yMaximum = yMaximum < intersection.getY() ? intersection.getY() : yMaximum; + + model.addNode(intersection); } } } @@ -222,7 +226,13 @@ public class Presenter implements Observer { model.setxMinimum(xMinimum); model.setxMaximum(xMaximum); model.setyMaximum(yMaximum); - model.setyMinimum(yMinimum); + model.setyMinimum(yMinimum);*/ + IntersectionCounter counter = new IntersectionCounter(); + counter.run(getLines(), new Interval(-99999,99999)); + counter.calculateIntersectionAbscissas(getModel()); + getModel().setXbounds(); + getModel().setYbounds(); + }); thread.start(); thread.join();