Package fmg.fmg8.sonstiges

Source Code of fmg.fmg8.sonstiges.SonstMeth

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

package fmg.fmg8.sonstiges;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.imageio.ImageIO;


import fmg.fmg8.earleyErkenner.Konstanten;
import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.Transition;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.CompLeaf;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.conditions.ConstLeaf;
import fmg.fmg8.endlAutomat.conditions.InnerNode;
import fmg.fmg8.endlAutomat.script.Const;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.statistik.Aufnahme;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.statistik.PopSnapshot;
import fmg.fmg8.statistik.RobSnapshot;
import fmg.fmg8.statistik.logging.AbstractMsg;
import fmg.fmg8.statistik.logging.MsgDebug;
import fmg.fmg8.statistik.logging.MsgError;
import fmg.fmg8.statistik.logging.MsgInfo;
import fmg.fmg8.statistik.logging.MsgOutput;
import fmg.fmg8.statistik.logging.MsgStage1;
import fmg.fmg8.statistik.logging.MsgWarning;

/**
* Implementiert einige n�tzliche Methoden, die keiner anderen Klasse
* zugeordnet werden k�nnen.
*
* @author Lukas K�nig
*/
public final class SonstMeth {

    /**
     * Verhaltensautomaten-Modus.
     */
    public static final int MODUS_VERHALTEN = 0;
   
    /**
     * �bersetzermodus.
     */
    public static final int MODUS_TRANSLATOR = 1;

    /**
     * Log-Stufe Stage1.
     */
    public static final int LOG_STAGE1 = -1;
   
    /**
     * Log-Stufe Output.
     */
    public static final int LOG_OUTPUT = 0;
   
    /**
     * Log-Stufe Debug.
     */
    public static final int LOG_DEBUG = 1;
   
    /**
     * Log-Stufe Info.
     */
    public static final int LOG_INFO = 2;
   
    /**
     * Log-Stufe Warning.
     */
    public static final int LOG_WARNING = 3;
   
    /**
     * Log-Stufe Error.
     */
    public static final int LOG_ERROR = 4;
   
    /**
     * Der Zeichensatz zum Zeichnen des Inputfeldes.
     */
    public static final char[] ZEICHEN_INPUT = {
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 0-9
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 10-19
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 20-29
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 30-39
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 40-49
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 50-59
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 60-69
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 70-79
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 80-89
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 90-99
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 100-109
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 110-119
        ' ', ' ', '.', ' ', '�', ' ', ' ', ' ', '#', ' ', // 120-129
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 130-139
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 140-149
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 150-159
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 160-169
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 170-179
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 180-189
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 190-199
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 200-209
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 210-219
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 220-229
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 230-239
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 240-249
        ' ', ' ', ' ', ' ', ' ', ' '};                    // 250-255

    /**
     * Die Priorit�tenliste f�r die verschiedenen Farben des Inputfeldes.
     */
    public static final int[] PRIORITAET_INPUT = {128, 124, 122};

    /**
     * Der Zeichensatz zum Zeichnen des Inputfeldes.
     */
    public static final char[] ZEICHEN_FELD = {
        ' ', '�', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 0-9
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 10-19
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 20-29
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 30-39
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 40-49
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 50-59
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 60-69
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 70-79
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 80-89
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 90-99
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 100-109
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 110-119
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 120-129
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 130-139
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 140-149
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 150-159
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 160-169
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 170-179
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 180-189
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 190-199
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', '�', ' ', ' ', // 200-209
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 210-219
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 220-229
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 230-239
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 240-249
        ' ', ' ', ' ', ' ', '#', 'R'};                    // 250-255
   
    /**
     * Die Priorit�tenliste f�r die verschiedenen Farben des Inputfeldes.
     */
    public static final int[] PRIORITAET_FELD = {1, 255, 254, 207};
   
    /**
     * �berlagerung des Default-Konstruktors.
     */
    private SonstMeth() {
       
    }
   
    /**
     * Zerlegt einen String in Tokens, wobei <code>trenn</code>
     * als Trennsymbol verwendet wird. Am Beginn und am Ende des Strings
     * m�ssen (und d�rfen!) keine Trennsymbole stehen. Das Trennzeichen
     * darf leer sein (in diesem Ausnahmefall steht das Trennzeichen
     * doch am Anfang und gleichzeitig am Ende des Strings).
     * <P>
     * BSP1: zerlege("a/b/c/d", "/") => [a, b, c, d]
     * BSP2: zerlege("abcdefg", "")  => [a, b, c, d, e, f, g]
     * BSP3: zerlege("a-+-b-+-c-+-d, "-+-") => [a, b, c, d]
     *
     * @param text   Die zu zerlegende Sequenz.
     * @param trenn  Die Trennsequenz.
     *
     * @return  Die Zerlegung in einer <code>ArrayList</code>.
     */
    public static ArrayList<String> zerlege(final String text,
                                    final String trenn) {
        ArrayList<String> seq = new ArrayList<String>();
        int end = 0;
        int anf = 0;
        int trennLen = trenn.length();

        while (end < text.length()) {
            while (end + trennLen < text.length()
                   && !text.substring(end, end + trennLen).equals(trenn)) {
                end++;
            }
            if (end + trennLen >= text.length()) {
                end = end + trennLen;
            }
            if (anf != 0) {
                anf = anf + trennLen;
            }
            if (trennLen == 0 && anf == 0) {
                end++;
            }
            if (text.substring(anf, end).equals(Konstanten.EPSILON)) {
                end = end + 0;
            } else {
                seq.add(text.substring(anf, end));
            }
            anf = end;
            end++;
        }
        if (trenn.equals("") && text.length() > 1) {
            seq.add(text.substring(anf, text.length()));
        }

        return seq;
    }

    /**
     * Erzeugt eine Liste aus Zahlen aus einer bereinigten Stringsequenz.
     *
     * @param seq  Die bereinigte Stringsequenz.
     *
     * @return  Die Liste aus Zahlen.
     */
    public static LinkedList<Integer> listSeqAusString(final String seq) {
        ArrayList<String> zerlegt;
        LinkedList<Integer> liste = new LinkedList<Integer>();
       
        if (seq.equals("")) {
            return liste;
        }
       
        zerlegt = SonstMeth.zerlege(seq.substring(1), " ");
       
        for (int i = 0; i < zerlegt.size(); i++) {
            liste.add(Integer.parseInt(zerlegt.get(i)));
        }
       
        return liste;
    }

    /**
     * Erzeugt eine Liste aus Zahlenlisten aus einer Liste bereinigter
     * Stringsequenzen.
     *
     * @param seq  Die bereinigten Stringsequenzen.
     *
     * @return  Die Listen aus Zahlen.
     */
    @SuppressWarnings(value = { "unchecked" })
    public static LinkedList<Integer>[] listSeqAusStrings(final String[] seq) {
        LinkedList<Integer>[] listen = new LinkedList[seq.length];
       
        for (int i = 0; i < seq.length; i++) {
            listen[i] = SonstMeth.listSeqAusString(seq[i]);
        }
       
        return listen;
    }

    /**
     * Erzeugt eine bereinigte Stringsequenz aus einer Liste von Zahlen.
     *
     * @param seq  Liste von Zahlen.
     *
     * @return  Die bereinigte Stringsequenz.
     */
    public static String stringAusListSeq(final LinkedList<Integer> seq) {
        EndlicherAutomat ea = new EndlicherAutomat();
       
        return ea.bereinige(ea.ausgabe(seq));
    }

