Teilentwurf eines Fuzzy-Reglers
|
Bild 0-1: UML-Klassendiagramme zum FuzzyRegler-Modul.
|
public class FuzzySet
{
protected double[] maxpos = null;
protected double min = 0.0;
protected double max = 0.0;
public FuzzySet()
{
}
public void erzeugeFuzzyGroessen(int anzahl)
{
if(anzahl>1) //mindestens min und max bei Eingangsfuzzysets
// if(anzahl>3) //mindestens zwei Größen und min und max für Ausgangsfuzzysets.
{
maxpos = new double[anzahl];
for(int i=0;i<maxpos.length;i++)
maxpos[i] = (double)i;
}
}
public void verteileFuzzyGroessenGleichmaessig(double min, double max)
{
if(max>min && maxpos!=null && maxpos.length>1)
{
double delta = (max-min)/((double)maxpos.length-1);
this.min = min;
this.max = max;
for(int i=0;i<maxpos.length;i++)
maxpos[i] = min + (double)i*delta;
}
}
/**
Um bei Optimierungen mit n Parametern zwischen 0..1 operieren zu<br/>
können, wird hier als absolute Grenzen min und max verwendet und<br/>
darauf bezogen die Maxima der Fuzzysets verteilt.<br/>
Vorgehen:<br/>
<code>
Es gibt die Verteilungen v0..vn-1
1. Setze das Maximum der ersten Fuzzygröße an die Stelle p0 = min + v0*(max-min)
2. Setze das Maximum der zweiten Fuzzygröße an die Stelle p1 = p0 + v1*(max-p0)
3. Setze das Maximum der zweiten Fuzzygröße an die Stelle p2 = p1 + v2*(max-p1)
usw.
</code>
<br/>
D.h. Die Ränder dürfen auch innerhalb von [min,max] liegen, aber nicht außerhalb.<br/>
Somit sollte [min,max] so eingestellt werden, dass diese absolute Grenzen darstellen,
die niemals überschritten werden dürfen.<br/>
Eine gleichmäßige Verteilung in [min,max] erhält man beispielsweise<br/>
bei 5 Parametern (0-1-2-3-4) über Verteilungswerte von:<br/>
verteilung = { 0 , 1/4 , 1/3 , 1/2 , 1 }
*/
public void verteileFuzzyGroessenNormiert(double[] verteilung)
{
if(maxpos!=null && verteilung!=null
&& maxpos.length==verteilung.length
&& max>min)
{
double palt=min;
for(int i=0;i<maxpos.length;i++)
{
maxpos[i] = palt + verteilung[i]*(max-palt);
palt = maxpos[i];
}
}
}
}
Code 0-1: Klasse FuzzySet
public class FuzzyEingangsSet extends FuzzySet
{
/**
Liefert den Zugehörigkeitsgrad des Eingangswerts input zu der i-ten Fuzzygröße.<br/>
D.h. es wird hier der i-te Zugehörigkeitswert für die übergebene Eingangsgroesse berechnet.
*/
public double getZugehoerigkeitsgrad(int i,double input)
{
if(maxpos==null || maxpos.length<2)
return 0.0;
if(i==0 && input<=maxpos[0]) //linker Rand
return 1.0;
if(i==maxpos.length-1 && input>=maxpos[i]) //rechter Rand
return 1.0;
if(i>0 && input<=maxpos[i-1]) //Nullbereich links
return 0.0;
if(i<maxpos.length-1 && input>=maxpos[i+1]) //Nullbereich rechts
return 0.0;
if(i>0 && input<maxpos[i]) //positive Steigung
if(maxpos[i]-maxpos[i-1]>0.0)
return (input-maxpos[i-1])/(maxpos[i]-maxpos[i-1]);
else
return 1.0;
if(i<maxpos.length-1 && input>maxpos[i]) //negative Steigung
if(maxpos[i+1]-maxpos[i]>0.0)
return (input-maxpos[i+1])/(maxpos[i]-maxpos[i+1]);
else
return 1.0;
System.out.println("Ungueltiges Ergebnis in getZugehoerigkeitsgrad()!");
return 0.0;
}
public static void main(String[] args)
{
//Beispiel aus Vorlesung durchtesten:
FuzzyEingangsSet raumtemperatur = new FuzzyEingangsSet();
raumtemperatur.erzeugeFuzzyGroessen(2);
raumtemperatur.verteileFuzzyGroessenGleichmaessig(10.0,30.0);
FuzzyEingangsSet luftfeuchte = new FuzzyEingangsSet();
luftfeuchte.erzeugeFuzzyGroessen(2);
luftfeuchte.verteileFuzzyGroessenGleichmaessig(50.0,70.0);
System.out.println("Tests:");
System.out.println("[25,60]");
System.out.println("RK="+raumtemperatur.getZugehoerigkeitsgrad(0,25.0));
System.out.println("RG="+raumtemperatur.getZugehoerigkeitsgrad(1,25.0));
System.out.println("LK="+luftfeuchte.getZugehoerigkeitsgrad(0,60.0));
System.out.println("LG="+luftfeuchte.getZugehoerigkeitsgrad(1,60.0));
}
}
Code 0-2: Klasse EingangsFuzzySet
public class FuzzyAusgangsSet extends FuzzySet
{
/**
ACHTUNG:<br/>
nr==0 verwendet das Maximum bei maxpos[1] usw.
*/
public double getFlaeche(int nr, double regelaktivierung)
{
if(nr<0 || nr>maxpos.length-3)
return 0.0;
if(regelaktivierung<=0)
return 0.0;
return
regelaktivierung*(maxpos[nr+1]-maxpos[nr])*( 1.0 - 0.5*regelaktivierung)
+ regelaktivierung*(maxpos[nr+2]-maxpos[nr+1])*( 1.0 - 0.5*regelaktivierung)
;
}
public double getSchwerpunkt(int nr, double regelaktivierung)
{
if(nr<0 || nr>maxpos.length-3)
return 0.0;
if(regelaktivierung<=0)
return 0.0;
return
?????????????????????????????????
;
}
public static void main(String[] args)
{
//?????????????????????????????
}
}
Code 0-3: Klasse AusgangsFuzzySet
Hinweise zu den Klassen
|
Array maxpos: x-Positionen der Maxima in EingangsFuzzySet.
^
|___ _____
| \/\/\/
| /\/\/\
--------------> Maximums-Position
Max Nr.0 1 2 3
Array maxpos: x-Positionen der Maxima in AusgangsFuzzySet.
^
|
| /\/\/\/\
| / /\/\/\ \
--------------> Maximums-Position
Max Nr. 0 1 2 3 4 5
Anders als beim EingangsFuzzySet
markieren 0 und 5 in dem Beispiel keine Maximumslage, sondern
den Rand! Nur 1..4 sind Maximumslagen in maxpos.
Code 0-4: Vergleich der Bedeutung des Arrays maxpos in EingangsFuzzySet und AusgangsFuzzySet.
|