/*
* 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);
}
}