Finished implementing Hopcroft algorithm

This commit is contained in:
2017-05-31 12:36:40 +02:00
parent e80ec332d1
commit aa12ce2951
2 changed files with 130 additions and 12 deletions
+64 -11
View File
@@ -1,6 +1,7 @@
package com.imegumii;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -19,12 +20,27 @@ public class HopcroftConverter {
DFAtoHopcroft();
updateGroupReferences();
System.out.println("\nFound " + sets.size() + " sets.");
}
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();
}
return HopcrofttoDFA();
}
@@ -40,7 +56,7 @@ public class HopcroftConverter {
HopcroftSet currentSet = null;
for(HopcroftSet s : sets) {
if (t.vanState == s.state) {
if (t.vanState.equals(s.state)) {
found = true;
currentSet = s;
break;
@@ -50,11 +66,12 @@ public class HopcroftConverter {
if(!found) {
String groupName = beginGroup;
boolean endState = false;
if(automata.eindStates.contains(t.vanState)) {
if(automata.eindStates.contains((String)t.vanState)) {
groupName = endGroup;
endState = true;
}
currentSet = new HopcroftSet(groupName, (String)t.vanState, endState);
sets.add(currentSet);
}
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)
return false;
sets.clear();
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()
{
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 state;
@@ -150,4 +192,15 @@ class HopcroftSet {
this.state = state;
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?"*":"");
}
}
+66 -1
View File
@@ -114,6 +114,69 @@ public class Main {
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()
{
Character [] characters = {'a', 'b'};
@@ -281,8 +344,10 @@ public class Main {
// Practicum4();
Practicum5();
// Practicum5();
// ReverseAutomata();
Hopcroft();
}
}