    /**
     * Erzeugt eine Liste bereinigter Stringsequenzen aus einer Liste von
     * Zahlen-Listen.
     *
     * @param seqs  Liste von Zahlen-Listen.
     *
     * @return  Die bereinigte Stringsequenz.
     */
    public static String[] stringAusListSeqs(
            final LinkedList<Integer>[] seqs) {
        String[] codes = new String[seqs.length];
       
        for (int i = 0; i < seqs.length; i++) {
            codes[i] = SonstMeth.stringAusListSeq(seqs[i]);
        }
       
        return codes;
    }

    /**
     * Klont ein beliebiges (serialisierbares) Objekt.
     *
     * @param o  Das zu klonende Objekt.
     *
     * @return  Das geklonte Objekt.
     */
    public static Object seriaClone(final Object o) {
        try {
        //Serialisieren des Objekts
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream os = new ObjectOutputStream(out);
        os.writeObject(o);
        os.flush();
        //Deserialisieren des Objekts
        ByteArrayInputStream in = new ByteArrayInputStream(
            out.toByteArray()
        );
        ObjectInputStream is = new ObjectInputStream(in);
        Object ret = is.readObject();
        is.close();
        os.close();
        return ret;
        } catch (Exception e) {
            StackTraceElement[] s = e.getStackTrace();
            System.out.println("Objekt nicht serialisierbar:\n" + o);
            System.out.println(e);
            for (int i = 0; i < s.length; i++) {
                System.out.println(s[i].getClassName()
                                   + ": "
                                   + s[i].getMethodName()
                                   + ": "
                                   + s[i].getLineNumber());
            }

            return null;
        }
    }

    /**
     * Erzeugt eine normierte Byte-Zahl aus einem Integer. Der Integer muss
     * einen Byte-Wert speichern. Die Ausgabe ist ein String der L�nge drei,
     * wobei bei Zahlen der L�nge < 3 vorne mit Nullen aufgef�llt wird.
     *
     * @param z  Die zu normierende Zahl als Integer.
     *
     * @return  Die normierte Zahl als String.
     */
    public static String normZahl(final int z) {
        final String zahl = "" + z;

        if (zahl.length() == 3) {
            return zahl;
        } else if (zahl.length() == 2) {
            return "0" + zahl;
        } else if (zahl.length() == 1) {
            return "00" + zahl;
        } else {
            throw new RuntimeException("Kein g�ltiger Bytewert.");
        }
    }

    /**
     * Testet, ob <code>c</code> eine Ziffer aus {0, ..., 9} ist.
     *
     * @param c  Der zutestende Character.
     *
     * @return  <code>true</code>, gdw. <code>c</code> eine Ziffer ist.
     */
    public static boolean istZiff(final char c) {
        return c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
               || c == '5' || c == '6' || c == '7' || c == '8' || c == '9';
    }

    /**
     * Gibt die (erste) Position eines Strings in einem Array zur�ck.
     * F�hrende 0'en und Gro�- Kleinschreibung werden ignoriert.
     *
     * @param strArray  Der Array, in dem der String gesucht werden soll.
     * @param str       Der String, der gesucht werden soll.
     *
     * @return  Die (erste) Position des Strings im Array. Falls der String
     *          nicht im Aray vorkommt, wird -1 zur�ckgegeben.
     */
    public static int posSuch(final String[] strArray,
                              final String   str) {
        boolean zahl = true;

        try {
            for (int i = 0; i < str.length(); i++) {
                if (!istZiff(str.charAt(i))) {
                    zahl = false;
                }
            }

            if (zahl) {
                return Integer.parseInt(str);
            }

            for (int i = 0; i < strArray.length; i++) {
                if ((strArray[i].toLowerCase()).equals(str.toLowerCase())) {
                    return i;
                }
            }

            return -1;
        } catch (NumberFormatException e) {
            return -1;
        }
    }

    /**
     * Gibt zur�ck, ob zwei Zahlen "ungef�hr" gleich sind. Die maximale
     * Unterscheidung zwischen ihnen wird auch �bergeben.
     *
     * @param a    Die erste der zu vergleichenden Zahlen.
     * @param b    Die zweite der zu vergleichenden Zahlen.
     * @param max  Die maximale Unterscheidung.
     *
     * @return  Ob "a ~ b".
     */
    public static boolean ungefGleich(final int a,
                                   final int b,
                                   final int max) {
        return Math.abs(a - b) <= max;
    }

    /**
     * Testet, ob ein Zeichen ein Sonderzeichen aus den in der Klasse
     * Konstanten definierten Zeichen ist.
     *
     * @param c  Das zu testende Zeichen.
     *
     * @return  <code>true</code>, gdw. das Zeichen ein Sonderzeichen ist.
     */
    public static boolean istSonderzeichen(final char c) {
        return c == fmg.fmg8.endlAutomat.Konstanten.EING   
               || c == fmg.fmg8.endlAutomat.Konstanten.FALSE
               || c == fmg.fmg8.endlAutomat.Konstanten.GL  
               || c == fmg.fmg8.endlAutomat.Konstanten.GR
               || c == fmg.fmg8.endlAutomat.Konstanten.GRGL
               || c == fmg.fmg8.endlAutomat.Konstanten.KA
               || c == fmg.fmg8.endlAutomat.Konstanten.KL  
               || c == fmg.fmg8.endlAutomat.Konstanten.KLGL
               || c == fmg.fmg8.endlAutomat.Konstanten.KZ  
               || c == fmg.fmg8.endlAutomat.Konstanten.ODER
               || c == fmg.fmg8.endlAutomat.Konstanten.TRUE
               || c == fmg.fmg8.endlAutomat.Konstanten.UGL
               || c == fmg.fmg8.endlAutomat.Konstanten.UND 
               || c == fmg.fmg8.endlAutomat.Konstanten.UNGF
               || c == fmg.fmg8.endlAutomat.Konstanten.NUNGF;
    }

    /**
     * Testet, ob ein Zeichen ein Operator ist.
     *
     * @param c  Das zu �berpr�fende Zeichen.
     *
     * @return  Ob c ein Operator ist.
     */
    public static boolean istOper(final char c) {
        return
        c == fmg.fmg8.endlAutomat.Konstanten.GL
        || c == fmg.fmg8.endlAutomat.Konstanten.GR
        || c == fmg.fmg8.endlAutomat.Konstanten.GRGL
        || c == fmg.fmg8.endlAutomat.Konstanten.UNGF
        || c == fmg.fmg8.endlAutomat.Konstanten.KL
        || c == fmg.fmg8.endlAutomat.Konstanten.KLGL
        || c == fmg.fmg8.endlAutomat.Konstanten.ODER
        || c == fmg.fmg8.endlAutomat.Konstanten.NUNGF
        || c == fmg.fmg8.endlAutomat.Konstanten.UGL
        || c == fmg.fmg8.endlAutomat.Konstanten.UND;
    }

    /**
     * Testet, ob ein Zeichen ein Operator ist.
     *
     * @param c  Das zu �berpr�fende Zeichen.
     *
     * @return  Ob c ein Operator ist.
     */
    public static boolean istOperator(final int c) {
        return
        c == fmg.fmg8.endlAutomat.Konstanten.GL_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.GR_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.GRGL_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.UNGF_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.KL_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.KLGL_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.ODER_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.NUNGF_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.UGL_CODE
        || c == fmg.fmg8.endlAutomat.Konstanten.UND_CODE;
    }

