Commit aad03838 authored by Falko Schumann's avatar Falko Schumann
Browse files

Fuzzyfizierung und Defuzzyfizierung als interne private Klasse

parent 5779b62d
Loading
Loading
Loading
Loading
+0 −105
Original line number Diff line number Diff line
/*
 * Segment 5 Intelligente Analyseverfahren, SWE 5.4 Funktionen Fuzzy
 * Copyright (C) 2007-2018 BitCtrl Systems GmbH
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.iav.fuzzylib.fuzzylib;

import java.util.*;
import java.util.stream.*;

class Defuzzyfizierung {

    private final LinguistischeVariable linguistischeVariable;

    Defuzzyfizierung(LinguistischeVariable linguistischeVariable) {
        this.linguistischeVariable = linguistischeVariable;
    }

    double defuzzyfiziere(FuzzyVariable fuzzyWert) {
        List<FuzzySet> fuzzySets = bestimmeRelevanteFuzzySets(fuzzyWert);
        if (fuzzySets.isEmpty()) {
            return Double.NaN;
        }
        Wertebereich intervall = bestimmeIntervall(fuzzySets);
        return bestimmeFlaechenschwerpunkt(fuzzyWert, fuzzySets, intervall);
    }

    private List<FuzzySet> bestimmeRelevanteFuzzySets(FuzzyVariable fuzzyWert) {
        List<String> gemeinsameTerme = bestimmeGemeinsameTerme(fuzzyWert);
        return gemeinsameTerme.stream()
                .map(t -> linguistischeVariable.gibFuzzySet(t))
                .sorted(Comparator.comparingDouble(FuzzySet::getT1))
                .collect(Collectors.toList());
    }

    private Wertebereich bestimmeIntervall(List<FuzzySet> fuzzySets) {
        double min = fuzzySets.stream()
                .mapToDouble(FuzzySet::getT1)
                .min()
                .getAsDouble();
        double max = fuzzySets.stream()
                .mapToDouble(FuzzySet::getT4)
                .max()
                .getAsDouble();
        return new Wertebereich(min, max);
    }

    private double bestimmeFlaechenschwerpunkt(FuzzyVariable fuzzyWert, List<FuzzySet> fuzzySets, Wertebereich intervall) {
        double min = intervall.getMinimum();
        double max = intervall.getMaximum();
        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 = fuzzyWert.gibTerm(fs.getName()).getZugehoerigkeit().getWert();
                double z = Math.min(zugehoerigkeitFuzzySet, zugehoerigkeitTerm);
                if (z > zugehoerigkeit) {
                    zugehoerigkeit = z;
                }
            }
            a += stuetzpunkt * zugehoerigkeit;
            l += zugehoerigkeit;
        }
        return a / l;
    }

    private List<String> bestimmeGemeinsameTerme(FuzzyVariable fuzzyVariable) {
        List<String> nonNullTerme = fuzzyVariable.getTerme().stream()
                .filter(t -> t.getZugehoerigkeit().nonNull())
                .filter(t -> t.getZugehoerigkeit().getWert() > 0)
                .map(Term::getName)
                .collect(Collectors.toList());
        nonNullTerme.retainAll(linguistischeVariable.getTerme());
        return nonNullTerme;
    }

}
+0 −81
Original line number Diff line number Diff line
/*
 * Segment 5 Intelligente Analyseverfahren, SWE 5.4 Funktionen Fuzzy
 * Copyright (C) 2007-2018 BitCtrl Systems GmbH
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.iav.fuzzylib.fuzzylib;

import java.util.*;
import java.util.stream.*;

class Fuzzyfizierung {

    private final LinguistischeVariable linguistischeVariable;

    Fuzzyfizierung(LinguistischeVariable linguistischeVariable) {
        this.linguistischeVariable = linguistischeVariable;
    }

    FuzzyVariable fuzzyfiziere(double wert) {
        // TODO Wenn nur t2 und t3 der Fuzzy-Sets angegeben sind, t1 und t4 so berechnen, das fließende Übergänge entstehen
        // TODO Wenn nur t2 und t3 der Fuzzy-Sets angegeben sind, für erstes und letztes Fuzzy-Set im Wertebereich Rampen annehmen

        List<Term> terme = fuzzyfiziere(linguistischeVariable.getFuzzySets(), wert);
        terme = fasseGleicheTermeZusammen(terme);
        return new FuzzyVariable(linguistischeVariable.getName(), terme);
    }

    private List<Term> fuzzyfiziere(List<FuzzySet> fuzzySets, double wert) {
        return fuzzySets.stream()
                .map(fs -> bestimmeTerm(fs, wert))
                .collect(Collectors.toList());
    }

    private List<Term> fasseGleicheTermeZusammen(List<Term> terme) {
        List<Term> zusammengefasst = new ArrayList<>();
        for (Term t : terme) {
            boolean neuerTerm = true;
            for (int i = 0; i < zusammengefasst.size(); i++) {
                if (t.getName().equals(zusammengefasst.get(i).getName())) {
                    double z1 = t.getZugehoerigkeit().getWert();
                    double z2 = zusammengefasst.get(i).getZugehoerigkeit().getWert();
                    double z = Math.max(z1, z2);
                    zusammengefasst.set(i, new Term(t.getName(), Zugehoerigkeit.von(z)));
                    neuerTerm = false;
                    break;
                }
            }
            if (neuerTerm) {
                zusammengefasst.add(t);
            }
        }
        return zusammengefasst;
    }

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

}
+127 −0
Original line number Diff line number Diff line
@@ -151,4 +151,131 @@ public final class LinguistischeVariable {
        return name + " (" + wertebereich + "): " + fuzzySets;
    }

    private static class Fuzzyfizierung {

        private final LinguistischeVariable linguistischeVariable;

        Fuzzyfizierung(LinguistischeVariable linguistischeVariable) {
            this.linguistischeVariable = linguistischeVariable;
        }

        FuzzyVariable fuzzyfiziere(double wert) {
            // TODO Wenn nur t2 und t3 der Fuzzy-Sets angegeben sind, t1 und t4 so berechnen, das fließende Übergänge entstehen
            // TODO Wenn nur t2 und t3 der Fuzzy-Sets angegeben sind, für erstes und letztes Fuzzy-Set im Wertebereich Rampen annehmen

            List<Term> terme = fuzzyfiziere(linguistischeVariable.getFuzzySets(), wert);
            terme = fasseGleicheTermeZusammen(terme);
            return new FuzzyVariable(linguistischeVariable.getName(), terme);
        }

        private List<Term> fuzzyfiziere(List<FuzzySet> fuzzySets, double wert) {
            return fuzzySets.stream()
                    .map(fs -> bestimmeTerm(fs, wert))
                    .collect(Collectors.toList());
        }

        private List<Term> fasseGleicheTermeZusammen(List<Term> terme) {
            List<Term> zusammengefasst = new ArrayList<>();
            for (Term t : terme) {
                boolean neuerTerm = true;
                for (int i = 0; i < zusammengefasst.size(); i++) {
                    if (t.getName().equals(zusammengefasst.get(i).getName())) {
                        double z1 = t.getZugehoerigkeit().getWert();
                        double z2 = zusammengefasst.get(i).getZugehoerigkeit().getWert();
                        double z = Math.max(z1, z2);
                        zusammengefasst.set(i, new Term(t.getName(), Zugehoerigkeit.von(z)));
                        neuerTerm = false;
                        break;
                    }
                }
                if (neuerTerm) {
                    zusammengefasst.add(t);
                }
            }
            return zusammengefasst;
        }

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

    }

    private static class Defuzzyfizierung {

        private final LinguistischeVariable linguistischeVariable;

        Defuzzyfizierung(LinguistischeVariable linguistischeVariable) {
            this.linguistischeVariable = linguistischeVariable;
        }

        double defuzzyfiziere(FuzzyVariable fuzzyWert) {
            List<FuzzySet> fuzzySets = bestimmeRelevanteFuzzySets(fuzzyWert);
            if (fuzzySets.isEmpty()) {
                return Double.NaN;
            }
            Wertebereich intervall = bestimmeIntervall(fuzzySets);
            return bestimmeFlaechenschwerpunkt(fuzzyWert, fuzzySets, intervall);
        }

        private List<FuzzySet> bestimmeRelevanteFuzzySets(FuzzyVariable fuzzyWert) {
            List<String> gemeinsameTerme = bestimmeGemeinsameTerme(fuzzyWert);
            return gemeinsameTerme.stream()
                    .map(t -> linguistischeVariable.gibFuzzySet(t))
                    .sorted(Comparator.comparingDouble(FuzzySet::getT1))
                    .collect(Collectors.toList());
        }

        private Wertebereich bestimmeIntervall(List<FuzzySet> fuzzySets) {
            double min = fuzzySets.stream()
                    .mapToDouble(FuzzySet::getT1)
                    .min()
                    .getAsDouble();
            double max = fuzzySets.stream()
                    .mapToDouble(FuzzySet::getT4)
                    .max()
                    .getAsDouble();
            return new Wertebereich(min, max);
        }

        private double bestimmeFlaechenschwerpunkt(FuzzyVariable fuzzyWert, List<FuzzySet> fuzzySets, Wertebereich intervall) {
            double min = intervall.getMinimum();
            double max = intervall.getMaximum();
            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 = fuzzyWert.gibTerm(fs.getName()).getZugehoerigkeit().getWert();
                    double z = Math.min(zugehoerigkeitFuzzySet, zugehoerigkeitTerm);
                    if (z > zugehoerigkeit) {
                        zugehoerigkeit = z;
                    }
                }
                a += stuetzpunkt * zugehoerigkeit;
                l += zugehoerigkeit;
            }
            return a / l;
        }

        private List<String> bestimmeGemeinsameTerme(FuzzyVariable fuzzyVariable) {
            List<String> nonNullTerme = fuzzyVariable.getTerme().stream()
                    .filter(t -> t.getZugehoerigkeit().nonNull())
                    .filter(t -> t.getZugehoerigkeit().getWert() > 0)
                    .map(Term::getName)
                    .collect(Collectors.toList());
            nonNullTerme.retainAll(linguistischeVariable.getTerme());
            return nonNullTerme;
        }

    }


}