E
Emerix
Gast
Schönen guten Tag !
Ich muss als Hausaufgabe ein Java Programm schreiben , weches die Graphische Darstellung von Automaten "repräsentiert".
Dazu gehört , dass man einen Automaten in einen deterministischen umformt
Ein Automat besteht aus Knoten und Kanten. Zu jeder kante gehört ein Von Knoten und ein Zu Knoten und ein array von Zeichen. Bei Eingabe eines dieser Zeichen kommt man vom Von Knoten zum Zu Knoten.
In einem deterministischen Automaten gibt es bei Eingabe von einem Zeichen genau einen Folgeknoten. Bei nichtdeterministischen ogischerweise manchmal auch mehrere.
Das Prinzip aus dem diese Methode beruht ist , um einen Automaten deterministisch zu machen wird die Menge der Folgeknoten , die man mit einem Zeichen erreicht zu einem neuen Knoten zusammen gefasst. Dann wird vom eben betrachteten Knoten zum neuen eine Kante mit nur einem Zeichen erstellt.
Von allen so erstellten Knoten wird das gleiche nochmals durchgeführt um am Ende einen deterministischen Automaten zu haben. Wenn man eine Menge von Knoten bereits einmal "heraus bekommen" hat, und somit bereits ein passender Zustand b erstellt wurde, dann wird vom betrachteten Knoten mit dem betrachteten Zeichen eine kante zum knoten b erstellt.
Auf dem papier ganz einfach aber als java code bekomm ich es einfach nicht gerafft, da irrgendwann der Fehler
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at AutomatBib.Automat.makeDeterm(Automat.java:281)
at AutomatBib.Oberflaeche.makeDeterm(Oberflaeche.java:69)
at AutomatBib.TestAutomaton.main(TestAutomaton.java:122)
auftaucht.
Bei google stand , dass dies geschieht , wenn man über eine Collection einen iterator laufen lässt und die collection ändern möchte. Allerdings wird der Fehler hier bei der zeile..
also bei it.next(); geworfen. Und das erst, wenn die while schleife bereits mehrmals durchlaufen wurde.
Ich bin doch sehr am verzweifeln hehe.
Ich nutze übrigens Eclipse und die neueste Java Version.
Wäre sehr erfreut über andere Lösungsansätze, da ich schon 4 mal versucht habe diese Methode von Grund auf neu zu coden und es einfach nicht hinbekomme (wegen diesem fehler)
Ich schicke übrigens gern den gesammten Source code weiter , wenn ihr selbst spielen wollt=)
Vielen Dank fürs Lesen![/code]
Ich muss als Hausaufgabe ein Java Programm schreiben , weches die Graphische Darstellung von Automaten "repräsentiert".
Dazu gehört , dass man einen Automaten in einen deterministischen umformt
Ein Automat besteht aus Knoten und Kanten. Zu jeder kante gehört ein Von Knoten und ein Zu Knoten und ein array von Zeichen. Bei Eingabe eines dieser Zeichen kommt man vom Von Knoten zum Zu Knoten.
In einem deterministischen Automaten gibt es bei Eingabe von einem Zeichen genau einen Folgeknoten. Bei nichtdeterministischen ogischerweise manchmal auch mehrere.
Das Prinzip aus dem diese Methode beruht ist , um einen Automaten deterministisch zu machen wird die Menge der Folgeknoten , die man mit einem Zeichen erreicht zu einem neuen Knoten zusammen gefasst. Dann wird vom eben betrachteten Knoten zum neuen eine Kante mit nur einem Zeichen erstellt.
Von allen so erstellten Knoten wird das gleiche nochmals durchgeführt um am Ende einen deterministischen Automaten zu haben. Wenn man eine Menge von Knoten bereits einmal "heraus bekommen" hat, und somit bereits ein passender Zustand b erstellt wurde, dann wird vom betrachteten Knoten mit dem betrachteten Zeichen eine kante zum knoten b erstellt.
Auf dem papier ganz einfach aber als java code bekomm ich es einfach nicht gerafft, da irrgendwann der Fehler
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at AutomatBib.Automat.makeDeterm(Automat.java:281)
at AutomatBib.Oberflaeche.makeDeterm(Oberflaeche.java:69)
at AutomatBib.TestAutomaton.main(TestAutomaton.java:122)
auftaucht.
Bei google stand , dass dies geschieht , wenn man über eine Collection einen iterator laufen lässt und die collection ändern möchte. Allerdings wird der Fehler hier bei der zeile..
Code:
while(it.hasNext()==true){
Node2 n=it.next();
//hier kommt es zur exception
also bei it.next(); geworfen. Und das erst, wenn die while schleife bereits mehrmals durchlaufen wurde.
Ich bin doch sehr am verzweifeln hehe.
Ich nutze übrigens Eclipse und die neueste Java Version.
Wäre sehr erfreut über andere Lösungsansätze, da ich schon 4 mal versucht habe diese Methode von Grund auf neu zu coden und es einfach nicht hinbekomme (wegen diesem fehler)
Code:
public Automat makeDeterm(){
//wenn automat deterministisch gib ihn wieder...
if(this.isDeterm()==true){
return this;
}
else{
//neuer automat der nachher wiedergegeben wird
Automat a=new Automat(sigma);
HashSet<Node2> hash=new HashSet<Node2>();
//set von (mengen von)knoten , die vom startknoten des zu bearbeitenden automaten
//angesprochen werden
for(int i=0;i<sigma.length;i++){
char[] ca=new char[1];
ca[0]=sigma[i];
//umformung des jetzt benutzen char in ein einelementiges array
//um nachher weitere edges erstellen zu können
HashSet<Node> baum=anfang.gebeTreeBeiZeichen(sigma[i]);
//menge von knoten die bei zeichen sigma[i] angesprochenw erden
if((baum.size()==1)&&(baum.contains(anfang))){
a.addEdge(a.anfang,ca,a.anfang);
}
//falls nur der erste knoten angesprochen wird wird eine kante vom anfang des
//neuen automaten und zurück erstellt. Bei weiteren knoten vom anfang zum anfang
//wird jeder neue knoten gemerged.. also bleibt nur ein knoten aber die liste
//der zeichen dieses knotens wird erweitert.
else{
Node2 n=new Node2(baum);
Iterator<Node2> iter=hash.iterator();
boolean check=false;
while(iter.hasNext()){
Node2 node=iter.next();
if((node.nodes.containsAll(baum)&&baum.containsAll(node.nodes))==true){
check=true;
a.addEdge(a.anfang,ca, node);
}
}
//hier wird überprüft ob es bereits einen knoten gibts , der die gleiche
//menge von knoten aus dem anfangsautomaten repräsentiert
//wenn ja wirdkein neuer zustand erstellt
if(check==false){
hash.add(n);
a.addNode(n);
a.addEdge(a.anfang,ca,n);
//wenn nicht wird hier ein neuer knoten erstellt.. und dieser in hash gemerkt
//ein automat merkt sich alle seine zustände als node
//nodes haben allerdings nicht das hashset kanten als attribut
//in welchen die menge der kanten gespeichert wird die sie repräsentiert
}
}
}
boolean crash=true;
//die variable die zum abbruch der schleife unten führt . wird false wenn
// keine weiteren sets übergeben werden und somit der "umbau" abgeschlossen ist
HashSet<Node2> nodes=new HashSet<Node2>();
//da der erste schritt von der anfangskante fertig ist werden nun alle node2's
//in einem neuen set gespeichert
HashSet<Node2> treeNext=new HashSet<Node2>();
//in dieses set werden alle , für den nächsten schleiendurchgang benötigten
// node2's gespeichert
nodes.addAll(hash);
//hash wird kopiert..
System.out.println(nodes);
while(crash){
Iterator<Node2> it=hash.iterator();
//iterator zur schleife über alle zuletzt erstellten nodes
while(it.hasNext()==true){
Node2 n=it.next();
//hier kommt es zur exception
for(int i=0;i<sigma.length;i++){
char[] ca=new char[1];
ca[0]=sigma[i];
HashSet<Node> tree=n.gebeTreeBeiZeichen2(sigma[i]);
if(tree.size()==1&&tree.contains(anfang)){
a.addEdge(n,ca,a.anfang);
}
else{
Iterator<Node2> itNodes=nodes.iterator();
boolean meh=false;
while(itNodes.hasNext()){
Node2 nodeCheck=itNodes.next();
if((nodeCheck.nodes.containsAll(tree))&&(tree.containsAll(nodeCheck.nodes))){
a.addEdge(n,ca,nodeCheck);
meh=true;
}
}
if(meh==false){
System.out.println("Meh");
Node2 neu=new Node2(tree);
a.addNode(neu);//fügt dem automaten den neuen knoten zu
a.addEdge(n,ca,neu);//fügt dem automaten die neue kante zu
nodes.add(neu);//fügt dem hilfsset von zuständen den neuen zu
treeNext.add(neu);
//fügt dem set der knoten welche als nächstes bearbeitet werden müssen
//diesen neuen knoten hinzu
}
}
}
}
hash=treeNext;
//das alte set wird mit dem neuen ersetzt
if(hash.size()==0){
//wenn das neue set leer sein sollte wird crash =false gesetzt und die schleife
//ist vollendet
crash=false;
}
}
Iterator<Node2> it =nodes.iterator();
while(it.hasNext()){
//setzten der akzeptanzzustände
boolean check=false;
Node2 n=it.next();
Iterator<Node> ite=n.nodes.iterator();
while(ite.hasNext()){
Node na=ite.next();
if(na.isF==true){
check=true;
}
}
if(check=true){
n.makeF();
}
}
return a;
}
}
Ich schicke übrigens gern den gesammten Source code weiter , wenn ihr selbst spielen wollt=)
Vielen Dank fürs Lesen![/code]