erste Lösung RM Estimator

This commit is contained in:
Armin Wolf 2017-06-21 14:41:37 +02:00
parent 6b99966b5e
commit bb34b3705a
1 changed files with 184 additions and 100 deletions

View File

@ -7,7 +7,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
/** /**
@ -21,6 +20,8 @@ public class RepeatedMedianEstimator implements Algorithm {
private LinkedList<Line> set; private LinkedList<Line> set;
private HashMap<Line, ArrayList<Line>> linePairs; private HashMap<Line, ArrayList<Line>> linePairs;
private HashMap<Line, Double> medianIntersections = new HashMap<>();
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
private Slab interval; private Slab interval;
//in der Literatur als L_i, C_i, und R_i bekannt //in der Literatur als L_i, C_i, und R_i bekannt
@ -57,71 +58,138 @@ public class RepeatedMedianEstimator implements Algorithm {
countLeftSlab.add(0); countLeftSlab.add(0);
countRightSlab.add(0); countRightSlab.add(0);
countCenterSlab.add(n - 1); countCenterSlab.add(n - 1);
intersectionAbscissas.put(set.get(i), new ArrayList<>());
} }
linesInLeftSlab = new ArrayList<>(); linesInLeftSlab = new ArrayList<>();
linesInCenterSlab = new ArrayList<>(set); linesInCenterSlab = new ArrayList<>(set);
linesInRightSlab = new ArrayList<>(); linesInRightSlab = new ArrayList<>();
linePairs = new HashMap<>(); linePairs = new HashMap<>();
} }
/**
*
*/
public void run() { public void run() {
while (linesInCenterSlab.size() != 1) { while (linesInCenterSlab.size() != 1) {
r = Math.floor(Math.pow(n, beta)); r = Math.ceil(Math.pow(n, beta));
ArrayList<Line> lines = sampleLines(linesInCenterSlab, r); ArrayList<Line> lines = sampleLines(linesInCenterSlab, r);
InversionCounter invCounter = new InversionCounter(); InversionCounter invCounter = new InversionCounter();
invCounter.run(lines, interval); //int intersectionCount = invCounter.run(lines, interval);
HashMap<Line, ArrayList<Line>> tmpMap; //For each Sampled Line, compute its median intersection abscissa
tmpMap = invCounter.getIntersectionAbscissas(); ArrayList<Double> medianIntersectionAbscissas = new ArrayList<>();
linePairs.putAll(tmpMap); for (Line l : lines) {
if (tmpMap.size() > 0){ Double abscissa = estimateMedianIntersectionAbscissas(l);
ArrayList<Double> medianIntersections = new ArrayList<>(); medianIntersections.put(l, abscissa);
for (Line l : lines) { medianIntersectionAbscissas.add(abscissa);
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();
} }
//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( System.out.println(
"Ergebnis: " + linesInCenterSlab.get(0).getM() + " * x + " + linesInCenterSlab.get(0) "Ergebnis: " + thetaLow * (-1) + " * x + " + (
.getB()); (linesInCenterSlab.get(0).getM() * (thetaLow * (-1))) + 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))));
} }
/**
*
* @param set
* @param r
* @return
*/
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) { public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) {
ArrayList<Line> sampledLines = new ArrayList<>(); ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) { 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; return sampledLines;
} }
/**
*
* @param sampledLine
* @return
*/
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
Integer index = Integer.parseInt(sampledLine.getId());
ArrayList<Double> 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<Double> a, int start, int end, double i) { public Double randomizedSelect(ArrayList<Double> a, int start, int end, double i) {
if (start == end) { if (start == end) {
return a.get(start); return a.get(start);
@ -138,6 +206,13 @@ public class RepeatedMedianEstimator implements Algorithm {
} }
} }
/**
*
* @param a
* @param start
* @param end
* @return
*/
public int randomizedPartition(ArrayList<Double> a, int start, int end) { public int randomizedPartition(ArrayList<Double> a, int start, int end) {
int delta = Math.abs(end - start); int delta = Math.abs(end - start);
int i = start + ThreadLocalRandom.current().nextInt(0, delta); int i = start + ThreadLocalRandom.current().nextInt(0, delta);
@ -145,6 +220,13 @@ public class RepeatedMedianEstimator implements Algorithm {
return partition(a, start, end); return partition(a, start, end);
} }
/**
*
* @param a
* @param start
* @param end
* @return
*/
public int partition(ArrayList<Double> a, int start, int end) { public int partition(ArrayList<Double> a, int start, int end) {
Double x = a.get(end); Double x = a.get(end);
int i = start - 1; int i = start - 1;
@ -158,84 +240,86 @@ public class RepeatedMedianEstimator implements Algorithm {
return i + 1; return i + 1;
} }
/**
*
*/
public void countNumberOfIntersectionsAbscissas() {
public void countNumberOfIntersectionsAbscissas(Line sampledLine) { for (Line line : linesInCenterSlab) {
ArrayList<Double> intersections = intersectionAbscissas.get(line);
Integer index = Integer.parseInt(line.getId());
int left = 0;
int center = 0;
int right = 0;
if (linePairs.get(sampledLine) != null){ for (Double intersection : intersections) {
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;
if (intersection <= thetaLow) { if (intersection <= thetaLow) {
tmpVal = countLeftSlab.get(index) + 1; left++;
countLeftSlab.set(index, tmpVal); } else if (intersection > thetaLow && intersection <= thetaHigh) {
tmpVal = countCenterSlab.get(index) - 1; center++;
countCenterSlab.set(index, tmpVal); } else if (intersection > thetaHigh){
} else if (intersection > thetaHigh) { right++;
tmpVal = countRightSlab.get(index) + 1;
countRightSlab.set(index, tmpVal);
tmpVal = countCenterSlab.get(index) - 1;
countCenterSlab.set(index, tmpVal);
} }
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<Double> 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() { public void contractIntervals() {
if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size() //if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size()
+ linesInCenterSlab.size())) { // + linesInCenterSlab.size())) {
for (int i = 0; i < linesInCenterSlab.size(); i++) { 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 (countRightSlab.get(i) == maxVal) { int left = countLeftSlab.get(i);
linesInRightSlab.add(linesInCenterSlab.get(i)); int center = countCenterSlab.get(i);
linesInCenterSlab.remove(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++) { //wähle C als C
countLeftSlab.set(i,0); if (linesInLeftSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= linesInLeftSlab.size()+linesInCenterSlab.size()){
countRightSlab.set(i,0); interval.setLower(thetaLow + 0.1);
countCenterSlab.set(i,n - 1);
}
interval.setLower(thetaLow - 0.01);
interval.setUpper(thetaHigh); 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);
} }
} }
} }