kramann.info
© Guido Kramann

Login: Passwort:










18.5.2 Teilentwurf eines Fuzzy-Reglers

  • Dieses Kapitel stellt eine Teilentwicklung zum Modul FuzzyRegler dar.
  • Die Hauptklasse stellt die Klasse FuzzyRegler dar.
  • Ähnlich wie die C-Funktion der letzten Aufgabe soll sie erlauben über die Methode berechneAusgang(...) die Stellgröße aus den Eingangsgrößen (z.B. der Regeldifferenz) zu bestimmen.
  • Anders als die C-Fuktion soll die Klasse aber für beliebige Fuzzy-Regler konfiguriert werden können.
  • Insbesondere können Fuzzy-Eingangssets, ein Fuzzy-Ausgangsset und die beide verknüpfenden Fuzzy-Regeln formuliert werden.
  • Unterklasse bilden FuzzyEingangsSet, FuzzyAusgangsSet und FuzzyRegeln.
  • Objekte dieser Klassen werden in FuzzyRegler registriert und spezifizieren zu dessen Verhalten.
UML-Klassendiagramme zum FuzzyRegler-Modul.

Bild 18.5.2-1: UML-Klassendiagramme zum FuzzyRegler-Modul.

  • An dieser Stelle soll nur ein Teilentwurf bestehend aus der Klasse FuzzyEingangsSet und der unvollständig implementierten Klasse FuzzyAusgangsSet dargestellt werden.
  • Die Fortsetzung der Implementierung soll im Rahmen einer nachfolgenden Übung erfolgen.
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 18.5.2-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 18.5.2-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 18.5.2-3: Klasse AusgangsFuzzySet

Hinweise zu den Klassen

  • Eingangs-Fuzzysets sind an den Rändern offen, Ausgangs-Fuzzysets geschlossen:
    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 18.5.2-4: Vergleich der Bedeutung des Arrays maxpos in EingangsFuzzySet und AusgangsFuzzySet.

  • Es gibt nur die Möglichkeit äquidistante Maxima zu initialisieren. Alles andere erfolgt über ein Optimierungsprogramm später.