From bb34b3705acb98292e8518ca8ca03a18f1527754 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Wed, 21 Jun 2017 14:41:37 +0200 Subject: [PATCH] =?UTF-8?q?erste=20L=C3=B6sung=20RM=20Estimator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Algorithms/RepeatedMedianEstimator.java | 284 ++++++++++++------ 1 file changed, 184 insertions(+), 100 deletions(-) diff --git a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java index a7ca993..420d43e 100644 --- a/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java +++ b/src/main/java/Presenter/Algorithms/RepeatedMedianEstimator.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; -import java.util.Random; import java.util.concurrent.ThreadLocalRandom; /** @@ -21,6 +20,8 @@ public class RepeatedMedianEstimator implements Algorithm { private LinkedList set; private HashMap> linePairs; + private HashMap medianIntersections = new HashMap<>(); + private HashMap> intersectionAbscissas = new HashMap<>(); private Slab interval; //in der Literatur als L_i, C_i, und R_i bekannt @@ -57,71 +58,138 @@ public class RepeatedMedianEstimator implements Algorithm { countLeftSlab.add(0); countRightSlab.add(0); countCenterSlab.add(n - 1); + intersectionAbscissas.put(set.get(i), new ArrayList<>()); } linesInLeftSlab = new ArrayList<>(); linesInCenterSlab = new ArrayList<>(set); linesInRightSlab = new ArrayList<>(); - linePairs = new HashMap<>(); + linePairs = new HashMap<>(); } - + /** + * + */ public void run() { while (linesInCenterSlab.size() != 1) { - r = Math.floor(Math.pow(n, beta)); + r = Math.ceil(Math.pow(n, beta)); ArrayList lines = sampleLines(linesInCenterSlab, r); InversionCounter invCounter = new InversionCounter(); - invCounter.run(lines, interval); + //int intersectionCount = invCounter.run(lines, interval); - HashMap> tmpMap; - tmpMap = invCounter.getIntersectionAbscissas(); - linePairs.putAll(tmpMap); - if (tmpMap.size() > 0){ - ArrayList medianIntersections = new ArrayList<>(); - for (Line l : lines) { - medianIntersections.add(estimateMedianIntersectionAbscissas(l)); - } - - k = (Math.floor(n * 0.5) - linesInLeftSlab.size()); - computeSlabBorders(); - thetaLow = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kLow); - thetaHigh = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kHigh); - - for (Line l : linesInCenterSlab) { - countNumberOfIntersectionsAbscissas(l); - } - - contractIntervals(); + //For each Sampled Line, compute its median intersection abscissa + ArrayList medianIntersectionAbscissas = new ArrayList<>(); + for (Line l : lines) { + Double abscissa = estimateMedianIntersectionAbscissas(l); + medianIntersections.put(l, abscissa); + medianIntersectionAbscissas.add(abscissa); } + + //rank of the repeated median in C + k = (Math.floor(n * 0.5) - linesInLeftSlab.size()); + + //compute k_lo and k_hi + computeSlabBorders(); + + //Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi + thetaLow = randomizedSelect(medianIntersectionAbscissas, 0, + medianIntersectionAbscissas.size() - 1, kLow); + thetaHigh = randomizedSelect(medianIntersectionAbscissas, 0, + medianIntersectionAbscissas.size() - 1, kHigh); + + //For each dual Line in C count the number of intersection abscissas that lie + //in each of the intervals. + countNumberOfIntersectionsAbscissas(); + + //Based on this 3 counts, determine which of the subintervals contains the repeated median + //and contract to this subiinterval. + contractIntervals(); + } System.out.println( - "Ergebnis: " + linesInCenterSlab.get(0).getM() + " * x + " + linesInCenterSlab.get(0) - .getB()); - } - - - public void computeSlabBorders() { - kLow = Math - .max(1, Math.ceil(((r * k) / (linesInCenterSlab.size())) - ((3 * Math.sqrt(r)) / (2)))); - kHigh = Math - .min(r, Math.ceil(((r * k) / (linesInCenterSlab.size())) + ((3 * Math.sqrt(r)) / (2)))); + "Ergebnis: " + thetaLow * (-1) + " * x + " + ( + (linesInCenterSlab.get(0).getM() * (thetaLow * (-1))) + linesInCenterSlab.get(0) + .getB())); } + /** + * + * @param set + * @param r + * @return + */ public ArrayList sampleLines(ArrayList set, Double r) { ArrayList sampledLines = new ArrayList<>(); for (int i = 0; i < r; i++) { - sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, n))); + sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, linesInCenterSlab.size()))); } return sampledLines; } + /** + * + * @param sampledLine + * @return + */ + public Double estimateMedianIntersectionAbscissas(Line sampledLine) { + Integer index = Integer.parseInt(sampledLine.getId()); + ArrayList intersections = new ArrayList<>(); + double intersection; + + for (Line line : linesInCenterSlab) { + if (line != sampledLine) { + intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); + + if (!intersectionAbscissas.get(line).contains(intersection)) + intersectionAbscissas.get(line).add(intersection); + if (!intersectionAbscissas.get(sampledLine).contains(intersection)) + intersectionAbscissas.get(sampledLine).add(intersection); + + intersections.add(intersection); + } + } + + Collections.sort(intersections); + double ki = Math.ceil((n - 1) / 2) - countLeftSlab.get(index); + double i = (Math.ceil((Math.sqrt(n) * ki) / countCenterSlab.get(index))); + int accessIndex; + if (i < 0) + accessIndex = 0; + else if (i >= intersections.size()) + accessIndex = intersections.size()-1; + else + accessIndex = (int) i; + + System.out.println(accessIndex); + + return intersections.get(accessIndex); + } + + /** + * + */ + public void computeSlabBorders() { + kLow = Math + .max(1, Math.floor(((r * k) / (linesInCenterSlab.size())) - ((3 * Math.sqrt(r)) / (2)))); + kHigh = Math + .min(r, Math.floor(((r * k) / (linesInCenterSlab.size())) + ((3 * Math.sqrt(r)) / (2)))); + } + + /** + * + * @param a + * @param start + * @param end + * @param i + * @return + */ public Double randomizedSelect(ArrayList a, int start, int end, double i) { if (start == end) { return a.get(start); @@ -138,6 +206,13 @@ public class RepeatedMedianEstimator implements Algorithm { } } + /** + * + * @param a + * @param start + * @param end + * @return + */ public int randomizedPartition(ArrayList a, int start, int end) { int delta = Math.abs(end - start); int i = start + ThreadLocalRandom.current().nextInt(0, delta); @@ -145,6 +220,13 @@ public class RepeatedMedianEstimator implements Algorithm { 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; @@ -158,84 +240,86 @@ public class RepeatedMedianEstimator implements Algorithm { return i + 1; } + /** + * + */ + public void countNumberOfIntersectionsAbscissas() { - public void countNumberOfIntersectionsAbscissas(Line sampledLine) { + for (Line line : linesInCenterSlab) { + ArrayList intersections = intersectionAbscissas.get(line); + Integer index = Integer.parseInt(line.getId()); + int left = 0; + int center = 0; + int right = 0; - if (linePairs.get(sampledLine) != null){ - double intersection; - Integer index = Integer.parseInt(sampledLine.getId()); - - for (Line line : linePairs.get(sampledLine)) { - intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); - - int tmpVal; + for (Double intersection : intersections) { if (intersection <= thetaLow) { - tmpVal = countLeftSlab.get(index) + 1; - countLeftSlab.set(index, tmpVal); - tmpVal = countCenterSlab.get(index) - 1; - countCenterSlab.set(index, tmpVal); - } else if (intersection > thetaHigh) { - tmpVal = countRightSlab.get(index) + 1; - countRightSlab.set(index, tmpVal); - tmpVal = countCenterSlab.get(index) - 1; - countCenterSlab.set(index, tmpVal); + left++; + } else if (intersection > thetaLow && intersection <= thetaHigh) { + center++; + } else if (intersection > thetaHigh){ + right++; } - - countCenterSlab - .set(index, Math.abs((n - 1) - (countLeftSlab.get(index) + countRightSlab.get(index)))); } + + System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right); + countLeftSlab.set(index, left); + countCenterSlab.set(index, center); + countRightSlab.set(index, right); } + } - - public Double estimateMedianIntersectionAbscissas(Line sampledLine) { - - Integer index = Integer.parseInt(sampledLine.getId()); - ArrayList intersections = new ArrayList<>(); - double intersection; - - for (Line line : linePairs.get(sampledLine)) { - if (line != sampledLine){ - intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM()); - intersections.add(intersection); - } - } - - Collections.sort(intersections); - double ki = Math.floor((n - 1) / 2) - countLeftSlab.get(index); - int accessIndex = ((int) Math.floor((Math.sqrt(n) * ki) / countCenterSlab.get(index)))-1; - System.out.println(accessIndex); - - return intersections.get(accessIndex); - } - - + /** + * + */ public void contractIntervals() { - if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size() - + linesInCenterSlab.size())) { - for (int i = 0; i < linesInCenterSlab.size(); i++) { - int maxVal = Math - .max(countLeftSlab.get(i), Math.max(countCenterSlab.get(i), countRightSlab.get(i))); - if (countLeftSlab.get(i) == maxVal) { - linesInLeftSlab.add(linesInCenterSlab.get(i)); - linesInCenterSlab.remove(i); - } + //if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size() + // + linesInCenterSlab.size())) { + for (int i = 0; i < linesInCenterSlab.size(); i++) { - if (countRightSlab.get(i) == maxVal) { - linesInRightSlab.add(linesInCenterSlab.get(i)); - linesInCenterSlab.remove(i); - } + int left = countLeftSlab.get(i); + int center = countCenterSlab.get(i); + int right = countRightSlab.get(i); + + int max = Math.max(left, Math.max(center, right)); + + if (left == max){ + linesInLeftSlab.add(linesInCenterSlab.get(i)); + linesInCenterSlab.remove(i); + } else if (right == max) { + linesInRightSlab.add(linesInCenterSlab.get(i)); + linesInCenterSlab.remove(i); + } + // if (medianIntersections.get(linesInCenterSlab.get(i)) != null) { + // if (medianIntersections.get(linesInCenterSlab.get(i)) <= thetaLow) { + // linesInLeftSlab.add(linesInCenterSlab.get(i)); + // linesInCenterSlab.remove(i); + // countLeftSlab.set(i, countLeftSlab.get(i) + 1); + // countCenterSlab.set(i, countCenterSlab.get(i) - 1); + // } else if (medianIntersections.get(linesInCenterSlab.get(i)) > thetaHigh) { + // linesInRightSlab.add(linesInCenterSlab.get(i)); + // linesInCenterSlab.remove(i); + // countRightSlab.set(i, countRightSlab.get(i) + 1); + // countCenterSlab.set(i, countCenterSlab.get(i) - 1); + // } + // } + // } + // } - for (int i = 0; i < n; i++) { - countLeftSlab.set(i,0); - countRightSlab.set(i,0); - countCenterSlab.set(i,n - 1); - } - - interval.setLower(thetaLow - 0.01); + //wähle C als C + if (linesInLeftSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= linesInLeftSlab.size()+linesInCenterSlab.size()){ + interval.setLower(thetaLow + 0.1); interval.setUpper(thetaHigh); - + } + // wähle L als C + else if (Math.ceil(n/2) <= linesInLeftSlab.size()){ + interval.setUpper(thetaLow); + } + //wähle R als C + else if (linesInLeftSlab.size()+linesInCenterSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= (linesInLeftSlab.size()+linesInCenterSlab.size()+linesInRightSlab.size()) ){ + interval.setLower(thetaHigh - 0.1); } } }