package de.wwwu.awolf.presenter.generator; import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.communication.Data; import de.wwwu.awolf.model.communication.GeneratorData; import de.wwwu.awolf.model.communication.SubscriberType; import de.wwwu.awolf.presenter.Presenter; import java.security.SecureRandom; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.Flow; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * * @Author: Armin Wolf * @Email: a_wolf28@uni-muenster.de * @Date: 01.08.2017. */ public class DatasetGenerator implements Flow.Publisher { private Double m; private Double b; private SecureRandom random; private Flow.Subscriber subscriber; /** * Konstruktor */ public DatasetGenerator(Presenter presenter) { random = new SecureRandom(); this.subscribe(presenter); } /** * Konstruktor */ public DatasetGenerator() { random = new SecureRandom(); } /** * Generiert zu einer gegebenen Größe einen Datensatz des typen: Punktwolke * * @param size Größe des Datensatzes * @return Liste der Geraden */ public LinkedList generateDataCloud(int size) { LinkedList lines = new LinkedList<>(); m = 1 + random.nextDouble(); b = random.nextDouble(); for (int i = 1; i < (size + 1); i++) { double y = (random.nextGaussian() * 100) % 100; double signal = m * i + b; signal *= -1; Line line = new Line(i, signal - y); line.setId(i - 1 + ""); lines.add(line); } communicate("Es wurden " + size + " Daten generiert mit den Parametern", m, b); return lines; } /** * Wrapper Methode zum generieren eines Datensatzes des typen: Gerade * * @param size Größe des Datensatzes * @return Liste des Geraden */ public List generateDataLines(int size) { List lines = new LinkedList<>(); return generateDataLines(lines, size); } /** * Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine * übergebene Liste hinzugefügt. * * @param lines Liste der Geraden * @param n Größe des Datensatzes * @return Liste des Geraden */ private List generateDataLines(List lines, int n) { m = 5d; b = 0d; int size = 0; Map points = new HashMap<>(); //speichere die Koordinaten in einer HashMap, damit keine Punkte //entstehen deren x-Koordinate zu sehr beieinander liegt. while (size < n) { double y = random.nextGaussian(); double signal = m * y + b; signal *= -1; if (!points.containsKey(y)) { points.put(y, signal); size++; } } int idx = lines.size(); for (Double d : points.keySet()) { Line line = new Line(d, points.get(d)); line.setId(idx + ""); lines.add(line); idx++; } communicate("Es wurden " + n + " Daten generiert mit den Parametern", m, b); return lines; } /** * Generiert einen Datensatz des typen: Gerade mit zirkulärer Störung. Zuerst wird die * zirkuläre Störung zu der Liste der (dualen-)Geraden hinzugefügt danach wird die wrapper Methode * generateDataLines() aufgerufen. * * @param size Größe des Datensatzes * @return Liste der Geraden */ public List generateCircle(int size) { List lines = new LinkedList<>(); double from = 0; double to = Math.PI * 5; //obere Grenze für die neuen Punkte int n = size / 2 + lines.size(); //calculate the distance between every two points double distance = (to - from) / ((double) n); //create points double currentDistance = from; //an die aktuelle Liste dranhängen for (int i = lines.size(); i < n; i++) { double x = Math.cos(currentDistance); double y = Math.sin(currentDistance); Line line = new Line(x, y); line.setId(i + ""); lines.add(line); //distance for the next iteration currentDistance += distance; } return generateDataLines(lines, size / 2); } @Override public void subscribe(Flow.Subscriber subscriber) { } private void communicate(final String message, final double m, final double b) { if (this.subscriber != null) { GeneratorData data = new GeneratorData(); data.setType(SubscriberType.GENERATOR); data.setMessage(message); data.setM(m); data.setB(b); this.subscriber.onNext(data); } } }