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 lines; private HashMap> slopesPerLine; private HashMap> interceptPerLine; private ArrayList xMedians, yMedians; private double medianX; private double medianY; /** * Konstruktor * @param lines Liste der Geraden */ public NaivRepeatedMedianEstimator(LinkedList 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 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 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; } }