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

Defuzzyfizierung reimplementiert

parent f2f54a7b
......@@ -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;
......
......@@ -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
......
......@@ -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
......
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