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.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
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.Vis;
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 {

    /**
     * Ung�ltiger Modus, der an Stellen zu verwenden ist, wo eine
     * Kennzeichnung notwendig ist, dass der Translator in der aktuellen
     * Form nicht benutzt werden sollte.
     */
    public static final int MODUS_UNGUELTIG = -1;
   
    /**
     * 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', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 0-9
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 10-19
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 20-29
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 30-39
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 40-49
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 50-59
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 60-69
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 70-79
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 80-89
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 90-99
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 100-109
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 110-119
        '0', '1', '.', '3', '�', '5', '6', ' ', '#', '9', // 120-129
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 130-139
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 140-149
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 150-159
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 160-169
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 170-179
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 180-189
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 190-199
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 200-209
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 210-219
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 220-229
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 230-239
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 240-249
        '0', '1', '2', '3', '4', '5'};                    // 250-255

    /**
     * Die Priorit�tenliste f�r die verschiedenen Farben des Inputfeldes.
     */
    public static final int[] PRIORITAET_INPUT = {128,
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
        10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
        20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
        30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
        40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
        50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
        60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
        70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
        80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
        90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
        100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
        110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
        120, 121, 123, 125, 126, 127, 129,
        130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
        140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
        150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
        160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
        170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
        180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
        190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
        210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
        220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
        230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
        240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
        250, 251, 252, 253, 254, 255,
        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, 0};
   
    /**
     * �berlagerung des Default-Konstruktors.
     */
    private SonstMeth() {
       
    }
   
    /**
     * Schreibt zwei Strings in die Konsole und kennzeichnet ihre Unterschiede.
     *
     * @param s1      Der erste String.
     * @param s2      Der zweite String.
     * @param params  Die Parameter.
     */
    public static void unterscheide(
            final String s1,
            final String s2,
            final Parametersatz params) {
        String unterschiede = "";

        if (s1.equals(s2)) {
            unterschiede = "Strings sind identisch.";
        } else {
            for (int i = 0; i < s1.length() || i < s2.length(); i++) {
                if (s1.length() <= i || s2.length() <= i) {
                    unterschiede += "-";
                } else {
                    if (s1.charAt(i) == s2.charAt(i)) {
                        unterschiede += " ";
                    } else {
                        unterschiede += "#";
                    }
                }
            }
        }
       
       
        SonstMeth.log(
                SonstMeth.LOG_INFO,
                "\n(" + s1.length() + "): " + s1 + "\n",
                params,
                "plain",
                null);
        SonstMeth.log(
                SonstMeth.LOG_INFO,
                "(" + s2.length() + "): " + s2 + "\n",
                params,
                "plain",
                null);
        SonstMeth.log(
                SonstMeth.LOG_INFO,
                unterschiede + "\n",
                params,
                "plain",
                null);
    }
   
    /**
     * 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) {
            throw new RuntimeException("Objekt nicht serialisierbar:\n" + o);
        }
    }

    /**
     * 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) {
        return SonstMeth.normZahl(z, 3);
    }
   
    /**
     * Erzeugt eine normierte Zahl aus einem Integer. Dabei werden f�hrende
     * Nullen eingef�gt. Die Zahl darf nicht l�nger als n sein.
     *
     * @param z  Die zu normierende Zahl als Integer.
     * @param n  Die Anzahl der Stellen.
     *
     * @return  Die normierte Zahl als String.
     */
    public static String normZahl(
            final long z,
            final int n) {
        final String zahl = "" + z;
        String nullen = "";
       
        if (zahl.length() <= n) {
            for (int i = 0; i < n - zahl.length(); i++) {
                nullen = "0" + nullen;
            }
        } else {
            throw new RuntimeException("Zahl kann nicht normiert werden.");
        }

        return nullen + zahl;
    }
   
    /**
     * 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;
    }

    /**
     * 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);
            }
           
            // Speichern des Loggings, falls die Stufe gespeichert wird.
            if (msg != null && params != null
                    && params.getLogSpeichern() <= stufe) {
                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) {
        try {
            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;
           
        } catch (final Exception e) {
            SonstMeth.log(
                    SonstMeth.LOG_ERROR,
                    "Bitmap-Feld nicht geladen: "
                        + pars.getStdPfad()
                        + File.separatorChar
                        + pars.getUmgebungDatname(),
                    pars);
           
            byte[][] aa = new byte[1][1];
            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: "
                    + verz + File.separator + datName,
                 params);
            throw new RuntimeException("Datei konnte nicht erstellt werden.");
        }
    }

    /**
     * Speichert mehrere Zeilen Text aus einer ArrayList in eine Textdatei.
     *
     * @param verz     Das Verzeichnis.
     * @param datName  Die Datei.
     * @param text     Der zu speichernde Text.
     * @param params   Die Parameter.
     */
    public static void speichereTextAusArray(
            final String verz,
            final String datName,
            final List<String> text,
            final Parametersatz params) {
        FileWriter f1 = null;
        Iterator<String> it = text.iterator();
       
        try {
            f1 = new FileWriter(verz + File.separator + datName);
            while (it.hasNext()) {
                f1.write(it.next() + "\n");
            }
            f1.close();
        } catch (IOException e) {
            log(SonstMeth.LOG_ERROR,
                "Fehler beim Erstellen der Text-Datei: "
                    + f1.toString(),
                 params);
            throw new RuntimeException("Datei konnte nicht erstellt werden.");
        }
    }
   
    /**
     * Liest zeilenweise Text aus einer Textdatei und gibt einen String-Array
     * der gesamten Datei zur�ck.
     *
     * @param verz     Das Verzeichnis.
     * @param datName  Die Datei.
     * @param params   Die Parameter.
     *
     * @return  Der zeilenweise gelsene Text aus der Datei.
     */
    public static LinkedList<String> liesTextArray(
            final String verz,
            final String datName,
            final Parametersatz params) {
        String zwisch;
        LinkedList<String> textArray = new LinkedList<String>();
       
        try {
            BufferedReader f1 =
                new BufferedReader(
                        new FileReader(verz + File.separator + datName));
           
            zwisch = f1.readLine();
            while (zwisch != null) {
                textArray.add(zwisch);
                zwisch = f1.readLine();
            }
            f1.close();
        } catch (IOException e) {
            log(SonstMeth.LOG_ERROR,
                "Fehler beim Lesen aus der Text-Datei: "
                    + verz + File.separator + datName,
                 params);
            throw new RuntimeException(
                    "Aus Datei konnte nicht gelesen werden.");
        }
       
        return textArray;
    }
   
    /**
     * 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 die Zusatzwerte der aktuellen Aufnahme.
     *
     * @param aufn  Die Aufnahme.
     *
     * @return Die gespeicherten Zusatzinformationen (Kollisionen und GP).
     */
    @SuppressWarnings(value = { "unchecked" })
    public static String extrZusatz(final Aufnahme aufn) {
        LinkedList<AbstractMsg> msgs
        = aufn.getParams().getMsgs(
            null,
            Long.MIN_VALUE,
            Long.MAX_VALUE);
        String s = "";
        long old = Long.MIN_VALUE;
        long akt;
       
        for (AbstractMsg m : msgs) {
            akt = m.getDatum();
            if (akt < old) {
                throw new RuntimeException(
                        "Falsche Reihenfolge der Nachrichten");
            }
           
            if (m.getZusatz() != null
                && m.getZusatz().getClass().equals(ArrayList.class)) {
               
                ArrayList<Long> zus = (ArrayList<Long>) m.getZusatz();
               
                for (Long l : zus) {
                    s += l + ";";
                }
               
                s += "\n";
            }
           
            old = akt;
        }
       
        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;
        String zusGes;
       
        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());
                zusGes = SonstMeth.extrZusatz(aufn);
               
                // Speichere Fitnesswerte.
                SonstMeth.speichereTextDatei(
                        verz,
                        "FIT-" + gespGr[i] + ".txt",
                        sGes,
                        params);

                // Speichere Zusatzwerte.
                SonstMeth.speichereTextDatei(
                        verz,
                        "ZUS-" + gespGr[i] + ".txt",
                        zusGes,
                        params);
               
            } catch (final Exception e) {
                SonstMeth.log(
                        SonstMeth.LOG_WARNING,
                        "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, je gr��er desto enger.
     * @param rasterY     Das Raster, je gr��er desto enger.
     * @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;
    }

    /**
     * �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 statistik.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));
        }
    }
   
    /**
     * Speichert den als Sequenz �bergebenen Automaten in einem
     * Standardverzeichnis und unter einem Standardnamen. Achtung: die Methode
     * erzeugt ein Vis-Objekt mit zugeh�rigem Roboter und ist daher
     * ineffizient ==> sparsam gebrauchen.
     *
     * @param seqOrig    Die Sequenz.
     * @param augabeDat  Der Name der Ausgabedatei.
     * @param params     Die Parameter.
     */
    public static void saveAutPNG(
            final String seqOrig,
            final String augabeDat,
            final Parametersatz params) {
        String[] seqs = new String[1];
        String seq
            = fmg.fmg8.endlAutomat.EndlicherAutomat.bereinigeStatic(seqOrig);
        seqs[0] = seq;
        Vis zwisch = new Vis("", seqs, null, 1, params, null);
        zwisch.getRob().erzeugeAusSequenz(0, seq, null, false);
        zwisch.savePNG(augabeDat);
    }
   
    /**
     * Schreibt die Info-Datei f�r diesen Lauf.
     *
     * @param params  Die Parameter.
     */
    public static void schreibeInfoDatei(final Parametersatz params) {
        String s = "Informationsdatei f�r " + params.getAufnDat() + "\n\n";
        String dateiname;
        String verzeichnis;
        String wert;
        String[] hervor = params.getHervorPar();
       
        s += "Potenziell variable Parameter:\n\n";

        s += "----------------\n";
        for (String parameter : params.getHervorPar()) {
            s += parameter
                    + " "
                    + params.getUniversalWert(parameter)
                    + "\n";
        }
        s += "----------------\n";
       
        s += "\nEs folgt eine Ausgabe des kompletten Parametersatzes:\n\n";
        s += params.toString();
       
        dateiname = params.getAufnDat();
        for (String herv : hervor) {
            wert = params.getUniversalWert(herv).toString();
            wert = wert.replace(':', '-');
            dateiname += "_"
                + herv + "_" + wert;
        }
        dateiname += "_info.txt";
        verzeichnis = params.getStdPfad();
       
        SonstMeth.speichereTextDatei(
                verzeichnis,
                dateiname,
                s,
                params);
       
        SonstMeth.log(
                SonstMeth.LOG_INFO,
                "Infodatei f�r diesen Lauf: "
                    + verzeichnis
                    + File.separatorChar
                    + dateiname,
                    params);
    }
}
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.