    /**
     * Testet, ob ein Zeichen ein boolescher Operator ist.
     *
     * @param c  Das zu �berpr�fende Zeichen.
     *
     * @return  Ob c ein boolescher Operator ist.
     */
    public static boolean istBoolOperator(final int c) {
        return c == fmg.fmg8.endlAutomat.Konstanten.UND
               || c == fmg.fmg8.endlAutomat.Konstanten.ODER;
    }

    /**
     * Erzeugt eine <code>Condition</code> aus einer Text-Bedingung, die
     * nicht formatiert sein muss.
     *
     * @param bedingung  Die (m�glicherweise unformatierte) Bedingung.
     *
     * @return  Die Condition.
     */
    public static Condition ausBed(final String bedingung) {
        return ausFormatBed(EndlicherAutomat.formatBed(bedingung));
    }
   
    /**
     * Erzeugt eine <code>Condition</code> aus einer Text-Bedingung.
     * <P>
     * Kommentar: Beizeiten verbessern - l�uft bisher mit quadratischer
     *            Laufzeit in der Anzahl der Operatoren.
     *            => Verbesserung durch Umwandeln in Postfix.
     *           
     * @param bedingung  Die Textbedingung.
     *
     * @return  Die <code>Condition</code>.
     */
    public static Condition ausFormatBed(final String bedingung) {
        int klammerAuf = 1;
       
        if (bedingung.length() == 3) {
            if (bedingung.charAt(1)
                == fmg.fmg8.endlAutomat.Konstanten.TRUE) {
                return new ConstLeaf(true);
            } else if (bedingung.charAt(1)
                       == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
                return new ConstLeaf(false);
            }
        }
       
        if (bedingung.charAt(1) != fmg.fmg8.endlAutomat.Konstanten.KA) {
            int op1;
            int op2;
            boolean sens1;
            boolean sens2;
            char op;
            int i = 4;
           
            if (bedingung.charAt(1) == fmg.fmg8.endlAutomat.Konstanten.EING) {
                sens1 = true;
                op1 = Integer.parseInt(bedingung.substring(3, 6));
            } else {
                sens1 = false;
                op1 = Integer.parseInt(bedingung.substring(0, 3));
            }
           
            while (!SonstMeth.istOper(bedingung.charAt(i))) {
                i++;
            }
           
            op = bedingung.charAt(i);
           
            if (bedingung.charAt(i + 3)
                    == fmg.fmg8.endlAutomat.Konstanten.EING) {
                sens2 = true;
                op2 = Integer.parseInt(bedingung.substring(i + 5, i + 8));
            } else {
                sens2 = false;
                op2 = Integer.parseInt(bedingung.substring(i + 2, i + 5));
            }
           
            return new CompLeaf(op1, op2, sens1, sens2, op);
        }
       
        for (int i = 4; i < bedingung.length(); i += 3) {
            if (bedingung.charAt(i) == fmg.fmg8.endlAutomat.Konstanten.KA) {
                klammerAuf++;
            } else if (bedingung.charAt(i)
                    == fmg.fmg8.endlAutomat.Konstanten.KZ) {
                klammerAuf--;
            } else if (klammerAuf == 1
                       && istBoolOperator(bedingung.charAt(i))) {
                return new InnerNode(ausFormatBed(bedingung.substring(3,
                                                                i - 1)),
                                     ausFormatBed(bedingung.substring(i + 2,
                                                     bedingung.length() - 3)),
                                     bedingung.charAt(i));
            }
        }
       
        throw new RuntimeException("Keine g�ltige Textbedingung.");
    }

    /**
     * Erzeugt einen Vektor aus <code>Condition</code>s aus einem Vektor aus
     * Text-Bedingungen.
     *           
     * @param beds  Die Textbedingungen.
     *
     * @return  Die <code>Condition</code>s.
     */
    public static Condition[] ausFormatBeds(final String[] beds) {
        Condition[] conds = new Condition[beds.length];
       
        for (int i = 0; i < beds.length; i++) {
            conds[i] = SonstMeth.ausFormatBed(beds[i]);
        }
       
        return conds;
    }

    /**
     * Erzeugt Conditions aus einer Liste von unformatierten Bedingungen.
     *
     * @param beds  Die Bedingungen.
     *
     * @return  Die Conditions.
     */
    public static Condition[] ausBeds(final String[] beds) {
        Condition[] conds = new Condition[beds.length];
       
        for (int i = 0; i < beds.length; i++) {
            conds[i] = SonstMeth.ausBed(beds[i]);
        }
       
        return conds;
    }

     /**
     * Erzeugt eine normalisierte Version der �bergebenen Zahl, die zwischen 0
     * und 255 liegen muss, nach folgendem Muster: Z => 00Z, ZZ => 0ZZ,
     * ZZZ => ZZZ (Z Platzhalter f�r 1 Ziffer).
     *
     * @param ii  Die zu normalisierende Zahl.
     * @return   Die normalisierte Zahl als String.
     */
    private static String normal(final int ii) {
        int i = ii;
        String s = "" + i;
  
        if (i < 0) {
            i = 0;
        }
        if (i > 255) {
            i = 255;
        }
  
        if (i < 100) {
            s = "0" + s;
        }
        if (i < 10) {
            s = "0" + s;
        }
           
        return s;
    }

    /**
     * L�st eine Bedingung mit den �bergebenen Sensordaten auf.
     *
     * @param bed       Die aufzul�sende Bedingung.
     * @param sensoren  Die Sensoren.
     *
     * @return  Ob die Bedingung erf�llt ist.
     */
    public static boolean loeseBed(final String bed,
                                    final int[]  sensoren) {
        String neuBed = "";
        int zwisch;
        int letztIndex = 0;
  
        for (int i = 0; i < bed.length(); i++) {
            if (bed.charAt(i) == 'h') {
                neuBed = neuBed + bed.substring(letztIndex, i - 1);
                zwisch = Integer.parseInt(bed.substring(i + 2, i + 5));
                neuBed = neuBed + normal(sensoren[zwisch - 1]);
                letztIndex = i + 5;
            }
        }
        neuBed = neuBed + bed.substring(letztIndex, bed.length());
        return loeseRek(neuBed);
    }
  
