Commit aad03838 authored by Falko Schumann's avatar Falko Schumann

Fuzzyfizierung und Defuzzyfizierung als interne private Klasse

parent 5779b62d
/*
* 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;
}
}
/*
* 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));
}
}
......@@ -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;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment