Package fmg.fmg8.endlAutomat.mutation

Source Code of fmg.fmg8.endlAutomat.mutation.MutArt1VT

/*
* Datei:            MutationsArt1Trans.java
* Autor(en):        Lukas K�nig
* Java-Version:     1.4
* Erstellt (vor):   08.01.2008
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/

package fmg.fmg8.endlAutomat.mutation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.Transition;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.sonstiges.MathMeth;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.umgebung2D.Roboter;

/**
* Die erste Mutationsart mit angepasstem Modus f�r die Mutation von
* Translatoren.
*
* @author Lukas K�nig
*/
public class MutArt1VT implements CondMutVerfahren {

    /**
     * Der Zufallsgenerator.
     */
    private Random rand;

    /**
     * Der konstante Parameter zur Einschr�nkung direkter Zahlmutationen.
     * Es muss gelten: 0 < k <= 255.
     */
    private int k;

    /**
     * Der Modus (�bersetzer oder Verhaltensautomat).
     */
    private int modus;
   
    /**
     * Verhaltensautomaten-Modus.
     */
    public static final int MODUS_VERHALTEN
        = SonstMeth.MODUS_VERHALTEN;
   
    /**
     * �bersetzermodus.
     */
    public static final int MODUS_TRANSLATOR
        = SonstMeth.MODUS_TRANSLATOR;

    /**
     * Konstruktor.
     *
     * @param random  Der Zufallsgenerator.
     * @param kKonst  Die Konstante k aus der Definition der Mutation: Gibt an
     *                wie gro� die �nderung bei bspw. Sensorwerten maximal
     *                sein darf.
     * @param mod     Der Modus (Verhalten oder �bersetzer).
     */
    public MutArt1VT(
            final Random random,
            final int    kKonst,
            final int    mod) {
        this.rand  = random;
        this.k     = kKonst;
        this.modus = mod;
       
        throw new RuntimeException("Mutation nicht ausgewaehlt.");
    }

    /**
     * Falls (mind.) eine "false"-Kante im Automaten existiert, wird eine
     * zuf�llige "false"-Kante gel�scht. Sonst bleibt der Automat unver�ndert.
     * Die Zuf�lligkeit bezieht sich nur auf die Wahl des Ausgangsknotens.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Kante entfernt wurde.
     */
    public final boolean mutationFalseKanteRem(final EndlicherAutomat ea) {
        HashMap<Integer, LinkedList<Transition>> alleBeds
            = ea.getAlleBedingungen();
        ArrayList<Integer> alleKnoten
            = new ArrayList<Integer>(alleBeds.keySet());
        LinkedList<Transition> aktBeds;
        Integer aktKnoten;
        Iterator<Transition> it;
        String aktBed;
        Transition vollstBed;
        Integer fZustand;
        int pruefIndex;
       
        while (alleKnoten.size() > 0) {
            pruefIndex = this.rand.nextInt(alleKnoten.size());
            aktKnoten = alleKnoten.get(pruefIndex);
            aktBeds = alleBeds.get(aktKnoten);
           
            it = aktBeds.iterator();
            while (it.hasNext()) {
                vollstBed = (Transition) it.next();
                aktBed = vollstBed.getCond().formatted();
                if (aktBed.charAt(1) == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
                    fZustand = new Integer(vollstBed.getFolgezustand());
                    ea.entferneKante(aktKnoten, fZustand, vollstBed);
                    return true;
                }
            }
           
            alleKnoten.remove(pruefIndex);
        }
       
        return false;
    }

    /**
     * F�gt eine "false"-Kante in den Automaten ein, falls mindestens ein
     * Zustand existiert. Die eingef�gte Kante zeigt
     * von rand(Z) nach rand(Z)
     * mit Z = Zust�nde des Automaten.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Kante eingef�gt wurde.
     */
    public final boolean mutationFalseKanteEin(final EndlicherAutomat ea) {
        ArrayList<Integer> knListe = ea.getKnList();
        Integer zufallsKnoten1;
        Integer zufallsKnoten2;
       
        if (knListe.size() > 0) {
            zufallsKnoten1 = knListe.get(this.rand.nextInt(knListe.size()));
            zufallsKnoten2 = knListe.get(this.rand.nextInt(knListe.size()));
            if (!ea.kanteExistiert(zufallsKnoten1, zufallsKnoten2)) {
                ea.einfuegKante(
                        zufallsKnoten1,
                        zufallsKnoten2,
                        " " + fmg.fmg8.endlAutomat.Konstanten.FALSE + " ",
                        1);
                return true;
            }
        }
       
        return false;
    }

    /**
     * L�scht einen Zustand ohne eingehende Kanten aus dem Automaten,
     * falls mindestens ein solcher Zustand existiert.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob ein Zustand gel�scht wurde.
     */
    public final boolean mutationZustandRem1(final EndlicherAutomat ea) {
        ArrayList<Integer> knListe = ea.getKnList();
        Knoten zufallsKnoten1;
        int zufallsIndex;

        while (knListe.size() > 0) {
            zufallsIndex = this.rand.nextInt(knListe.size());
            zufallsKnoten1 = (Knoten) ea.holeKnoten(knListe.get(zufallsIndex));
            if (!ea.istStartZ(zufallsKnoten1)
                && zufallsKnoten1.holeVorgaenger().size() == 0) {
               
                ea.entferneKnoten(knListe.get(zufallsIndex));
                return true;
            }
            knListe.remove(zufallsIndex);
        }
        return false;
    }

    /**
     * L�scht einen Zustand ohne ausgehende Kanten und IDLE als Befehl aus dem
     * Automaten, falls mindestens ein solcher Zustand existiert.
     *
     * SEMI-SEMANTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob ein Zustand gel�scht wurde.
     */
    public final boolean mutationZustandRem2(final EndlicherAutomat ea) {
        ArrayList<Integer> knListe = ea.getKnList();
        Knoten zufallsKnoten1;
        int zufallsIndex;

        while (knListe.size() > 0) {
            zufallsIndex = this.rand.nextInt(knListe.size());
            zufallsKnoten1 = (Knoten) ea.holeKnoten(knListe.get(zufallsIndex));
            if (((ZInfo) zufallsKnoten1.getInfo()).getAktion()
                    == Konstanten.IDLE_BEFEHL
                && zufallsKnoten1.holeNachfolger().size() == 0
                && !ea.istStartZ(zufallsKnoten1)) {
               
                ea.entferneKnoten(knListe.get(zufallsIndex));
                return true;
            }
            knListe.remove(zufallsIndex);
        }
        return false;
    }

    /**
     * F�gt einen Zustand ohne eingehende Kanten in den Automaten ein.
     * Falls der Namensraum f�r Zust�nde �berl�uft, bleibt der Automat
     * unver�ndert. Falls vorher kein Startzustand
     * existierte, wird der neue Zustand zum Startzustand.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob ein Zustand eingef�gt wurde.
     */
    public final boolean mutationZustandEin(final EndlicherAutomat ea) {
        int parameter;
        int befehl;
        ArrayList<Integer> knListe = ea.getKnList();
        final int byteMax = 255;
        Integer name;
       
        parameter = this.rand.nextInt(this.k) + 1;

        befehl = SonstMeth.glVertZwischen(
                SonstMeth.minBef(this.modus),
                SonstMeth.maxBef(this.modus),
                this.rand);
       
        for (int i = 1; i <= byteMax; i++) {
            name = new Integer(i);
            if (!knListe.contains(name)) {
                ea.einfuegenKnoten(name, befehl, parameter, 1);
                if (ea.holeStartzustand() == null) {
                    ea.setStart(ea.holeKnoten(name));
                }
                return true;
            }
        }
       
        return false;
    }

    /**
     * Mutiert eine zuf�llige Bedingung nach dem folgenden Muster:
     * false <> a = b <> a ~ b <> a <= b <> a < b <> a # b <> a != b <> true
     * Falls keine Bedingung existiert, bleibt der Automat unver�ndert.
     *
     * SEMANTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Bedingung mutiert wurde.
     */
    public final boolean mutationBedA(final EndlicherAutomat ea) {
        ArrayList<Transition> bedingungen = ea.getBedListe();
        Transition aktBed;
        String aktString;
        String neuString = "";
        int pos;
        int zufallsindex;
        ArrayList<Character> zeichen = new ArrayList<Character>(2);
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.FALSE));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.GL));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.UNGF));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.KLGL));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.GRGL));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.KL));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.GR));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.NUNGF));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.UGL));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.TRUE));
        boolean links = this.rand.nextBoolean();
        boolean oben = this.rand.nextBoolean();
        boolean var1 = this.rand.nextBoolean();
        boolean var2 = !var1 || this.rand.nextBoolean();
        String string1;
        String string2;

        if (bedingungen.size() > 0) {
            zufallsindex = this.rand.nextInt(bedingungen.size());
            aktBed = (Transition) bedingungen.get(zufallsindex);
            aktString = aktBed.getCond().formatted();

            pos = this.indexZeichen(aktString,
                                    zeichen);
            if (aktString.charAt(pos)
                    == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
                if (var1) {
                    int variable1 = SonstMeth.glVertZwischen(
                            SonstMeth.minVar(this.modus),
                            SonstMeth.maxVar(this.modus),
                            this.rand);
                   
                    string1 = " " 
                        + fmg.fmg8.endlAutomat.Konstanten.EING + " "
                        + fmg.fmg8.sonstiges.SonstMeth.normZahl(variable1);
                } else {
                    int nummer1 = this.rand.nextInt(255) + 1;
                    string1 = fmg.fmg8.sonstiges.SonstMeth.normZahl(nummer1);
                }

                if (var2) {
                    int variable2 = SonstMeth.glVertZwischen(
                            SonstMeth.minVar(this.modus),
                            SonstMeth.maxVar(this.modus),
                            this.rand);
                   
                    string2 = " "
                        + fmg.fmg8.endlAutomat.Konstanten.EING + " "
                        + fmg.fmg8.sonstiges.SonstMeth.normZahl(variable2);
                } else {
                    int nummer2 = this.rand.nextInt(255) + 1;
                    string2 = fmg.fmg8.sonstiges.SonstMeth.normZahl(nummer2);
                }

                neuString = aktString.substring(0, pos - 1)
                            + string1
                            + " " + fmg.fmg8.endlAutomat.Konstanten.GL + " "
                            + string2
                            + aktString.substring(pos + 2);
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.GL) {
                if (links) {
                    int lGrenze;
                    int rGrenze;
                    if (pos >= 6 && aktString.charAt(pos - 6)
                        == fmg.fmg8.endlAutomat.Konstanten.EING) {
                        lGrenze = pos - 7;
                    } else {
                        lGrenze = pos - 4;
                    }
                    if (aktString.charAt(pos + 3)
                            == fmg.fmg8.endlAutomat.Konstanten.EING) {
                            rGrenze = pos + 8;
                        } else {
                            rGrenze = pos + 5;
                    }
                    neuString = aktString.substring(0, lGrenze)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.FALSE + " "
                        + aktString.substring(rGrenze);
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.UNGF
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.UNGF) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.GL
                                + aktString.substring(pos + 1);
                } else {
                    if (oben) {
                        neuString = aktString.substring(0, pos)
                                    + fmg.fmg8.endlAutomat.Konstanten.KLGL
                                    + aktString.substring(pos + 1);
                    } else {
                        neuString = aktString.substring(0, pos)
                                    + fmg.fmg8.endlAutomat.Konstanten.GRGL
                                    + aktString.substring(pos + 1);
                    }
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.KLGL) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.UNGF
                                + aktString.substring(pos + 1);
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.KL
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.GRGL) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.UNGF
                                + aktString.substring(pos + 1);
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.GR
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.KL) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.KLGL
                                + aktString.substring(pos + 1);
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.NUNGF
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.GR) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.GRGL
                                + aktString.substring(pos + 1);
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.NUNGF
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos)
                    == fmg.fmg8.endlAutomat.Konstanten.NUNGF) {
                if (links) {
                    if (oben) {
                        neuString = aktString.substring(0, pos)
                                    + fmg.fmg8.endlAutomat.Konstanten.KL
                                    + aktString.substring(pos + 1);
                    } else {
                        neuString = aktString.substring(0, pos)
                                    + fmg.fmg8.endlAutomat.Konstanten.GR
                                    + aktString.substring(pos + 1);
                    }
                } else {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.UGL
                                + aktString.substring(pos + 1);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.UGL) {
                if (links) {
                    neuString = aktString.substring(0, pos)
                                + fmg.fmg8.endlAutomat.Konstanten.NUNGF
                                + aktString.substring(pos + 1);
                } else {
                    int lGrenze;
                    int rGrenze;
                    if (pos >= 6 && aktString.charAt(pos - 6)
                        == fmg.fmg8.endlAutomat.Konstanten.EING) {
                        lGrenze = pos - 7;
                    } else {
                        lGrenze = pos - 4;
                    }
                    if (aktString.charAt(pos + 3)
                            == fmg.fmg8.endlAutomat.Konstanten.EING) {
                            rGrenze = pos + 8;
                        } else {
                            rGrenze = pos + 5;
                    }
                    neuString = aktString.substring(0, lGrenze)
                        + " "
                        + fmg.fmg8.endlAutomat.Konstanten.TRUE
                        + " "
                        + aktString.substring(rGrenze);
                }
            }

            if (aktString.charAt(pos) == fmg.fmg8.endlAutomat.Konstanten.TRUE) {
                if (var1) {
                    int variable1 = SonstMeth.glVertZwischen(
                            SonstMeth.minVar(this.modus),
                            SonstMeth.maxVar(this.modus),
                            this.rand);
                   
                    string1 = " "
                        + fmg.fmg8.endlAutomat.Konstanten.EING
                        + " "
                        + fmg.fmg8.sonstiges.SonstMeth.normZahl(variable1);
                } else {
                    int nummer1 = this.rand.nextInt(255) + 1;
                    string1 = fmg.fmg8.sonstiges.SonstMeth.normZahl(nummer1);
                }

                if (var2) {
                    int variable2 = SonstMeth.glVertZwischen(
                            SonstMeth.minVar(this.modus),
                            SonstMeth.maxVar(this.modus),
                            this.rand);
                   
                    string2 = " "
                        + fmg.fmg8.endlAutomat.Konstanten.EING
                        + " "
                        + fmg.fmg8.sonstiges.SonstMeth.normZahl(variable2);
                } else {
                    int nummer2 = this.rand.nextInt(255) + 1;
                    string2 = fmg.fmg8.sonstiges.SonstMeth.normZahl(nummer2);
                }

                neuString = aktString.substring(0, pos - 1)
                            + string1
                            + " " + fmg.fmg8.endlAutomat.Konstanten.UGL + " "
                            + string2
                            + aktString.substring(pos + 2);
            }

            aktBed.setBedingung(neuString);
            return true;
        }
       
        return false;
    }

    /**
     * Gibt die Position einer zuf�lligen Folge von (zeichen1, zeichen2)
     * in einem String zur�ck. Falls keine solche Folge existiert,
     * wird -1 zur�ckgegeben. Der Index bezieht sich immer auf die MITTE
     * des ZWEITEN Zeichens (jedes Zeichen wird als 3 character kodiert).
     *
     * @param bedingung  Der zu durchsuchende String.
     * @param zeichen1   Das erste Zeichen der Folge.
     * @param zeichen2   Das zweite Zeichen der Folge.
     *
     * @return  Die Position einer zuf�lligen Zeichenfolge wie beschrieben
     *          im String.
     */
    private int indexZeichenfolge(final String bedingung,
                                  final char   zeichen1,
                                  final char   zeichen2) {
        int start = this.rand.nextInt(bedingung.length());
        int i;
        char lastTok;
       
        while (start % 3 != 1) {
            start = (start + 1) % bedingung.length();
        }
       
        i = (start + 3) % bedingung.length();
        lastTok = bedingung.charAt(start);
       
        while (i != start) {
            if (bedingung.charAt(i) == zeichen2                   
                && lastTok == zeichen1) {
                return i;
            }
           
            lastTok = bedingung.charAt(i);
            i = (i + 3) % bedingung.length();
        }
       
        return -1;
    }

    /**
     * Gibt die Position der zu pos geh�renden �ffnenden Klammer zur�ck.
     *
     * @param bed  Die zu durchsuchende Bedingung.
     * @param pos  Die Startposition.
     *
     * @return  Die Position der zu pos geh�renden �ffnenden Klammer. 0, falls
     *          keine existiert.
     */
    private int findeKlLinks(final String bed,
                             final int    pos) {
        int klammer = 0;
       
        if (pos < 0 || pos >= bed.length()) {
            return -1;
        }
       
        if (bed.charAt(pos) != fmg.fmg8.endlAutomat.Konstanten.KZ) {
            klammer = 1;
        }
       
        for (int i = pos; i >= 0; i--) {
            if (bed.charAt(i) == fmg.fmg8.endlAutomat.Konstanten.KZ) {
                klammer += 1;
            } else if (bed.charAt(i) == fmg.fmg8.endlAutomat.Konstanten.KA) {
                klammer -= 1;
            }
           
            if (klammer == 0) {
                return i;
            }
        }
       
        return 0;
    }
   
    /**
     * Gibt die Position der zu pos geh�renden schlie�enden Klammer zur�ck.
     *
     * @param bed  Die zu durchsuchende Bedingung.
     * @param pos  Die Startposition.
     *
     * @return  Die Position der zu pos geh�renden schlie�enden Klammer.
     *          "lastIndex", falls keine existiert.
     */
    private int findeKlRechts(final String bed,
                              final int    pos) {
        int klammer = 0;
       
        if (pos < 0 || pos >= bed.length()) {
            return -1;
        }
       
        if (bed.charAt(pos) != fmg.fmg8.endlAutomat.Konstanten.KA) {
            klammer = 1;
        }
       
        for (int i = pos; i < bed.length(); i++) {
            if (bed.charAt(i) == fmg.fmg8.endlAutomat.Konstanten.KA) {
                klammer += 1;
            } else if (bed.charAt(i) == fmg.fmg8.endlAutomat.Konstanten.KZ) {
                klammer -= 1;
            }
           
            if (klammer == 0) {
                return i;
            }
        }
       
        return bed.length() - 1;
    }

    /**
     * Mutiert eine zuf�llige Bedingung nach dem folgenden Muster:
     * (A AND true)  > A     < (true AND A)
     * (A OR true)   > true  < (true OR A)
     * (A AND false) > false < (false AND A)
     * (A OR false)  > A     < (false OR A)
     * Falls keine mutierbare Bedingung existiert, bleibt der Automat
     * unver�ndert.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Bedingung mutiert wurde.
     */
    public final boolean mutationBedBeinfacher(final EndlicherAutomat ea) {
        ArrayList<Transition> bedingungen = ea.getBedListe();
        Transition aktBed;
        String aktString;
        String neuString;
        int posLKlammer;
        int posRKlammer;
        int pos;
        int zufallsindex;
       
        while (bedingungen.size() > 0) {
            zufallsindex = rand.nextInt(bedingungen.size());
            aktBed = (Transition) bedingungen.get(zufallsindex);
            aktString = aktBed.getCond().formatted();
           
            pos = this.indexZeichenfolge(aktString,
                                         fmg.fmg8.endlAutomat.Konstanten.UND,
                                         fmg.fmg8.endlAutomat.Konstanten.TRUE);
           
            if (pos < 0) {
                pos = this.indexZeichenfolge(
                        aktString,
                        fmg.fmg8.endlAutomat.Konstanten.ODER,
                        fmg.fmg8.endlAutomat.Konstanten.FALSE);
            }
           
            if (pos >= 0) {
                posLKlammer = this.findeKlLinks(aktString, pos);
                posRKlammer = pos + 3;
                neuString = aktString.substring(0, posLKlammer - 1)
                            + aktString.substring(posLKlammer + 2,
                                                  pos - 4)
                            + aktString.substring(posRKlammer + 2);
                aktBed.setBedingung(neuString);
                return true;
            }
           
            pos = this.indexZeichenfolge(
                    aktString,
                    fmg.fmg8.endlAutomat.Konstanten.TRUE,
                    fmg.fmg8.endlAutomat.Konstanten.UND);

            if (pos < 0) {
                pos = this.indexZeichenfolge(
                        aktString,
                        fmg.fmg8.endlAutomat.Konstanten.FALSE,
                        fmg.fmg8.endlAutomat.Konstanten.ODER);
            }

            if (pos >= 0) {
                posLKlammer = pos - 3;
                posRKlammer = this.findeKlRechts(aktString, pos);
                neuString = aktString.substring(0, pos - 7)
                            + aktString.substring(pos + 2,
                                                  posRKlammer - 1)
                            + aktString.substring(posRKlammer + 2);
                aktBed.setBedingung(neuString);
                return true;
            }
           
            pos = this.indexZeichenfolge(aktString,
                                         fmg.fmg8.endlAutomat.Konstanten.ODER,
                                         fmg.fmg8.endlAutomat.Konstanten.TRUE);
            if (pos < 0) {
                pos = this.indexZeichenfolge(aktString,
                        fmg.fmg8.endlAutomat.Konstanten.UND,
                        fmg.fmg8.endlAutomat.Konstanten.FALSE);
            }
           
            if (pos >= 0) {
                posLKlammer = this.findeKlLinks(aktString, pos);
                posRKlammer = pos + 3;
                neuString = aktString.substring(0, posLKlammer - 1)
                            + aktString.substring(pos - 1, pos + 2)
                            + aktString.substring(posRKlammer + 2);
                aktBed.setBedingung(neuString);
                return true;
            }

            pos = this.indexZeichenfolge(aktString,
                                         fmg.fmg8.endlAutomat.Konstanten.TRUE,
                                         fmg.fmg8.endlAutomat.Konstanten.ODER);
            if (pos < 0) {
                pos = this.indexZeichenfolge(aktString,
                        fmg.fmg8.endlAutomat.Konstanten.FALSE,
                        fmg.fmg8.endlAutomat.Konstanten.UND);
            }

            if (pos >= 0) {
                posLKlammer = pos - 6;
                posRKlammer = this.findeKlRechts(aktString, pos);
                neuString = aktString.substring(0, posLKlammer - 1)
                            + aktString.substring(pos - 4, pos - 1)
                            + aktString.substring(posRKlammer + 2);
                aktBed.setBedingung(neuString);
                return true;
            }
           
            bedingungen.remove(zufallsindex);
        }
       
        return false;
    }
    /**
     * Gibt zuf�llig eine Position zur�ck, an der eines der �bergebenen Zeichen
     * ist. Falls keine solche Position existiert, wird -1 zur�cgegeben.
     *
     * @param bedingung  Der zu durchsuchende String.
     * @param zeichen    Liste der Zeichen, deren Position gesucht werden soll.
     *
     * @return  Die Position eines zuf�lligen Zeichens wie beschrieben
     *          im String oder -1.
     */
    private int indexZeichen(final String          bedingung,
                             final List<Character> zeichen) {
        int start = this.rand.nextInt(bedingung.length());
        int i;
       
        while (start % 3 != 1) {
            start = (start + 1) % bedingung.length();
        }
       
        i = (start + 3) % bedingung.length();
       
        while (i != start) {
            if (zeichen.contains(new Character(bedingung.charAt(i)))) {
                return i;
            }
           
            i = (i + 3) % bedingung.length();
        }

        if (zeichen.contains(new Character(bedingung.charAt(i)))) {
            return i;
        }

        return -1;
    }

    /**
     * Mutiert eine zuf�llige Bedingung nach dem folgenden Muster:
     * (A AND true)  < A > (true AND A)
     * (A OR false)  < A > (false OR A)
     * Falls keine Bedingung existiert, bleibt der Automat unver�ndert.
     *
     * SYNTAKTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Bedingung mutiert wurde.
     */
    public final boolean mutationBedkomplexer(final EndlicherAutomat ea) {
        // Sei & e {UND, ODER}
        // Fall 1: Bed = A => Bed2 = (t & A)
        // Fall 2: Bed = (... (A & B) ...) => Bed2 = (... ((t & A) & B) ...)
        // Fall 3: Bed = (... (A & B) ...) => Bed2 = (... (A & (t & B)) ...)
        // 1. Suche pos mit BED[pos] = UND oder BED[pos] = ODER.
        // 2. Falls so ein pos ex.: zuf�llig Fall 2 oder Fall 3.
        //    Sonst: Fall 1.
       
        ArrayList<Transition> bedingungen = ea.getBedListe();
        Transition aktBed;
        String aktString;
        String neuString = "";
        int posLKlammer;
        int posRKlammer;
        int pos;
        int zufallsindex;
        ArrayList<Character> zeichen = new ArrayList<Character>(2);
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.UND));
        zeichen.add(new Character(fmg.fmg8.endlAutomat.Konstanten.ODER));
        boolean und = this.rand.nextBoolean();
        boolean fallZwei = this.rand.nextBoolean();
        boolean erzwingeFall1 = this.rand.nextInt(5) == 0;
       
        if (bedingungen.size() > 0) {
            zufallsindex = this.rand.nextInt(bedingungen.size());
           
            aktBed = (Transition) bedingungen.get(zufallsindex);
            aktString = aktBed.getCond().formatted();

            pos = this.indexZeichen(aktString,
                                    zeichen);
            if (pos < 0 || erzwingeFall1) {
                // Fall 1
                if (und) {
                    neuString = " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.TRUE + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.UND + " "
                        + aktString
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " ";
                } else {
                    neuString =
                        " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.FALSE + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.ODER + " "
                        + aktString
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " ";
                }
               
            } else {
                // Fall 2 oder 3
                posLKlammer = this.findeKlLinks(aktString, pos);
                posRKlammer = this.findeKlRechts(aktString, pos);
                if (fallZwei && und) {
                    neuString = aktString.substring(0, posLKlammer + 2)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.TRUE + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.UND + " "
                        + aktString.substring(
                                posLKlammer + 2,
                                pos - 1)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " "
                        + aktString.substring(pos - 1);
                }

                if (fallZwei && !und) {
                    neuString = aktString.substring(0, posLKlammer + 2)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.FALSE + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.ODER + " "
                        + aktString.substring(
                                posLKlammer + 2,
                                pos - 1)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " "
                        + aktString.substring(pos - 1);
                }
               
                if (!fallZwei && und) {
                    neuString =
                        aktString.substring(0, pos + 2)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                        + aktString.substring(
                                pos + 2,
                                posRKlammer - 1)
                        + " " + fmg.fmg8.endlAutomat.Konstanten.UND + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.TRUE + " "
                        + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " "
                        + aktString.substring(posRKlammer - 1);
                }

                if (!fallZwei && !und) {
                    neuString = aktString.substring(0, pos + 2)
                    + " " + fmg.fmg8.endlAutomat.Konstanten.KA + " "
                    + aktString.substring(
                            pos + 2,
                            posRKlammer - 1)
                    + " " + fmg.fmg8.endlAutomat.Konstanten.ODER + " "
                    + " " + fmg.fmg8.endlAutomat.Konstanten.FALSE + " "
                    + " " + fmg.fmg8.endlAutomat.Konstanten.KZ + " "
                    + aktString.substring(posRKlammer - 1);
                }
            }

            aktBed.setBedingung(neuString);
           
            return true;
        }
       
        return false;
    }

    /**
     * Gibt die Position einer zuf�lligen Zahl in der Bedingung zur�ck.
     * (Gemeint sind konstante Byte-Werte). Falls keine Zahl existiert,
     * wird -1 zur�ckgegeben. Der Index bezieht sich immer auf die MITTE
     * einer 3-stelligen Zahl. (Jedes Zeichen wird als 3 character kodiert.)
     *
     * @param bedingung  Die zu durchsuchende Bedingung.
     *
     * @return  Die Position einer zuf�lligen Byte-Konstante im String.
     */
    private int indexZahl(final String bedingung) {
        int start = this.rand.nextInt(bedingung.length());
        int i;
        char lastTok;
       
        while (start % 3 != 1) {
            start = (start + 1) % bedingung.length();
        }
       
        i = (start + 3) % bedingung.length();
        lastTok = bedingung.charAt(start);
       
        while (i != start) {
            if (SonstMeth.istZiff(bedingung.charAt(i))
                && lastTok != fmg.fmg8.endlAutomat.Konstanten.EING) {
                return i;
            }
           
            lastTok = bedingung.charAt(i);
            i = (i + 3) % bedingung.length();
        }

        if (SonstMeth.istZiff(bedingung.charAt(i))
                && lastTok != fmg.fmg8.endlAutomat.Konstanten.EING) {
                return i;
        }

        return -1;
    }

    /**
     * Gibt die Position einer zuf�lligen SensorVar in der Bedingung zur�ck.
     * Falls keine SensorVar existiert,
     * wird -1 zur�ckgegeben. Der Index bezieht sich immer auf die MITTE
     * der 3-stelligen Sensor-Nummer. (Jedes Zeichen wird als 3 character
     * kodiert.)
     *
     * @param bedingung  Die zu durchsuchende Bedingung.
     *
     * @return  Die Position einer zuf�lligen SensorVar im String.
     */
    private int indexSensVar(final String bedingung) {
        int start = this.rand.nextInt(bedingung.length());
        int i;
        char lastTok;
       
        while (start % 3 != 1) {
            start = (start + 1) % bedingung.length();
        }
       
        i = (start + 3) % bedingung.length();
        lastTok = bedingung.charAt(start);
       
        while (i != start) {
            if (SonstMeth.istZiff(bedingung.charAt(i))
                && lastTok == fmg.fmg8.endlAutomat.Konstanten.EING) {
                return i;
            }
           
            lastTok = bedingung.charAt(i);
            i = (i + 3) % bedingung.length();
        }

        if (SonstMeth.istZiff(bedingung.charAt(i))
            && lastTok == fmg.fmg8.endlAutomat.Konstanten.EING) {
            return i;
        }

        return -1;
    }

    /**
     * Mutiert eine zuf�llige Zahl in einer zuf�lligen Bedingung.
     * Falls keine solche Zahl existiert, bleibt der Automat unver�ndert.
     *
     * SEMANTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Bedingung mutiert wurde.
     */
    public final boolean mutationBedZahl(final EndlicherAutomat ea) {
        ArrayList<Transition> bedingungen = ea.getBedListe();
        int zufallsIndex;
        Transition zufallsBed;
        String bedString;
        int alt;
        int neu;
        String neuS;
        int pos;
       
        while (bedingungen.size() > 0) {
            zufallsIndex = this.rand.nextInt(bedingungen.size());
            zufallsBed = (Transition) bedingungen.get(zufallsIndex);
            bedString = zufallsBed.getCond().formatted();
            pos = this.indexZahl(bedString);
           
            if (pos >= 0) {
                alt = Integer.parseInt(bedString.substring(pos - 1, pos + 2));
                neu = alt + (this.rand.nextInt(2 * this.k)) - this.k;
                if (neu < 1) {
                    neu = 1;
                }
                if (neu > 255) {
                    neu = 255;
                }

                neuS = bedString.substring(0, pos - 1)
                       + SonstMeth.normZahl(neu)
                       + bedString.substring(pos + 2);

                zufallsBed.setBedingung(neuS);
               
                return true;
            }
            bedingungen.remove(zufallsIndex);
        }
        return false;
    }

    /**
     * Mutiert eine zuf�llige Sensorvariable in einer zuf�lligen Bedingung.
     * Falls keine solche Sensorvariable existiert, bleibt der Automat
     * unver�ndert.
     *
     * SEMANTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob eine Bedingung mutiert wurde.
     */
    public final boolean mutationBedSensVar(final EndlicherAutomat ea) {
        ArrayList<Transition> bedingungen = ea.getBedListe();
        int zufallsIndex;
        Transition zufallsBed;
        String bedString;
        int neu;
        String neuS;
        int pos;
       
        while (bedingungen.size() > 0) {
            zufallsIndex = this.rand.nextInt(bedingungen.size());
            zufallsBed = (Transition) bedingungen.get(zufallsIndex);
            bedString = zufallsBed.getCond().formatted();
            pos = this.indexSensVar(bedString);
           
            if (pos >= 0) {
                neu = SonstMeth.glVertZwischen(
                        SonstMeth.minVar(this.modus),
                        SonstMeth.maxVar(this.modus),
                        this.rand);

                neuS = bedString.substring(0, pos - 1)
                       + SonstMeth.normZahl(neu)
                       + bedString.substring(pos + 2);

                zufallsBed.setBedingung(neuS);
               
                return true;
            }
            bedingungen.remove(zufallsIndex);
        }
        return false;
    }

    /**
     * Mutiert Parameter und evtl. Befehl eines zuf�lligen Zustands, falls
     * mindestens ein Zustand im Automaten existiert.
     *
     * SEMANTISCH
     *
     * @param ea  Der zu mutierende Automat.
     * @return  Ob ein Zustand mutiert wurde.
     */
    public final boolean mutationZustand(final EndlicherAutomat ea) {
        ArrayList<Integer> knListe = ea.getKnList();
        Knoten zufallsKnoten1;
        int veraenderung;
        int neuParam;
        int altParam;
        int neuBefehl;
        int zufallsIndex;
       
        if (knListe.size() == 0) {
            return false;
        } else {
            zufallsIndex = this.rand.nextInt(knListe.size());
            zufallsKnoten1 = (Knoten) ea.holeKnoten(knListe.get(zufallsIndex));
            veraenderung = this.rand.nextInt(2 * this.k) - this.k;
            altParam = ((ZInfo)
                    zufallsKnoten1.getInfo()).getParam();
            if (veraenderung + altParam > 0) {
                neuParam = altParam + veraenderung;
                neuBefehl = ((ZInfo)
                        zufallsKnoten1.getInfo()).getAktion();
            } else if (veraenderung + altParam < 0) {
                neuParam = (veraenderung + altParam) * -1;
                neuBefehl = SonstMeth.glVertZwischen(
                        SonstMeth.minBef(this.modus),
                        SonstMeth.maxBef(this.modus),
                        this.rand);
               
            } else { // veraenderung + altparam == 0
                neuParam = 1;
                neuBefehl = ((ZInfo)
                        zufallsKnoten1.getInfo()).getAktion();
            }
               
           
            ((ZInfo) zufallsKnoten1.getInfo()).setAkt(neuBefehl);
            ((ZInfo) zufallsKnoten1.getInfo()).setPar(neuParam);
           
            return true;
        }
    }

    /**
     * Die toString-Methode.
     *
     * @return  String.
     */
    @Override
    public String toString() {
        return "Mutationsart1";
    }

    /**
     * @return  Der Zufallsgenerator.
     */
    public Random getRand() {
        return this.rand;
    }

    /**
     * Mutiert die �bergebene Bedingung.
     *
     * @param cond  Die zu mutierende Bedingung.
     *
     * @return  Die mutierte Bedingung.
     */
    @Override
    public Condition mutiere(final Condition cond) {
        EndlicherAutomat aut = new EndlicherAutomat();
        Long[] intObj = new Long[5];
        ArrayList<Long> vert = new ArrayList<Long>(5);
       
        aut.einfuegenKnoten(1, 1, 1, 1);
        aut.einfuegKante(1, 1, cond, 1);

       
        for (int i = 0; i < intObj.length; i++) {
            intObj[i] = new Long(i);
        }
       
        vert.add(new Long(10)); // 0 : mutationBedA
        vert.add(new Long(9)); //  1 : mutationBedBeinfacher
        vert.add(new Long(3)); //  2 : mutationBedZahl
        vert.add(new Long(6)); //  3 : mutationBedkomplexer
        vert.add(new Long(1)); //  4 : mutationBedSensVar
       
        Long rnd = (Long) MathMeth.randVerteilung(
                intObj,
                vert,
                this.getRand());
       
        switch(rnd.intValue()) {
        case 0:
            this.mutationBedA(aut);
            break;
        case 1:
            this.mutationBedBeinfacher(aut);
            break;
        case 2:
            this.mutationBedZahl(aut);
            break;
        case 3:
            this.mutationBedkomplexer(aut);
            break;
        case 4:
            this.mutationBedSensVar(aut);
            break;
        default:
            break;
        }

        return aut.holeKnoten(1).getInfo().getBedingungen().get(0).getCond();
    }
   
    /**
     * Mutiert den aktiven Verhaltensautomaten des �bergebenen Roboters.
     * ACHTUNG: BISHER NUR VERHALTENSAUTOMAT!
     *
     * @param rob  Der zu mutierende Roboter.
     *
     * @return  Ob der Automat mutiert wurde.
     */
    public final boolean mutiere(final Roboter rob) {
        Long[] intObj = new Long[11];
        ArrayList<Long> vert = new ArrayList<Long>(11);
        boolean b;
       
        for (int i = 0; i < intObj.length; i++) {
            intObj[i] = new Long(i);
        }
       
        vert.add(new Long(10)); // 0 : mutationBedA
        vert.add(new Long(4)); //  1 : mutationBedBeinfacher
        vert.add(new Long(7)); //  2 : mutationFalseKanteRem
        vert.add(new Long(3)); //  3 : mutationZustandRem1
        vert.add(new Long(3)); //  4 : mutationZustandRem2
        vert.add(new Long(1)); //  5 : mutationZustand
        vert.add(new Long(3)); //  6 : mutationBedZahl
        vert.add(new Long(7)); //  7 : mutationFalseKanteEin
        vert.add(new Long(4)); //  8 : mutationZustandEin
        vert.add(new Long(6)); //  9 : mutationBedkomplexer
        vert.add(new Long(1)); //  10: mutationBedSensVar
       
        Long rnd = (Long) MathMeth.randVerteilung(intObj,
                                                  vert,
                                                  this.rand);

        int zufall = rnd.intValue();

        // Mutiere Verhaltensautomaten.
        switch(zufall) {
        case 0:
            b = this.mutationBedA(rob.getAktVAut());
            break;
        case 1:
            b = this.mutationBedBeinfacher(rob.getAktVAut());
            break;
        case 2:
            b = this.mutationFalseKanteRem(rob.getAktVAut());
            break;
        case 3:
            b = this.mutationZustandRem1(rob.getAktVAut());
            break;
        case 4:
            b = this.mutationZustandRem2(rob.getAktVAut());
            break;
        case 5:
            b = this.mutationZustand(rob.getAktVAut());
            break;
        case 6:
            b = this.mutationBedZahl(rob.getAktVAut());
            break;
        case 7:
            b = this.mutationFalseKanteEin(rob.getAktVAut());
            break;
        case 8:
            b = this.mutationZustandEin(rob.getAktVAut());
            break;
        case 9:
            b = this.mutationBedkomplexer(rob.getAktVAut());
            break;
        case 10:
            b = this.mutationBedSensVar(rob.getAktVAut());
            break;
        default:
            b = false;
        }

        // Setze Code des Verhaltensautomaten.
        if (b) {
            rob.setAktVCode(rob.getAktVAut().erzeugeSequenz());
        }

        return b;
    }
}
TOP

Related Classes of fmg.fmg8.endlAutomat.mutation.MutArt1VT

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.