Commit 5779b62d authored by Falko Schumann's avatar Falko Schumann

Refaktorisierung

parent 2c62c656
/*
* 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));
}
}
......@@ -37,8 +37,7 @@ import java.util.stream.*;
* <p>
* Durch Fuzzyfizierung wird für einen scharfen Messwert eine Fuzzy-Variable
* bestimmt. Durch Defuzzyfizierung wird für eine Fuzzy-Variable ein scharfer
* Messwert bestimmt. Fuzzyfizierung und Defuzzyfizierung finden nur im
* Wertebereich der Messgröße statt.
* Messwert bestimmt.
*
* @author BitCtrl Systems GmbH, Falko Schumann
* @see FuzzySet
......@@ -125,88 +124,11 @@ public final class LinguistischeVariable {
}
public 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(fuzzySets, wert);
terme = fasseGleicheTermeZusammen(terme);
return new FuzzyVariable(name, terme);
}
private static List<Term> fuzzyfiziere(List<FuzzySet> fuzzySets, double wert) {
return fuzzySets.stream()
.map(fs -> bestimmeTerm(fs, wert))
.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) {
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;
return new Fuzzyfizierung(this).fuzzyfiziere(wert);
}
public double defuzzyfiziere(FuzzyVariable variable) {
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;
public double defuzzyfiziere(FuzzyVariable fuzzyWert) {
return new Defuzzyfizierung(this).defuzzyfiziere(fuzzyWert);
}
@Override
......
......@@ -195,34 +195,46 @@ public class LinguistischeVariableTests {
FuzzySet.dreieck("c", 16, 24, 32),
FuzzySet.aufsteigendeRampe("d", 24, 32, 36)
);
double wert = linguistischeVariable.defuzzyfiziere(
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))
)
FuzzyVariable fuzzyWert = 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))
);
double wert = linguistischeVariable.defuzzyfiziere(fuzzyWert);
assertEquals(22.43, wert, 0.01);
}
@Test
public void defuzzyfiziere_Normalfall() {
LinguistischeVariable linguistischeVariable = erzeugeLinguistischeVariable();
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))
)
FuzzyVariable fuzzyWert = new FuzzyVariable("Geschwindigkeit",
new Term("niedrig", Zugehoerigkeit.von(0.5)),
new Term("mittel", Zugehoerigkeit.von(0.5)),
new Term("hoch", Zugehoerigkeit.von(0.0))
);
double wert = linguistischeVariable.defuzzyfiziere(fuzzyWert);
assertEquals(41.04, wert, 0.01);
}
@Test
public void defuzzyfiziere_TermePassenNicht() {
LinguistischeVariable linguistischeVariable = erzeugeLinguistischeVariable();
FuzzyVariable fuzzyWert = new FuzzyVariable("Geschwindigkeit",
new Term("x", Zugehoerigkeit.von(0.5)),
new Term("y", Zugehoerigkeit.von(0.5)),
new Term("z", Zugehoerigkeit.von(0.0))
);
double wert = linguistischeVariable.defuzzyfiziere(fuzzyWert);
assertTrue(Double.isNaN(wert));
}
@Test
public void formattierterText() {
LinguistischeVariable geschwindigkeit = erzeugeLinguistischeVariable();
......
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