Finished implementing Hopcroft algorithm
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.imegumii;
|
package com.imegumii;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@@ -19,12 +20,27 @@ public class HopcroftConverter {
|
|||||||
|
|
||||||
DFAtoHopcroft();
|
DFAtoHopcroft();
|
||||||
updateGroupReferences();
|
updateGroupReferences();
|
||||||
|
|
||||||
|
System.out.println("\nFound " + sets.size() + " sets.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public DFA<String> minimize()
|
public DFA<String> minimize()
|
||||||
{
|
{
|
||||||
while(splitGroups())
|
int lastround = 0;
|
||||||
|
int newround = 2;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while(lastround != newround) {
|
||||||
|
|
||||||
|
count++;
|
||||||
|
System.out.println("Minimize round " + count + " (" + lastround + "/" + newround + ")");
|
||||||
|
|
||||||
|
lastround = newround;
|
||||||
|
newround = splitGroups(lastround);
|
||||||
|
|
||||||
updateGroupReferences();
|
updateGroupReferences();
|
||||||
|
}
|
||||||
|
|
||||||
return HopcrofttoDFA();
|
return HopcrofttoDFA();
|
||||||
}
|
}
|
||||||
@@ -40,7 +56,7 @@ public class HopcroftConverter {
|
|||||||
HopcroftSet currentSet = null;
|
HopcroftSet currentSet = null;
|
||||||
|
|
||||||
for(HopcroftSet s : sets) {
|
for(HopcroftSet s : sets) {
|
||||||
if (t.vanState == s.state) {
|
if (t.vanState.equals(s.state)) {
|
||||||
found = true;
|
found = true;
|
||||||
currentSet = s;
|
currentSet = s;
|
||||||
break;
|
break;
|
||||||
@@ -50,11 +66,12 @@ public class HopcroftConverter {
|
|||||||
if(!found) {
|
if(!found) {
|
||||||
String groupName = beginGroup;
|
String groupName = beginGroup;
|
||||||
boolean endState = false;
|
boolean endState = false;
|
||||||
if(automata.eindStates.contains(t.vanState)) {
|
if(automata.eindStates.contains((String)t.vanState)) {
|
||||||
groupName = endGroup;
|
groupName = endGroup;
|
||||||
endState = true;
|
endState = true;
|
||||||
}
|
}
|
||||||
currentSet = new HopcroftSet(groupName, (String)t.vanState, endState);
|
currentSet = new HopcroftSet(groupName, (String)t.vanState, endState);
|
||||||
|
sets.add(currentSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t.symbol == 'a')
|
if(t.symbol == 'a')
|
||||||
@@ -106,32 +123,57 @@ public class HopcroftConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean splitGroups()
|
private int splitGroups(int oldsize)
|
||||||
{
|
{
|
||||||
int splitCount = 0;
|
HashMap<String, ArrayList<HopcroftSet>> groups = new HashMap<String, ArrayList<HopcroftSet>>();
|
||||||
|
|
||||||
|
for(HopcroftSet s : sets)
|
||||||
|
{
|
||||||
|
String key = s.group + s.transitionAGroup + s.transitionBGroup;
|
||||||
|
|
||||||
|
if(!groups.containsKey(key))
|
||||||
|
{
|
||||||
|
groups.put(key, new ArrayList<HopcroftSet>());
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.get(key).add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(oldsize == groups.size())
|
||||||
|
return oldsize;
|
||||||
|
|
||||||
if(splitCount == 0)
|
sets.clear();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
for(ArrayList<HopcroftSet> arr : groups.values())
|
||||||
|
{
|
||||||
|
String newGroupName = getGroupName();
|
||||||
|
|
||||||
|
for(HopcroftSet ns : arr)
|
||||||
|
{
|
||||||
|
ns.group = newGroupName;
|
||||||
|
sets.add(ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int count = 0;
|
private int count = -1;
|
||||||
|
private String[] alphabet = {"A", "B", "C", "D", "E", "F", "G","H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
|
||||||
|
|
||||||
private String getGroupName()
|
private String getGroupName()
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
return "G" + count;
|
if(count >= alphabet.length)
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
return alphabet[count];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HopcroftSet {
|
class HopcroftSet implements Comparable<HopcroftSet>{
|
||||||
|
|
||||||
public String group;
|
public String group;
|
||||||
public String state;
|
public String state;
|
||||||
@@ -150,4 +192,15 @@ class HopcroftSet {
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
this.isEndState = isEndState;
|
this.isEndState = isEndState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(HopcroftSet o) {
|
||||||
|
return (this.group + this.state).compareTo(o.group + o.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return group + " " + state + " | " + transitionAState + " " + transitionAGroup + " | " + transitionBState + " " + transitionBGroup + " " + (isEndState?"*":"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -114,6 +114,69 @@ public class Main {
|
|||||||
System.out.println(Graph.generateGraphString(test));
|
System.out.println(Graph.generateGraphString(test));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Hopcroft()
|
||||||
|
{
|
||||||
|
Character [] characters = {'a', 'b'};
|
||||||
|
DFA<String> automata = new DFA<String>(characters);
|
||||||
|
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("q0", 'a', "q2"));
|
||||||
|
automata.addTransition(new Transition<String>("q0", 'b', "q3"));
|
||||||
|
automata.addTransition(new Transition<String>("q1", 'a', "q3"));
|
||||||
|
automata.addTransition(new Transition<String>("q1", 'b', "q2"));
|
||||||
|
automata.addTransition(new Transition<String>("q2", 'a', "q0"));
|
||||||
|
automata.addTransition(new Transition<String>("q2", 'b', "q4"));
|
||||||
|
automata.addTransition(new Transition<String>("q3", 'a', "q1"));
|
||||||
|
automata.addTransition(new Transition<String>("q3", 'b', "q5"));
|
||||||
|
automata.addTransition(new Transition<String>("q4", 'a', "q6"));
|
||||||
|
automata.addTransition(new Transition<String>("q4", 'b', "q5"));
|
||||||
|
automata.addTransition(new Transition<String>("q5", 'a', "q2"));
|
||||||
|
automata.addTransition(new Transition<String>("q5", 'b', "q0"));
|
||||||
|
automata.addTransition(new Transition<String>("q6", 'a', "q4"));
|
||||||
|
automata.addTransition(new Transition<String>("q6", 'b', "q0"));
|
||||||
|
|
||||||
|
automata.defineAsStartState("q0");
|
||||||
|
|
||||||
|
automata.defineAsEndState("q1");
|
||||||
|
automata.defineAsEndState("q3");
|
||||||
|
automata.defineAsEndState("q4");
|
||||||
|
automata.defineAsEndState("q6");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
automata.addTransition(new Transition<String>("0", 'a', "0"));
|
||||||
|
automata.addTransition(new Transition<String>("0", 'b', "1"));
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||||
|
automata.addTransition(new Transition<String>("1", 'b', "1"));
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("2", 'a', "0"));
|
||||||
|
automata.addTransition(new Transition<String>("2", 'b', "3"));
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("3", 'a', "4"));
|
||||||
|
automata.addTransition(new Transition<String>("3", 'b', "1"));
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("4", 'a', "5"));
|
||||||
|
automata.addTransition(new Transition<String>("4", 'b', "3"));
|
||||||
|
|
||||||
|
automata.addTransition(new Transition<String>("5", 'a', "0"));
|
||||||
|
automata.addTransition(new Transition<String>("5", 'b', "3"));
|
||||||
|
|
||||||
|
automata.defineAsStartState("0");
|
||||||
|
automata.defineAsEndState("2");
|
||||||
|
automata.defineAsEndState("4");
|
||||||
|
*/
|
||||||
|
|
||||||
|
System.out.println("\nNormal automata..");
|
||||||
|
System.out.println(Graph.generateGraphString(automata));
|
||||||
|
|
||||||
|
HopcroftConverter convert = new HopcroftConverter(automata);
|
||||||
|
DFA<String> minimized = convert.minimize();
|
||||||
|
|
||||||
|
System.out.println("\nMinimized automata..");
|
||||||
|
System.out.println(Graph.generateGraphString(minimized));
|
||||||
|
}
|
||||||
|
|
||||||
public static void ReverseAutomata()
|
public static void ReverseAutomata()
|
||||||
{
|
{
|
||||||
Character [] characters = {'a', 'b'};
|
Character [] characters = {'a', 'b'};
|
||||||
@@ -281,8 +344,10 @@ public class Main {
|
|||||||
|
|
||||||
// Practicum4();
|
// Practicum4();
|
||||||
|
|
||||||
Practicum5();
|
// Practicum5();
|
||||||
|
|
||||||
// ReverseAutomata();
|
// ReverseAutomata();
|
||||||
|
|
||||||
|
Hopcroft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user