diff --git "a/docs/#IHK_Abschlusspr\303\274fung_Sven_Bergmann.lyx#" "b/docs/#IHK_Abschlusspr\303\274fung_Sven_Bergmann.lyx#" index 4ae3973..ef8c0fe 100644 --- "a/docs/#IHK_Abschlusspr\303\274fung_Sven_Bergmann.lyx#" +++ "b/docs/#IHK_Abschlusspr\303\274fung_Sven_Bergmann.lyx#" @@ -1316,6 +1316,20 @@ aten berechnet und falls dieser geringer ist, als der vorher gespeicherte Benutzeranleitung \end_layout +\begin_layout Standard +Generell befindet sich die Gesamtdokumentation der Klassen und Methoden + als javadoc im +\begin_inset Quotes gld +\end_inset + +docs +\begin_inset Quotes grd +\end_inset + + Ordner. + +\end_layout + \begin_layout Subsection Ordnerstruktur \end_layout @@ -1851,8 +1865,47 @@ input Beispiel 4: 2 Staaten zum Testen \end_layout -\begin_layout Subsubsection -Äquivalenzklassen +\begin_layout Standard +In diesem Beispiel habe ich zwei Staaten +\begin_inset Quotes gld +\end_inset + +1 +\begin_inset Quotes grd +\end_inset + + und +\begin_inset Quotes gld +\end_inset + +2 +\begin_inset Quotes grd +\end_inset + + zum Testen angelegt. + Normalerweise sollten sich die Kreise direkt nach der ersten Iteration + richtig ausgerichtet haben. + +\end_layout + +\begin_layout Standard +Das Beispiel ist in der Datei +\begin_inset Quotes gld +\end_inset + +beispiel4.txt +\begin_inset Quotes grd +\end_inset + + im Ordner +\begin_inset Quotes gld +\end_inset + +input +\begin_inset Quotes grd +\end_inset + + zu finden. \end_layout \begin_layout Subsection @@ -1864,7 +1917,7 @@ Kontrollflussgraphen \end_layout \begin_layout Section -Zusammenfassung und Ausblicks +Zusammenfassung und Ausblick \end_layout \begin_layout Standard @@ -2257,7 +2310,17 @@ Aktivitätsdiagramme \end_layout \begin_layout Section -Eigenständigkeitserklärung +Selbstständigkeitserklärung +\end_layout + +\begin_layout Standard +\begin_inset Graphics + filename Selbstständigkeitserklärung.pdf + width 100text% + +\end_inset + + \end_layout \end_body diff --git "a/docs/Selbstst\303\244ndigkeitserkl\303\244rung.pdf" "b/docs/Selbstst\303\244ndigkeitserkl\303\244rung.pdf" new file mode 100644 index 0000000..781f3db Binary files /dev/null and "b/docs/Selbstst\303\244ndigkeitserkl\303\244rung.pdf" differ diff --git a/docs/umls/Package algorithms.png b/docs/umls/Package algorithms.png index 6811e91..4c91775 100644 Binary files a/docs/umls/Package algorithms.png and b/docs/umls/Package algorithms.png differ diff --git a/docs/umls/Package models.png b/docs/umls/Package models.png index affc3db..e63a632 100644 Binary files a/docs/umls/Package models.png and b/docs/umls/Package models.png differ diff --git a/input/file3.txt b/input/beispiel5.txt similarity index 100% rename from input/file3.txt rename to input/beispiel5.txt diff --git a/input_saved/beispiel1.txt b/input_saved/beispiel1.txt new file mode 100644 index 0000000..9067296 --- /dev/null +++ b/input_saved/beispiel1.txt @@ -0,0 +1,21 @@ +Fläche der Staaten +# Staat Fläche Längengrad Breitengrad +D 357 10.0 51.3 +NL 42 5.3 52.2 +B 33 4.8 50.7 +L 3 6.1 49.8 +F 544 2.8 47.4 +CH 41 8.2 46.9 +A 84 14.2 47.6 +CZ 79 15.3 49.8 +PL 313 18.9 52.2 +DK 43 9.6 56.0 +# Nachbarschaften +D: NL B L F CH A CZ PL DK +NL: B +B: L F +L: F +F: CH +CH: A +A: CZ +CZ: PL \ No newline at end of file diff --git a/input_saved/beispiel2.txt b/input_saved/beispiel2.txt new file mode 100644 index 0000000..f55ba27 --- /dev/null +++ b/input_saved/beispiel2.txt @@ -0,0 +1,21 @@ +Bierkonsum +# Staat Bierkonsum Längengrad Breitengrad +D 8692 10.0 51.3 +NL 1156 5.3 52.2 +B 781 4.8 50.7 +L 80 6.1 49.8 +F 2077 2.8 47.4 +CH 440 8.2 46.9 +A 945 14.2 47.6 +CZ 1573 15.3 49.8 +PL 3724 18.9 52.2 +DK 360 9.6 56.0 +# Nachbarschaften +D: NL B L F CH A CZ PL DK +NL: B +B: L F +L: F +F: CH +CH: A +A: CZ +CZ: PL \ No newline at end of file diff --git a/input_saved/beispiel3.txt b/input_saved/beispiel3.txt new file mode 100644 index 0000000..3c9c34a --- /dev/null +++ b/input_saved/beispiel3.txt @@ -0,0 +1,50 @@ +Fläche der Staaten +# Staat Fläche Längengrad Breitengrad +D 357 10.0 51.3 +NL 42 5.3 52.2 +B 33 4.8 50.7 +L 3 6.1 49.8 +F 544 2.8 47.4 +CH 41 8.2 46.9 +A 84 14.2 47.6 +CZ 79 15.3 49.8 +PL 313 18.9 52.2 +DK 43 9.6 56.0 +E 506 -3.7 40.5 +P 92 -8.2 39.6 +I 301 11.7 43.2 +SLO 20 14.7 46.1 +SK 49 19.7 48.8 +H 93 19.2 47.1 +HR 57 16.0 45.2 +BIH 51 17.8 44.2 +SRB 88 20.8 44.1 +MNE 14 19.2 42.8 +MK 26 21.7 41.6 +AL 29 19.9 41.3 +RO 228 25.0 45.9 +BG 111 25.2 42.7 +GR 132 22.9 39.5 +# Nachbarschaften +D: NL B L F CH A CZ PL DK +NL: B +B: L F +L: F +F: CH E I +CH: A I +A: CZ SLO I SK H +CZ: PL SK +PL: SK +E: P +I: SLO +SLO: H HR +SK: H +H: HR SRB RO +HR: BIH SRB +BIH: SRB MNE +SRB: MNE MK RO BG AL +MNE: AL +MK: AL GR BG +AL: GR +RO: BG +BG: GR \ No newline at end of file diff --git a/input_saved/beispiel4.txt b/input_saved/beispiel4.txt new file mode 100644 index 0000000..e93ada0 --- /dev/null +++ b/input_saved/beispiel4.txt @@ -0,0 +1,6 @@ +Test +# Staat Bierkonsum Längengrad Breitengrad +1 200 6 5 +2 300 2 3 +# Nachbarschaften +1: 2 \ No newline at end of file diff --git a/input_saved/beispiel5.txt b/input_saved/beispiel5.txt new file mode 100644 index 0000000..c88cc11 --- /dev/null +++ b/input_saved/beispiel5.txt @@ -0,0 +1,8 @@ +Test +# Staat Bierkonsum Längengrad Breitengrad +1 200 6 5 +2 300 2 3 +3 50 4 7 +# Nachbarschaften +1: 2 3 +2: 3 \ No newline at end of file diff --git a/output/beispiel5.txt_out.txt b/output/beispiel5.txt_out.txt new file mode 100644 index 0000000..9a7faac --- /dev/null +++ b/output/beispiel5.txt_out.txt @@ -0,0 +1,15 @@ +reset +set xrange [1.8698310770064768:6.0379913583150095] +set yrange [4.830346104049601:7.166666666666667] +set size ratio 1.0 +set title "Test, Iterationen: 8" +unset xtics +unset ytics +$data << EOD +4.0 7.0 0.16666666666666666 3 0 +3.975561971127063 5.880610818217393 0.6666666666666666 1 1 +4.0379913583150095 5.830346104049601 1.0 2 2 +EOD +plot \ +'$data' using 1:2:3:5 with circles lc var notitle, \ +'$data' using 1:2:4:5 with labels font "arial,9" tc variable notitle \ No newline at end of file diff --git a/src/main/java/com/cae/de/models/Landkarte.java b/src/main/java/com/cae/de/models/Landkarte.java index e0de8f3..d4483ef 100644 --- a/src/main/java/com/cae/de/models/Landkarte.java +++ b/src/main/java/com/cae/de/models/Landkarte.java @@ -93,7 +93,8 @@ public static HashMap> deepCopyBeziehungen( * Diese Methode berechnet den Abstand aller Nachbarstaaten, also aller Staaten, bei denen der * direkte Nachbar angegeben wurde. Eventuelle andere Beziehungen werden nicht beachtet. Für die * Abstandsberechnung wird die Methode {@link Kreis#getAbstandZwischenKreisen(Kreis)} genutzt, - * wobei der Absolutwert des Ergebnisses daraus genommen wird. + * wobei zu dem Ergebnis 1 addiert wird, falls die Kreise sich schneiden, sodass eine + * Überschneidung als größtmöglicher Wert gewertet wird. * * @return den Abstand der zwischen allen benachbarten Staaten */ @@ -105,10 +106,12 @@ public double getAbstandZwischenNachbarStaaten() { var k1 = new Kreis(s1.getX(), s1.getY(), s1.getKenngroesse()); return staatHashSetEntry.getValue().stream() .map( - s2 -> - Math.abs( - new Kreis(s2.getX(), s2.getY(), s2.getKenngroesse()) - .getAbstandZwischenKreisen(k1))) + s2 -> { + var abstand = + new Kreis(s2.getX(), s2.getY(), s2.getKenngroesse()) + .getAbstandZwischenKreisen(k1); + return abstand > 0 ? abstand : 1; + }) .mapToDouble(Double::doubleValue) .sum(); }) diff --git a/src/main/java/com/cae/de/utils/algorithms/BruteForceStrategy.java b/src/main/java/com/cae/de/utils/algorithms/BruteForceStrategy.java index 17511c4..985bdea 100644 --- a/src/main/java/com/cae/de/utils/algorithms/BruteForceStrategy.java +++ b/src/main/java/com/cae/de/utils/algorithms/BruteForceStrategy.java @@ -6,6 +6,8 @@ import com.cae.de.utils.la.Punkt; import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -28,7 +30,6 @@ public class BruteForceStrategy implements IStrategy { * @param landkarte die gegebene Landkarte */ private static void iteriere(Landkarte landkarte) { - var epsilon = 1e-10; // Abstoßungskräfte der Staaten bestimmen, bei denen die Kreise überlappen landkarte @@ -80,39 +81,47 @@ private static void iteriere(Landkarte landkarte) { .getStaatenNachKenngroesseSortiert() .forEach( staat -> - landkarte.getKreafte().get(staat).entrySet().stream() - .filter(n -> n.getValue() > epsilon || n.getValue() < -epsilon) + landkarte + .getKreafte() + .get(staat) .forEach( - n -> { + (nachbarstaat, kraft) -> { var m1 = new Punkt(staat.getX(), staat.getY()); - var nachbarstaat = n.getKey(); var m2 = new Punkt(nachbarstaat.getX(), nachbarstaat.getY()); var m1new = - (n.getValue() > 0) - ? m1.verschiebeInRichtung(m2, n.getValue() / 2) - : m1.verschiebeInGegenrichtung(m2, -n.getValue() / 2); + kraft > 0 + ? m1.verschiebeInRichtung(m2, kraft / 2) + : m1.verschiebeInRichtung(m2, -kraft / 2); verschiebungen.get(staat.getIdentifier()).add(m1new); })); // Setze für jeden Staat einen neuen Mittelpunkt, basieren auf den vorher ausgerechneten - // Punkten, wobei der Staat mit den meisten Nachbarn nicht beachtet wird + // Punkten, wobei der Staat mit den meisten Nachbarn nicht beachtet wird und der Staat nicht + // verschoben wird, wenn der neue Mittelpunkt in irgendeinem anderen Kreis liegt. landkarte.getStaatenNachKenngroesseSortiert().stream() - .filter( - staat -> - !staat - .getIdentifier() - .equals(landkarte.getStaatMitMeistenNachbarn().getIdentifier())) + .filter(staat -> !staat.equals(landkarte.getStaatMitMeistenNachbarn())) .forEach( staat -> { - var p = Punkt.getMittelpunkt(verschiebungen.get(staat.getIdentifier())); LOGGER.log( Level.INFO, - "Verschiebe: " - + staat.getIdentifier() - + " von " - + new Punkt(staat.getX(), staat.getY()) - + " nach " - + p); + getKreiseAllerAnderenStaaten(staat, landkarte.getStaatenNachKenngroesseSortiert()) + .toString()); + var p = Punkt.getMittelpunkt(verschiebungen.get(staat.getIdentifier())); + if (getKreiseAllerAnderenStaaten(staat, landkarte.getStaatenNachKenngroesseSortiert()) + .stream() + .noneMatch( + kreis -> + kreis.getAbstandZwischenKreisen( + new Kreis(p.x(), p.y(), staat.getKenngroesse())) + < 0)) + LOGGER.log( + Level.INFO, + "Verschiebe: " + + staat.getIdentifier() + + " von " + + new Punkt(staat.getX(), staat.getY()) + + " nach " + + p); staat.setX(p.x()); staat.setY(p.y()); }); @@ -120,6 +129,20 @@ private static void iteriere(Landkarte landkarte) { landkarte.removeKraefte(); } + /** + * Berechnet die Kreise aller anderen Staaten außer dem des gegebenen Staats. + * + * @param staat der Staat, von dem der Kreis nicht berechnet werden soll + * @param staaten alle Staaten + * @return ein Set der Kreise aller anderen Staaten + */ + private static Set getKreiseAllerAnderenStaaten(Staat staat, List staaten) { + return staaten.stream() + .filter(staat1 -> !staat1.equals(staat)) + .map(staat1 -> new Kreis(staat1.getX(), staat1.getY(), staat1.getKenngroesse())) + .collect(Collectors.toSet()); + } + /** * Der Algorithmus der {@link BruteForceStrategy} berechnet zuerst den Abstand zwischen allen * Nachbarn und speichert dazu die aktuellen Beziehungen inklusive der Staaten. Dann folgt eine @@ -134,11 +157,11 @@ private static void iteriere(Landkarte landkarte) { */ @Override public void rechne(Landkarte landkarte, int maxIterationen) { - var i = 0; - var minimumIterationen = 0; + var i = 1; + var minimumIterationen = i; var beziehungenMitKleinstemAbstand = Landkarte.deepCopyBeziehungen(landkarte.getBeziehungen()); var abstandZwischenAllenNachbarn = landkarte.getAbstandZwischenNachbarStaaten(); - while (i < maxIterationen) { + while (i <= maxIterationen) { iteriere(landkarte); var neuerAbstand = landkarte.getAbstandZwischenNachbarStaaten(); if (abstandZwischenAllenNachbarn > neuerAbstand) { diff --git a/src/main/java/com/cae/de/utils/la/Kreis.java b/src/main/java/com/cae/de/utils/la/Kreis.java index 440db7a..ebfdb9f 100644 --- a/src/main/java/com/cae/de/utils/la/Kreis.java +++ b/src/main/java/com/cae/de/utils/la/Kreis.java @@ -15,18 +15,16 @@ public record Kreis(double x, double y, double r) { * andernfalls ist der Abstand negativ und repräsentiert die Strecke der größten Überschneidung. */ public double getAbstandZwischenKreisen(Kreis k) { - var dM1M2 = Math.sqrt((k.x - this.x) * (k.x - this.x) + (k.y - this.y) * (k.y - this.y)); - if (dM1M2 < (k.r + this.r)) return -dM1M2; - return dM1M2 - (this.r + k.r); + return new Punkt(k.x, k.y).getAbstand(new Punkt(this.x, this.y)) - (this.r + k.r); } /** - * Berechnet ob der gegebene Punkt innerhalb des Kreises liegt. + * Berechnet, ob der gegebene Punkt innerhalb des Kreises liegt. * @param p der Punkt * @return true wenn er innerhalb liegt, andernfalls false */ public boolean isInnerhalb(Punkt p) { - return p.getAbstand(new Punkt(this.x, this.y)) <= this.r; + return p.getAbstand(new Punkt(this.x, this.y)) < this.r; } } diff --git a/src/main/java/com/cae/de/utils/la/Punkt.java b/src/main/java/com/cae/de/utils/la/Punkt.java index c163be3..648ff14 100644 --- a/src/main/java/com/cae/de/utils/la/Punkt.java +++ b/src/main/java/com/cae/de/utils/la/Punkt.java @@ -38,20 +38,6 @@ public Punkt verschiebeInRichtung(Punkt p, double wert) { ); } - /** - * Verschiebt den Punkt in die Gegenrichtung des gegebenen Punktes um den Wert. - * @param p der Punkt gegen welche Richtung der andere Punkt verschoben werden soll - * @param wert der Wert, um den der Punkt verschoben werden soll - * @return den aus der Verschiebung resultierenden Punkt - */ - public Punkt verschiebeInGegenrichtung(Punkt p, double wert) { - return this.subtrahiere( - new Punkt(p.x - this.x, p.y - this.y) - .normalisiere() - .multipliziereMitSkalar(wert) - ); - } - /** * Berechnet den euklidischen Abstand beider Punkte. * @param p der andere Punkt