142 lines
4.2 KiB
Java
142 lines
4.2 KiB
Java
package presenter.algorithms.naiv;
|
|
|
|
import model.Line;
|
|
import model.Point;
|
|
import presenter.algorithms.Algorithm;
|
|
import presenter.util.FastElementSelector;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
|
|
/**
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
*
|
|
* @Author: Armin Wolf
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
* @Date: 15.09.2017.
|
|
*/
|
|
public class NaivRepeatedMedianEstimator implements Algorithm {
|
|
|
|
private LinkedList<Line> lines;
|
|
private HashMap<String, ArrayList<Double>> slopesPerLine;
|
|
private HashMap<String, ArrayList<Double>> interceptPerLine;
|
|
private ArrayList<Double> xMedians, yMedians;
|
|
private Double medianX;
|
|
private Double medianY;
|
|
|
|
/**
|
|
* Konstruktor
|
|
* @param lines Liste der Geraden
|
|
*/
|
|
public NaivRepeatedMedianEstimator(LinkedList<Line> lines) {
|
|
this.lines = lines;
|
|
slopesPerLine = new HashMap<>();
|
|
interceptPerLine = new HashMap<>();
|
|
xMedians = new ArrayList<>();
|
|
yMedians = new ArrayList<>();
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
//init the List for the slopes
|
|
System.out.println("=== S T A R T - naiv R M ===");
|
|
long start;
|
|
long end;
|
|
start = System.currentTimeMillis();
|
|
for (int j = 0; j < lines.size(); j++) {
|
|
Line leq = lines.get(j);
|
|
if (slopesPerLine.get(leq.getId()) == null) {
|
|
slopesPerLine.put(leq.getId(), new ArrayList<>());
|
|
}
|
|
if (interceptPerLine.get(leq.getId()) == null) {
|
|
interceptPerLine.put(leq.getId(), new ArrayList<>());
|
|
}
|
|
}
|
|
|
|
//calculate all slopes for each line
|
|
Point ret;
|
|
for (int i = 0; i < lines.size(); i++) {
|
|
for (int j = i + 1; j < lines.size(); j++) {
|
|
ret = calculateLine(lines.get(i), lines.get(j));
|
|
slopesPerLine.get(lines.get(i).getId()).add(ret.getX());
|
|
interceptPerLine.get(lines.get(i).getId()).add(ret.getY());
|
|
}
|
|
}
|
|
|
|
//berechne mediane Steigung
|
|
for (String l : slopesPerLine.keySet()) {
|
|
ArrayList<Double> list = slopesPerLine.get(l);
|
|
int size = list.size() / 2;
|
|
if (size > 0) {
|
|
Double medianX = FastElementSelector.randomizedSelect(list, size);
|
|
xMedians.add(medianX);
|
|
}
|
|
}
|
|
|
|
//berechne medianen y-Achsenabschnitt
|
|
for (String l : interceptPerLine.keySet()) {
|
|
ArrayList<Double> list = interceptPerLine.get(l);
|
|
int size = list.size() / 2;
|
|
if (size > 0) {
|
|
Double medianY = FastElementSelector.randomizedSelect(list, size);
|
|
yMedians.add(medianY);
|
|
}
|
|
}
|
|
|
|
medianX = FastElementSelector.randomizedSelect(xMedians, xMedians.size() / 2);
|
|
medianY = FastElementSelector.randomizedSelect(yMedians, yMedians.size() / 2);
|
|
end = System.currentTimeMillis();
|
|
System.out.println("Zeit: "+ ((end-start)/1000));
|
|
}
|
|
|
|
@Override
|
|
public void pepareResult() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Berechnet die Geraden zwischen zwei Punkten im dualen Raum.
|
|
* @param startPoint Gerade 1 => Startpunkt mit den Koordianten (m,b)
|
|
* @param endPoint Gerade 2 => Endpunkt mit den Koordianten (m', b')
|
|
* @return
|
|
*/
|
|
private Point calculateLine(Line startPoint, Line endPoint) {
|
|
Double xi;
|
|
Double xj;
|
|
Double yi;
|
|
Double yj;
|
|
|
|
if (endPoint.getM() > startPoint.getM()) {
|
|
xi = startPoint.getM();
|
|
yi = startPoint.getB();
|
|
xj = endPoint.getM();
|
|
yj = endPoint.getB();
|
|
} else {
|
|
xj = startPoint.getM();
|
|
yj = startPoint.getB();
|
|
xi = endPoint.getM();
|
|
yi = endPoint.getB();
|
|
}
|
|
|
|
|
|
Double m = (yj - yi) / (xj - xi);
|
|
Double b = ((xj * yi) - (xi * yj)) / (xj - xi);
|
|
return new Point(m, b);
|
|
}
|
|
|
|
/**
|
|
* @return Steigung
|
|
*/
|
|
public Double getM() {
|
|
return medianX * -1;
|
|
}
|
|
|
|
/**
|
|
* @return y-Achsenabschnitt
|
|
*/
|
|
public Double getB() {
|
|
return medianY * -1;
|
|
}
|
|
}
|