Commit 2c62c656 authored by Falko Schumann's avatar Falko Schumann
Browse files

Defuzzyfizierung reimplementiert

parent f2f54a7b
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -112,6 +112,29 @@ public final class FuzzySet {
        return t4;
    }

    /**
     * Berechnet mit Hilfe des Strahlensatzes die Zugehörigkeit eines Terms.
     *
     * <p><img src="doc-files/strahlensatz.png" alt="Strahlensatz"></p>
     */
    double bestimmeZugehoerigkeit(double wert) {
        if (t1 < wert && wert < t2) {
            double laengeZA = wert - t1;
            double laengeZC = t2 - t1;
            double laengeCD = 1.0;
            return (laengeZA / laengeZC) * laengeCD;
        } else if (t2 <= wert && wert <= t3) {
            return 1.0;
        } else if (t3 < wert && wert < t4) {
            double laengeZA = t4 - wert;
            double laengeZC = t4 - t3;
            double laengeCD = 1.0;
            return (laengeZA / laengeZC) * laengeCD;
        } else {
            return 0.0;
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
+46 −25
Original line number Diff line number Diff line
@@ -139,6 +139,11 @@ public final class LinguistischeVariable {
                .collect(Collectors.toList());
    }

    private static Term bestimmeTerm(FuzzySet fuzzySet, double wert) {
        double z = fuzzySet.bestimmeZugehoerigkeit(wert);
        return new Term(fuzzySet.getName(), Zugehoerigkeit.von(z));
    }

    private List<Term> fasseGleicheTermeZusammen(List<Term> terme) {
        List<Term> zusammengefasst = new ArrayList<>();
        for (Term t : terme) {
@@ -160,32 +165,48 @@ public final class LinguistischeVariable {
        return zusammengefasst;
    }

    /**
     * Berechnet mit Hilfe des Strahlensatzes die Zugehörigkeit eines Terms.
     *
     * <p><img src="doc-files/strahlensatz.png" alt="Strahlensatz"></p>
     */
    private static Term bestimmeTerm(FuzzySet fuzzySet, double wert) {
        double z = 0.0;
        if (fuzzySet.getT1() < wert && wert < fuzzySet.getT2()) {
            double laengeZA = wert - fuzzySet.getT1();
            double laengeZC = fuzzySet.getT2() - fuzzySet.getT1();
            double laengeCD = 1.0;
            z = (laengeZA / laengeZC) * laengeCD;
        } else if (fuzzySet.getT2() <= wert && wert <= fuzzySet.getT3()) {
            z = 1.0;
        } else if (fuzzySet.getT3() < wert && wert < fuzzySet.getT4()) {
            double laengeZA = fuzzySet.getT4() - wert;
            double laengeZC = fuzzySet.getT4() - fuzzySet.getT3();
            double laengeCD = 1.0;
            z = (laengeZA / laengeZC) * laengeCD;
        }
        return new Term(fuzzySet.getName(), Zugehoerigkeit.von(z));
    }

    public double defuzzyfiziere(FuzzyVariable variable) {
        // TODO Defuzzyfizierung implementieren
        return 0.0;
        List<String> terme = variable.getTerme().stream()
                .filter(t -> t.getZugehoerigkeit().nonNull())
                .map(Term::getName)
                .collect(Collectors.toList());
        terme.retainAll(getTerme());

        List<FuzzySet> fuzzySets = getFuzzySets().stream()
                .filter(fs -> terme.contains(fs.getName()))
                .filter(fs -> variable.gibTerm(fs.getName()).getZugehoerigkeit().getWert() > 0)
                .sorted(Comparator.comparingDouble(FuzzySet::getT1))
                .collect(Collectors.toList());
        double min = fuzzySets.stream()
                .mapToDouble(FuzzySet::getT1)
                .min()
                .getAsDouble();
        double max = fuzzySets.stream()
                .mapToDouble(FuzzySet::getT4)
                .max()
                .getAsDouble();

        double minSchrittweite = 0.5;
        int maxAnzahlStuetzpunkte = 100;
        int anzahlStuetzpunkte = (int) Math.min((max - min) / minSchrittweite, maxAnzahlStuetzpunkte);

        double a = 0;
        double l = 0;
        for (int i = 0; i <= anzahlStuetzpunkte; i++) {
            double stuetzpunkt = min + i * (max - min) / anzahlStuetzpunkte;
            double zugehoerigkeit = Double.NEGATIVE_INFINITY;
            for (FuzzySet fs : fuzzySets) {
                double zugehoerigkeitFuzzySet = fs.bestimmeZugehoerigkeit(stuetzpunkt);
                double zugehoerigkeitTerm = variable.gibTerm(fs.getName()).getZugehoerigkeit().getWert();
                double z = Math.min(zugehoerigkeitFuzzySet, zugehoerigkeitTerm);
                if (z > zugehoerigkeit) {
                    zugehoerigkeit = z;
                }
            }
            a += stuetzpunkt * zugehoerigkeit;
            l += zugehoerigkeit;
        }
        return a / l;
    }

    @Override
+19 −29
Original line number Diff line number Diff line
@@ -186,51 +186,41 @@ public class LinguistischeVariableTests {
    }

    @Test
    @Ignore("Defuzzyfizierung noch nicht implementiert")
    public void defuzzyfiziere_Normalfall() {
        LinguistischeVariable linguistischeVariable = erzeugeLinguistischeVariable();
    public void defuzzyfiziere_BeispielWikipedia_FuzzyRegler() {
        LinguistischeVariable linguistischeVariable = new LinguistischeVariable(
                "x",
                new Wertebereich(4, 36),
                FuzzySet.abfallendeRampe("a", 4, 8, 16),
                FuzzySet.dreieck("b", 8, 16, 24),
                FuzzySet.dreieck("c", 16, 24, 32),
                FuzzySet.aufsteigendeRampe("d", 24, 32, 36)
        );

        double wert = linguistischeVariable.defuzzyfiziere(
                new FuzzyVariable("Geschwindigkeit",
                        new Term("niedrig", Zugehoerigkeit.von(0.5)),
                        new Term("mittel", Zugehoerigkeit.von(0.5)),
                        new Term("hoch", Zugehoerigkeit.von(0.0))
                new FuzzyVariable("x",
                        new Term("a", Zugehoerigkeit.von(0.0)),
                        new Term("b", Zugehoerigkeit.von(0.15)),
                        new Term("c", Zugehoerigkeit.von(0.75)),
                        new Term("d", Zugehoerigkeit.von(0.0))
                )
        );

        assertEquals(25.0, wert, 0.001);
        assertEquals(22.43, wert, 0.01);
    }

    @Test
    @Ignore("Defuzzyfizierung noch nicht implementiert")
    public void defuzzyfiziere_FalscheVariable_Ausnahmefehler() {
        exception.expect(IllegalArgumentException.class);
        exception.expectMessage("Die Namen der linguistischen Variable und der Fuzzy-Variable stimmen nicht überein.");
    public void defuzzyfiziere_Normalfall() {
        LinguistischeVariable linguistischeVariable = erzeugeLinguistischeVariable();

        linguistischeVariable.defuzzyfiziere(
                new FuzzyVariable("Verkehrsdichte",
        double wert = linguistischeVariable.defuzzyfiziere(
                new FuzzyVariable("Geschwindigkeit",
                        new Term("niedrig", Zugehoerigkeit.von(0.5)),
                        new Term("mittel", Zugehoerigkeit.von(0.5)),
                        new Term("hoch", Zugehoerigkeit.von(0.0))
                )
        );
    }

    @Test
    @Ignore("Defuzzyfizierung noch nicht implementiert")
    public void defuzzyfiziere_FalscherTerm_Ausnahmefehler() {
        exception.expect(IllegalArgumentException.class);
        exception.expectMessage("Die linguistische Variable und die Fuzzy-Variable haben verschiedene Terme.");
        LinguistischeVariable linguistischeVariable = erzeugeLinguistischeVariable();

        linguistischeVariable.defuzzyfiziere(
                new FuzzyVariable("Geschwindigkeit",
                        new Term("langsam", Zugehoerigkeit.von(0.5)),
                        new Term("mittel", Zugehoerigkeit.von(0.5)),
                        new Term("hoch", Zugehoerigkeit.von(0.0))
                )
        );
        assertEquals(41.04, wert, 0.01);
    }

    @Test