    /**
     * L�st eine Bedingung auf, die keine Sensor-Platzhalter mehr enth�lt.
     *
     * @param fBed  Eine finale Bedingung (ohne Sensorplatzhalter).
     *
     * @return  Ob die Bedingung erf�llt ist.
     */
    private static boolean loeseRek(final String fBed) {
        int simpZahl1;
        int simpZahl2;
        String linksI;
        String rechtsI;
        String neuBed;
        char neuWert;
        String vorKl;
        String nachKl;
  
        RuntimeException fehler = new RuntimeException("Fehler in einer"
                                                       + " Bedingung.");
        if (fBed.length() == 3) {
            if (fBed.charAt(1) == fmg.fmg8.endlAutomat.Konstanten.TRUE) {
                return true;
            } else if (fBed.charAt(1)
                    == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
                return false;
            } else {
                throw fehler;
            }
        } else if (fBed.length() == 9) {
            simpZahl1 = Integer.parseInt(fBed.substring(0, 3));
            simpZahl2 = Integer.parseInt(fBed.substring(6, fBed.length()));
            if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.GL) {
                return simpZahl1 == simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.GR) {
                return simpZahl1 > simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.GRGL) {
                return simpZahl1 >= simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.KL) {
                return simpZahl1 < simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.KLGL) {
                return simpZahl1 <= simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.UGL) {
                return simpZahl1 != simpZahl2;
            } else if (fBed.charAt(4) == fmg.fmg8.endlAutomat.Konstanten.UNGF) {
                return SonstMeth.ungefGleich(
                        simpZahl1,
                        simpZahl2,
                        fmg.fmg8.umgebung2D.Konstanten.UNGEF_KONST);
            } else if (fBed.charAt(4)
                    == fmg.fmg8.endlAutomat.Konstanten.NUNGF) {
                return !SonstMeth.ungefGleich(
                        simpZahl1,
                        simpZahl2,
                        fmg.fmg8.umgebung2D.Konstanten.UNGEF_KONST);
            } else {
                throw fehler;
            }
        } else {
            int a = 0// Innerste Klammer - Anfang.
            int e = 0// Innerste Klammer - Ende.
            int o = 0// Innerste Klammer - Operator.
            while (fBed.charAt(e) != fmg.fmg8.endlAutomat.Konstanten.KZ) {
                if (fBed.charAt(e) == fmg.fmg8.endlAutomat.Konstanten.KA) {
                    a = e;
                }
                if (fBed.charAt(e) == fmg.fmg8.endlAutomat.Konstanten.UND
                    || fBed.charAt(e) == fmg.fmg8.endlAutomat.Konstanten.ODER) {
                        o = e;
                }
                e++;
            }
            a = a + 2;
            e = e - 1;
  
            linksI = fBed.substring(a, o - 1);
            rechtsI = fBed.substring(o + 2, e);
            if (fBed.charAt(o) == fmg.fmg8.endlAutomat.Konstanten.UND) {
                if (loeseRek(linksI) && loeseRek(rechtsI)) {
                    neuWert = fmg.fmg8.endlAutomat.Konstanten.TRUE;
                } else {
                    neuWert = fmg.fmg8.endlAutomat.Konstanten.FALSE;
                }
            } else if (fBed.charAt(o) == fmg.fmg8.endlAutomat.Konstanten.ODER) {
                if (loeseRek(linksI) || loeseRek(rechtsI)) {
                    neuWert = fmg.fmg8.endlAutomat.Konstanten.TRUE;
                } else {
                    neuWert = fmg.fmg8.endlAutomat.Konstanten.FALSE;
                }
            } else {
                throw fehler;
            }
  
            vorKl = fBed.substring(0, a - 3);
            nachKl = fBed.substring(e + 3, fBed.length());
            neuBed = vorKl + " " + neuWert + " " + nachKl;
            return loeseRek(neuBed);
        }
    }

    /**
     * Schreibt einen Log-Eintrag in die Konsole (siehe �berladene Methode).
     * Der Zusatzparameter wird als "" �bergeben.
     *
     * @param stufe      Die Stufe des Logs.
     * @param s          Der auszugebende String.
     * @param params     Die Parameter.
     */
    public static void log(final int stufe,
                           final String s,
                           final Parametersatz params) {
        SonstMeth.log(stufe, s, params, "", null);
    }

    /**
     * Gibt eine als Message gegebene Nachricht aus, wobei der Zeitstempel mit
     * ausgegeben wird. Das Message-Objekt wird an die erzeugte
     * Ausgabenachricht angeh�ngt.
     *
     * @param msg     Die Nachricht.
     * @param params  Der Parametersatz.
     */
    public static void log(
            final AbstractMsg msg,
            final Parametersatz params) {
        SonstMeth.log(
                msg.getStufe(),
                "[Nachrichtenstempel: "
                    + msg.getDatum()
                    + "] "
                    + msg.getMessage(),
                params,
                "",
                msg);
    }
   
    /**
     * Schreibt einen Log-Eintrag in die Konsole.
     *
     * Die Stufen des Loggens:<BR>
     * 0: OUTPUT <BR>
     * 1: DEBUG <BR>
     * 2: INFO <BR>
     * 3: WARNING <BR>
     * 4: ERROR <BR>
     *
     * @param stufe      Die Stufe des Logs.
     * @param s          Der auszugebende String.
     * @param params     Die Parameter.
     * @param zusatzPar  Ein Zusatzparameter. Bisher definiert:
     *                   - "plain" => Ausgabe ohne Logstufe und newline.
     * @param zusatz     Ein zus�tzliches Objekt, das die Mitteilung genauer
     *                   spezifiziert.
     */
    public static void log(final int stufe,
                           final String s,
                           final Parametersatz params,
                           final String zusatzPar,
                           final Object zusatz) {
        int logParStufe;
        AbstractMsg msg = null;
       
        if (params != null) {
            logParStufe = params.getLogStufe().intValue();
        } else {
            logParStufe = 0;
        }
       
        if (stufe >= logParStufe) {
            if (!zusatzPar.toLowerCase().equals("plain")) {
                System.out.println();
                System.out.print(new Date() + " - ");
               
                if (stufe == SonstMeth.LOG_STAGE1) {
                    System.out.print("STAGE1: ");
                } else if (stufe == LOG_OUTPUT) {
                    System.out.print("OUTPUT: ");
                } else if (stufe == LOG_DEBUG) {
                    System.out.print("DEBUG : ");
                } else if (stufe == LOG_INFO) {
                    System.out.print("INFO  : ");
                } else if (stufe == LOG_WARNING) {
                    System.out.print("WARN  : ");
                } else if (stufe == LOG_ERROR) {
                    System.out.print("ERROR : ");
                } else {
                    System.out.print("[N.A.]: ");
                }
            }

            if (stufe == LOG_OUTPUT) {
                msg = new MsgOutput(s, System.currentTimeMillis(), zusatz);
            } else if (stufe == LOG_DEBUG) {
                msg = new MsgDebug(s, System.currentTimeMillis(), zusatz);
            } else if (stufe == LOG_INFO) {
                msg = new MsgInfo(s, System.currentTimeMillis(), zusatz);
            } else if (stufe == LOG_WARNING) {
                msg = new MsgWarning(s, System.currentTimeMillis(), zusatz);
            } else if (stufe == LOG_ERROR) {
                msg = new MsgError(s, System.currentTimeMillis(), zusatz);
            } else if (stufe == LOG_STAGE1) {
                msg = new MsgStage1(s, System.currentTimeMillis(), zusatz);
            }
           
            if (msg != null && params != null) {
                params.addMessage(msg);
            }

            System.out.print(s);
        }
    }
   
    /**
     * L�dt ein Bild und gibt es zur�ck.
     *
     * @param pars  Die Parameter.
     *
     * @return  Das Bild.
     */
    private static BufferedImage ladeBild(final Parametersatz pars) {
        File dat = new File(pars.getStdPfad()
                + File.separator
                + pars.getUmgebungDatname());
       
        try {
            BufferedImage image = ImageIO.read(dat);
            return image;
        } catch (IOException e) {
            StackTraceElement[] stack = e.getStackTrace();
            for (int i = 0; i < stack.length; i++) {
                SonstMeth.log(SonstMeth.LOG_DEBUG,
                              e.getStackTrace()[i].toString(),
                              pars);
            }
           
            SonstMeth.log(SonstMeth.LOG_ERROR,
                          "Bitmapdatei nicht geladen: " + dat,
                          pars);
           
            throw new RuntimeException("\nBitmapdatei nicht geladen.");
        }
    }
   
    /**
     * Liest eine Bitmapdatei in ein Array aus Pixelfarben.
     *
     * @param pars  Die Parameter.
     *
     * @return  2D-Array aus Pixelfarben.
     */
    public static byte[][] liesImage(final Parametersatz pars) {
        BufferedImage img = ladeBild(pars);
        byte[] a = new byte[1];
        byte[][] aa = new byte[img.getWidth()][img.getHeight()];

        for (int j = 0; j < aa[0].length; j++) {
            for (int i = 0; i < aa.length; i++) {
                img.getRaster().getDataElements(i, j, 1, 1, a);
                aa[i][j] = a[0];
            }
        }
           
        return aa;
    }

    /**
     * Extrahiert die Fitnesswerte der aktuellen Roboter.
     *
     * @param pops  Die Populationen.
     *
     * @return  Die extrahierten Fitnesswerte.
     */
    public static String extrahiereFit(final List<PopSnapshot> pops) {
        PopSnapshot pop;
        long popNummer;
        String sGes = "";
        Iterator<PopSnapshot> it = pops.iterator();
       
        // Erste Zeile.
        sGes = sGes + "SnapshotID";
       
        for (int i = 0;
             i < ((PopSnapshot) pops.get(0)).getRobSchnapp().length;
             i++) {
            sGes = sGes + ";Fitness (Roboter " + i + ")";
        }
        sGes = sGes + "\n";
       
        // Rest.
        while (it.hasNext()) {
            String s = "";
           
            pop = it.next();
            popNummer = pop.getId();
           
            s = s + popNummer;
               
            for (int i = 0; i < pop.getRobSchnapp().length; i++) {
                s = s
                    + ";"
                    + pop.getRobSchnapp()[i].getFitness()[0];
            }
           
            sGes = sGes + s + "\n";
        }

        return sGes;
    }
   
    /**
     * Speichert einen Text in eine Textdatei.
     *
     * @param verz     Das Verzeichnis.
     * @param datName  Die Datei.
     * @param text     Der zu speichernde Text.
     * @param params   Die Parameter.
     */
    public static void speichereTextDatei(final String verz,
                                          final String datName,
                                          final String text,
                                          final Parametersatz params) {
        FileWriter f1 = null;
       
        try {
            f1 = new FileWriter(verz + File.separator + datName);
            f1.write(text);
            f1.close();
        } catch (IOException e) {
            log(4,
                "Fehler beim Erstellen der Text-Datei: "
                    + f1.toString(),
                 params);
            throw new RuntimeException("Datei konnte nicht erstellt werden.");
        }
    }
   
    /**
     * Extrahiert die Fitness einer bestimmten Population aus einer Aufnahme.
     *
     * @param a       Die Aufnahme.
     * @param popNum  Die Nummer der Population.
     *
     * @return  Die Fitnesswerte der Roboter der Population als String.
     */
    public static String extrEinzelPopFitness(final Aufnahme a,
                                              final int      popNum) {
        String s = "";
        PopSnapshot p = (PopSnapshot) a.getPops().get(popNum);
        RobSnapshot[] robs = p.getRobSchnapp();
       
        for (int i = 0; i < robs.length; i++) {
            s = s + robs[i].getFitness();
            if (i < robs.length - 1) {
                s = s + "_";
            }
        }
       
        return s;
    }
   
    /**
     * Extrahiert alle Fitnesswerte aus allen Statistikdateien im angegebenen
     * Verzeichnis.
     *
     * @param verz    Das Verzeichnis, in dem sich die Statistiken befinden.
     * @param params  Die Parameter.
     */
    public static void extrahiereAlleFit(final String verz,
                                         final Parametersatz params) {
        File pfad = new File(verz);
        String endung = "gz";
        String[] gespGr = pfad.list(new DateiFilter(endung));
        Aufnahme aufn;
        String sGes;
       
        if (gespGr == null) {
            log(4, "Ungueltiges Verzeichnis: " + verz, params);
            throw new RuntimeException("Ung�ltiges Verzeichnis.\n" + verz);
        }

        for (int i = 0; i < gespGr.length; i++) {
            log(2,
                "Extrahiere Fitness ("
                    + verz
                    + File.separator
                    + gespGr[i]
                    + ").",
                params);
            try {
                aufn = new Aufnahme(verz + File.separator
                        + gespGr[i].substring(0, gespGr[i].length() - 3));
                sGes = extrahiereFit(aufn.getPops());
               
                speichereTextDatei(verz,
                                   "FIT-" + gespGr[i] + ".txt",
                                   sGes,
                                   params);

//              zusText = extrEinzelPopFitness(aufn,
//              aufn.getPops().size()
//                  - 1);
//                speichereTextDatei(verz,
//                                   "FIT-"
//                                       + gespGr[i]
//                                       + "["
//                                       + zusText
//                                       + "].txt",
//                                   sGes,
//                                   params);
            } catch (final Exception e) {
                log(3, "Fitnesswerte nicht extrahiert: " + gespGr[i], params);
            }
        }
    }

    /**
     * Bennent eine Datei um.
     *
     * @param quelle  Name der Quelldatei.
     * @param ziel    Name der Zieldatei.
     * @param params  Die Parameter.
     */
    public static void renameDAT(final String quelle,
                                 final String ziel,
                                 final Parametersatz params) {
        String pfad = params.getStdPfad();
        File quellDatei = new File(pfad + File.separator + quelle);
        File zielDatei = new File(pfad + File.separator + ziel);
        if (quellDatei.renameTo(zielDatei)) {
            return;
        } else {
            throw new RuntimeException("Datei konnte nicht umbenannt werden");
        }
    }
   
    /**
     * Bennent alle Dateien im Standardverzeichnis um. Dabei wird die
     * Dateinamenerweiterung von ext1 auf ext2 ge�ndert.
     *
     * @param ext1    Die Quelldateiendung.
     * @param ext2    Die Zieldateiendung.
     * @param params  Die Parameter
     */
    public static void renameALL(final String ext1,
                                 final String ext2,
                                 final Parametersatz params) {
        File pfad = new File(params.getStdPfad());
        String[] alleDat = pfad.list(new DateiFilter(ext1));
        String neuName;
       
        if (alleDat == null) {
            return;
        }
       
        for (int i = 0; i < alleDat.length; i++) {
            neuName = alleDat[i].substring(0,
                                           alleDat[i].length() - 4)
                                               + "." + ext2;
           
            renameDAT(alleDat[i], neuName, params);
        }
    }
   
    /**
     * L�scht den String mit dem angegebenen Namen.
     *
     * @param datNam  Der Dateiname.
     * @param params  Die Parameter.
     */
    public static void deleteDAT(final String datNam,
                                 final Parametersatz params) {
        File datei = new File(params.getStdPfad() + File.separator + datNam);
        if (datei.delete()) {
            return;
        } else {
            throw new RuntimeException("Datei konnte nicht gel�scht werden");
        }
    }
   
    /**
     * L�scht alle Dateien mit der angegebenen Erweiterung aus dem
     * Standardverzeichnis.
     *
     * @param ext     Die Erweiterung.
     * @param params  Die Parameter.
     */
    public static void deleteALL(final String ext,
                                 final Parametersatz params) {
        File pfad = new File(params.getStdPfad());
        String[] alleDat = pfad.list(new DateiFilter(ext));
       
        if (alleDat == null) {
            return;
        }

        for (int i = 0; i < alleDat.length; i++) {
            deleteDAT(alleDat[i], params);
        }
    }
   
    /**
     * Gibt zur�ck, ob ein Element in einem Array enthalten ist.
     *
     * @param array    Das Array, in dem das Element gesucht werden soll.
     * @param element  Das Element, das gesucht werden soll.
     *
     * @return  Ob das Element in dem Array enthalten ist.
     */
    public static boolean enthaelt(final int[] array,
                                   final int   element) {
        for (int i = 0; i < array.length; i++) {
            if (array[i] == element) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param feld     Das Feld.
     * @param x        X-Koordinate.
     * @param y        Y-Koordinate.
     * @param rasterX  Zugriffsraster.
     * @param rasterY  Zugriffsraster.
     * @param farben   Array, in dem die Farben zur�ckgegeben werden.
     *
     * @return  Die Verteilung der Farben im Feld.
     */
    private static long[] pixGes(final byte[][] feld,
                                 final int      x,
                                 final int      y,
                                 final int      rasterX,
                                 final int      rasterY,
                                 final long[]   farben) {
        int startX = x;
        int startY = y;
        int endeX = x + rasterX;
        int endeY = y + rasterY;
       
        for (int i = 0; i < farben.length; i++) {
            farben[i] = 0;
        }
       
        if (startX < 0) {
            startX = 0;
        }
        if (startY < 0) {
            startY = 0;
        }
        if (endeX > feld.length) {
            endeX = feld.length;
        }
        if (endeY > feld[0].length) {
            endeY = feld[0].length;
        }

        for (int i = startX; i < endeX; i += 1) {
            for (int j = startY; j < endeY; j += 1) {
                farben[feld[i][j] + 128]++;
            }
        }
       
        return farben;
    }
   
    /**
     * @param feld        Das Feld.
     * @param rasterX     Das Raster.
     * @param rasterY     Das Raster.
     * @param zeichen     Die den Farben zugeordneten Zeichen (das Array muss
     *                    256 Felder haben.
     * @param prioritaet  Nach welcher Priotit�t die Farben genommen werden.
     *
     * @return  Die Umgebung als Stringausgabe.
     */
    public static String feldAusgabe(final byte[][] feld,
                                     final int      rasterX,
                                     final int      rasterY,
                                     final char[]   zeichen,
                                     final int[]    prioritaet) {
        String s = "";
        boolean gesetzt;
        long[] farben = new long[256];
       
        if (zeichen.length != 256) {
            throw new RuntimeException("Ein Array hat eine falsche L�nge: ("
                                           + zeichen.length);
        }
       
        for (int j = 0; j < feld[0].length; j += rasterY) {
            for (int i = 0; i < feld.length; i += rasterX) {
                pixGes(feld, i, j, rasterX, rasterY, farben);
                   
                gesetzt = false;
                for (int k = 0; k < prioritaet.length; k++) {
                    if (farben[prioritaet[k]] > 0) {
                        s = s + zeichen[prioritaet[k]];
                        gesetzt = true;
                        break;
                    }
                }
               
                if (!gesetzt) {
                    s = s + " ";
                }
            }
            s = s + "\n";
        }
       
        return s;
    }
   
    /**
     * Gibt entweder den �bergebenen String-Vektor zur�ck oder erzeugt einen
     * Vektor gleicher L�nge mit leeren Strings abh�ngig von der Variable
     * <code>aut</code>.
     *
     * @param origSeqs  Die Originalstrings.
     * @param aut       Ob die Originalstrings zur�ckgegeben werden sollen.
     *
     * @return  Die Originalstrings oder leere Strings.
     */
    public static String[] erzeugeSeqs(final String[] origSeqs,
                                       final boolean aut) {
       if (aut) {
           return origSeqs;
       } else {
           return new String[origSeqs.length];
       }
    }

    /**
     * Gibt entweder den �bergebenen Condition-Vektor zur�ck oder erzeugt
     * einen Vektor gleicher L�nge mit leeren Conditions abh�ngig von der
     * Variable <code>aut</code>.
     *
     * @param origSeqs  Die Originalstrings.
     * @param aut       Ob die Originalstrings zur�ckgegeben werden sollen.
     *
     * @return  Die Originalstrings oder leere Strings.
     */
    public static Condition[] erzeugeConds(final Condition[] origSeqs,
                                           final boolean aut) {
       if (aut) {
           return origSeqs;
       } else {
           return new Condition[origSeqs.length];
       }
    }

    /**
     * Speichert die Datei <code>in</code> in die Datei <code>out</code>,
     * wobei eine GZ-Kompression verwendet wird.
     *
     * @param in        Der Dateiname der Inputdatei.
     * @param out       Der Dateiname der Outputdatei.
     * @param inLoeschen  Ob die Originaldatei gel�scht werden soll.
     */
    public static void packeDatei(final String in,
                                  final String out,
                                  final boolean inLoeschen) {
        int read = 0;
        byte[] data = new byte[1024];
       
        try {
            // Original-Datei mit Stream verbinden
            File f = new File(in);
            FileInputStream inP = new FileInputStream(f);

            // Ausgabedatei erstellen
            GZIPOutputStream outP =
              new GZIPOutputStream(
                new FileOutputStream(out));

            // Alle Daten der Original-Datei in die Ausgabedatei schreiben
            while ((read = inP.read(data, 0, 1024)) != -1) {
              outP.write(data, 0, read);
            }
            inP.close();
            outP.close();
            if (inLoeschen) {
                f.delete();   // Original-Datei l�schen
            }
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Speichert die Datei <code>in</code> in die Datei <code>out</code>,
     * wobei eine GZ-Entkompression verwendet wird.
     *
     * @param in        Der Dateiname der Inputdatei.
     * @param out       Der Dateiname der Outputdatei.
     * @param inLoeschen  Ob die Originaldatei gel�scht werden soll.
     *
     * @return  Ob die Datei entpackt wurde.
     */
    public static boolean entpackeDatei(final String in,
                                        final String out,
                                        final boolean inLoeschen) {
        String source = in, destination = out;
      
        InputStream  is = null;
        OutputStream os = null;
     
        try {
            is = new GZIPInputStream(new FileInputStream(source));
            os = new FileOutputStream(destination);
      
            byte[] buffer = new byte[8192];
      
            for (int length = is.read(buffer);
                 length != -1;
                 length = is.read(buffer)) {
                os.write(buffer, 0, length);
            }
           
            if (inLoeschen) {
                (new File(source)).delete();
            }
           
        } catch (final IOException e) {
            SonstMeth.log(SonstMeth.LOG_WARNING,
                          "Datei nicht entpackt: " + in,
                          null);
            return false;
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    SonstMeth.log(SonstMeth.LOG_WARNING,
                            "Datei nicht entpackt: " + in,
                            null);
                    return false;
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    SonstMeth.log(SonstMeth.LOG_WARNING,
                            "Datei nicht entpackt: " + in,
                            null);
                    return false;
                }
            }
        }
       
        return true;
    }

    /**
     * Erzeugt einen einzigen Automaten aus den �bergebenen Einzelautomaten
     * mit Aktivierungsbedingungen.
     *
     * @param endAuts  Die Automaten.
     * @param conds    Die zugeh�rigen Bedingungen.
     *
     * @return  Gesamtautomat, dessen Verhalten zu dem der �bergebenen Einzel-
     *          automaten �quivalent ist.
     */
    @SuppressWarnings("unchecked")
    public static EndlicherAutomat gesamtAutomat(
            final EndlicherAutomat[] endAuts,
            final Condition[]        conds) {
        HashMap[] knotZuord = new HashMap[endAuts.length];
        EndlicherAutomat neu = new EndlicherAutomat();
        int lfdNr = 1;
        ArrayList<Integer> knot;
        ArrayList<Integer> knot1;
        Iterator<Integer> it, it1;
        Iterator<Transition> it3;
        Integer aktKnNum;
        Knoten aktKn;
        ZInfo info;
        Knoten zielKn;
        Integer zielKnNum;
        Condition aktBed;
        Condition neuBed = null;
        Condition zwischBed;
        int numOrig1, numOrig2;
        int idlBefehl;
        EndlicherAutomat[] eas = new EndlicherAutomat[endAuts.length];
        LinkedList<Transition> trans;
        Transition tran;
        String[] args = {"log 4"};
       
        if (endAuts == null
                || conds == null
                || endAuts.length != conds.length
                || endAuts.length == 0) {
            SonstMeth.log(SonstMeth.LOG_ERROR,
                          "Gesamtautomat konnte nicht erzeugt werden.",
                          new Parametersatz(args));
        }
       
        for (int i = 0; i < eas.length; i++) {
            eas[i] = new EndlicherAutomat();
            eas[i].erzeugeAusSequenz(
                    endAuts[i].erzeugeStringSeq(),
                    fmg.fmg8.endlAutomat.translator.Konstanten.STD_TRANSL_BE,
                    false);
           
            if (eas[i].istLeer()) {
                eas[i].einfuegenKnoten(Integer.MAX_VALUE,
                        SonstMeth.posSuch(
                                fmg.fmg8.umgebung2D.Konstanten.BEF,
                                "stp"),
                        1,
                        1);
               
                eas[i].setStart(eas[i].holeKnoten(Integer.MAX_VALUE));
            }
        }
       
        // Neue Knoten zuordnen.
        for (int i = 0; i < eas.length; i++) {
            knotZuord[i] = new HashMap<Integer, Integer>();
           
            knot = new ArrayList<Integer>(eas[i].holAdj().keySet());
            it = knot.iterator();

            while (it.hasNext()) {
                aktKnNum = it.next();
                aktKn = eas[i].holeKnoten(aktKnNum);
                info = aktKn.getInfo();
                neu.einfuegenKnoten(lfdNr,
                                    info.getAktion(),
                                    info.getParam(),
                                    info.getAlter());
               
                knotZuord[i].put(aktKnNum, lfdNr);
                lfdNr++;
            }
        }
       
        // Neue Kanten INTER Automaten zuordnen.
        for (int i = 0; i < eas.length; i++) {
            zielKn = eas[i].holeStartzustand();
           
            if (zielKn != null) {
                zielKnNum = (Integer) knotZuord[i].get(zielKn.holeName());
                neuBed = SonstMeth.ausFormatBed(conds[i].formatted());
                for (int j = 0; j < i; j++) {
                    zwischBed = SonstMeth.ausFormatBed(conds[j].formatted());
                    zwischBed.negiere();
                    neuBed = new InnerNode(neuBed,
                                           zwischBed,
                                           fmg.fmg8.endlAutomat.Konstanten.UND);
                }
               
                for (int j = 0; j < eas.length; j++) {
                    if (j != i) {
                        knot = new ArrayList<Integer>(
                                eas[j].holAdj().keySet());
                        it = knot.iterator();
                       
                        while (it.hasNext()) {
                            aktKnNum = (Integer) knotZuord[j].get(it.next());
                            neu.einfuegKante(aktKnNum, zielKnNum, neuBed, 1);
                        }
                    }
                }
            }
        }

        // Neue Kanten INTRA Automaten zuordnen.
        for (int i = 0; i < eas.length; i++) {
            knot1 = new ArrayList<Integer>(eas[i].holAdj().keySet());
            it1 = knot1.iterator();
           
            while (it1.hasNext()) {
                numOrig1 = it1.next();
                aktKnNum = (Integer) knotZuord[i].get(numOrig1);
                aktKn = eas[i].holeKnoten(numOrig1);
               
                if (aktKn.getInfo() != null
                        && aktKn.getInfo().getBedingungen() != null) {
                    trans = aktKn.getInfo().getBedingungen();
                    it3 = trans.iterator();
                   
                    while (it3.hasNext()) {
                        tran = it3.next();
                        numOrig2 = tran.getFolgezustand();
                        zielKnNum = (Integer) knotZuord[i].get(numOrig2);
                        aktBed = tran.getCond();
                       
                        if (aktBed != null) {
                            neu.einfuegKante(aktKnNum, zielKnNum, aktBed, 1);
                        }
                    }
                }
            }
        }

        // true - Kanten zu den einzelnen Startknoten einf�gen.
        for (int i = 0; i < eas.length; i++) {
            zielKn = eas[i].holeStartzustand();
           
            if (zielKn != null) {
                zielKnNum = (Integer) knotZuord[i].get(zielKn.holeName());
               
                knot = new ArrayList<Integer>(eas[i].holAdj().keySet());
                it = knot.iterator();
               
                while (it.hasNext()) {
                    aktKnNum = (Integer) knotZuord[i].get(it.next());
                    neu.einfuegKante(aktKnNum,
                                     zielKnNum,
                                     SonstMeth.ausBed("t"),
                                     1);
                }
            }
        }

        // Einen IDLE-Startknoten einf�gen.
        idlBefehl = SonstMeth.posSuch(fmg.fmg8.umgebung2D.Konstanten.BEF,
                                      "IDL");
        neu.einfuegenKnoten(lfdNr, idlBefehl, 1, 1);
        neu.setStart(neu.holeKnoten(lfdNr));
        for (int i = 0; i < conds.length; i++) {
            if (i > 0) {
                neuBed = conds[i];
            } else {
                neuBed = SonstMeth.ausFormatBed(conds[i].formatted());
                for (int j = 1; j < conds.length; j++) {
                    zwischBed = SonstMeth.ausFormatBed(conds[j].formatted());
                    zwischBed.negiere();
                    neuBed = new InnerNode(
                            neuBed,
                            zwischBed,
                            fmg.fmg8.endlAutomat.Konstanten.ODER);
                }
            }

            if (conds.length == 1) {
                neuBed = SonstMeth.ausBed("t");
            }

            if (eas[i].holeStartzustand() != null) {
                neu.einfuegKante(lfdNr,
                       (Integer)
                       knotZuord[i].get(eas[i].holeStartzustand().holeName()),
                       neuBed,
                       1);
            }
        }
       
       
        return neu;
    }
   
    /**
     * Die berechneten Wahrscheinlichkeiten.
     */
    private static HashMap<String, Double> berConds;

    /**
     * Die Anzahl der Iterationen.
     */
    private static HashMap<String, Long> berCondsIt;

    /**
     * Gibt eine probabilistische Absch�tzung des prozentualen Anteils an
     * wahren Belegungen der Bedingung zur�ck.
     *
     * @param cond       Die Bedingung.
     * @param erstmalig  Wie viele Iterationen beim ersten Mal.
     * @param spaeter    Wie viele Iterationen ab dem zweiten Mal.
     *
     * @return  Prozentualer Anteil an wahren Belegungen.
     */
    public static double condStrength(final Condition cond,
                               final long erstmalig,
                               final long spaeter) {
        long iterat;
        Condition c = cond.simplify();
        Random rand = new Random();
        HashSet<Integer> sensors = cond.aktSens();
        int[] sens;
        int max = 0;
        double value;
        boolean vorhanden = false;
        String cForm = c.formatted();
        double newVal;
       
        Iterator<Integer> it = sensors.iterator();
        while (it.hasNext()) {
            int zwisch = it.next();
           
            if (zwisch > max) {
                max = zwisch;
            }
        }
       
        sens = new int[max];
       
        if (SonstMeth.berConds == null) {
            berConds = new HashMap<String, Double>();
            berCondsIt = new HashMap<String, Long>();
        }
       
        if (berConds.containsKey(cForm)) {
            iterat = spaeter;
            vorhanden = true;
        } else {
            iterat = erstmalig;
        }
       
        value = 0;
        for (long i = 0; i < iterat; i++) {
            it = sensors.iterator();
            while (it.hasNext()) {
                sens[it.next() - 1] = rand.nextInt(256);
            }
           
            if (c.evaluiereSens(sens)) {
                value++;
            }
        }
       
        if (vorhanden) {
            double oldVal = SonstMeth.berConds.get(cForm);
            long oldIt = SonstMeth.berCondsIt.get(cForm);
            newVal = (oldVal * oldIt + value) / (oldIt + spaeter);
            SonstMeth.berConds.put(cForm, newVal);
            SonstMeth.berCondsIt.put(cForm, oldIt + spaeter);
        } else {
            value /= erstmalig;
            SonstMeth.berConds.put(cForm, value);
            SonstMeth.berCondsIt.put(cForm, erstmalig);
            newVal = value;
        }
       
        return newVal;
    }

    /**
     * Main-Methode mit Funktionalit�t zum Umbenennen der Fitness-Statistiken.
     *
     * @param args  Die Parameter f�r den parametersatz.
     */
    public static void main(final String[] args) {
        Parametersatz pars = new Parametersatz(args);
        // pars.ergaenze();
       
        File dir = new File(pars.getStdPfad());
        File dat;
        File newFile;
        String[] liste = dir.list(new FilenameFilter() {
       
            @Override
            public boolean accept(final File dir, final String name) {

                int i = 0;
               
                while (i < name.length() - 4) {
                    if (name.substring(i, i + 4).equals(".dat")) {
                        return true;
                    }
                   
                    i++;
                }

                return false;
            }
       
        });
       
        for (int i = 0; i < liste.length; i++) {
            dat = new File(pars.getStdPfad() + File.separator + liste[i]);
            int j = 0;
           
            while (j < liste[i].length() - 4) {
                if (liste[i].substring(j, j + 4).equals(".dat")) {
                    break;
                }
               
                j++;
            }

            newFile = new File(
                    pars.getStdPfad()
                    + File.separator
                    + liste[i].substring(0, j + 4)
                    + ".txt");
           
            dat.renameTo(newFile);
           
            System.out.println(dat + " -> " + newFile);
        }
    }
   
    /**
     * �bertr�gt die Parameter aus der FMG3-Version in den aktuellen Satz.
     *
     * @param parsOld  Die alten Parameter.
     * @param parsNew  Die neuen Parameter.
     */
    public static void konvertiere(
            final Parametersatz parsOld,
            final Parametersatz parsNew) {
        // TODO
    }
   
    /**
     * @param modus  Der Modus (�bersetzer oder Verhalten).
     *
     * @return  Die minimale Befehlsnummer je nach Modus.
     */
    public static int minBef(final int modus) {
        if (modus == SonstMeth.MODUS_VERHALTEN) {
            return fmg.fmg8.umgebung2D.Konstanten.MIN_INST_BEH;
        } else if (modus == SonstMeth.MODUS_TRANSLATOR) {
            return fmg.fmg8.umgebung2D.Konstanten.MIN_INST_TRANS;
        } else {
            return -1;
        }
    }

    /**
     * @param modus  Der Modus (�bersetzer oder Verhalten).
     *
     * @return  Die maximale Befehlsnummer je nach Modus.
     */
    public static int maxBef(final int modus) {
        if (modus == SonstMeth.MODUS_VERHALTEN) {
            return fmg.fmg8.umgebung2D.Konstanten.MAX_INST_BEH;
        } else if (modus == SonstMeth.MODUS_TRANSLATOR) {
            return fmg.fmg8.umgebung2D.Konstanten.MAX_INST_TRANS;
        } else {
            return -1;
        }
    }

    /**
     * @param modus  Der Modus (�bersetzer oder Verhalten).
     *
     * @return  Die minimale Variablennummer je nach Modus.
     */
    public static int minVar(final int modus) {
        if (modus == SonstMeth.MODUS_VERHALTEN) {
            return Const.MIN_VAR_BEH;
        } else if (modus == SonstMeth.MODUS_TRANSLATOR) {
            return Const.MIN_VAR_TRANS;
        } else {
            return -1;
        }
    }

    /**
     * @param modus  Der Modus (�bersetzer oder Verhalten).
     *
     * @return  Die maximale Variablennummer je nach Modus.
     */
    public static int maxVar(final int modus) {
        if (modus == SonstMeth.MODUS_VERHALTEN) {
            return Const.MAX_VAR_BEH;
        } else if (modus == SonstMeth.MODUS_TRANSLATOR) {
            return Const.MAX_VAR_TRANS;
        } else {
            return -1;
        }
    }
   
    /**
     * Gibt eine gleichverteilte Zufallszahl aus
     * {min, min + 1, ..., max}
     * zur�ck.
     *
     * @param min   Das Minimum.
     * @param max   Das Maximum.
     * @param rand  Der Zufallsgenerator.
     * @return  Gleichverteilte Zufallszahl zwischen min und max.
     */
    public static int glVertZwischen(
            final int min,
            final int max,
            final Random rand) {
        if (min > max) {
            throw new RuntimeException(
                    "Fehler in Methode glVertZwischen: min > max");
        }

        return Math.abs(rand.nextInt()) % (max - min + 1) + min;
    }
   
    /**
     * Gibt eine Zahl zur�ck, die modulo des angegebenen Bereichs der
     * eingegebenen Zahl entspricht.
     *
     * Beispiel (min = 3, max = 7, zahl = i, f = modZwischen):
     * i             :  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
     * f(i, min, max):   4, 5, 6, 7, 3, 4, 5, 6, 7, 3, 4, 5, ...
     *
     * @param zahl  Die Zahl.
     * @param min   Der Beginn des Bereichs.
     * @param max   Das Ende des Bereichs.
     *
     * @return  Zahl, die der Eingabe modulo des Bereichs entspricht.
     */
    public static int modZwischen(
            final int zahl,
            final int min,
            final int max) {
        if (min > max) {
            throw new RuntimeException(
                    "Fehler in Methode modZwischen: min > max");
        }
       
        if (zahl >= min) {
            return (zahl - min) % (max - min + 1) + min;
        } else {
            return -(SonstMeth.modZwischen(-zahl, -max, -min));
        }
    }
}
TOP

Related Classes of fmg.fmg8.sonstiges.SonstMeth

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.