protected internal virtual TransducerGraph BuildMinimizedFA() { TransducerGraph minimizedFA = new TransducerGraph(); TransducerGraph unminimizedFA = GetUnminimizedFA(); foreach (TransducerGraph.Arc arc in unminimizedFA.GetArcs()) { ICollection <TransducerGraph.Arc> source = ProjectNode(arc.GetSourceNode()); ICollection <TransducerGraph.Arc> target = ProjectNode(arc.GetTargetNode()); try { if (minimizedFA.CanAddArc(source, target, arc.GetInput(), arc.GetOutput())) { minimizedFA.AddArc(source, target, arc.GetInput(), arc.GetOutput()); } } catch (Exception) { } } //throw new IllegalArgumentException(); minimizedFA.SetStartNode(ProjectNode(unminimizedFA.GetStartNode())); foreach (object o in unminimizedFA.GetEndNodes()) { minimizedFA.SetEndNode(ProjectNode(o)); } return(minimizedFA); }
public virtual TransducerGraph ProcessGraph(TransducerGraph g) { g = new TransducerGraph(g); ISet nodes = g.GetNodes(); foreach (object node in nodes) { ICollection <TransducerGraph.Arc> myArcs = null; if (forward) { myArcs = g.GetArcsBySource(node); } else { myArcs = g.GetArcsByTarget(node); } // compute a total double total = 0.0; foreach (TransducerGraph.Arc a in myArcs) { total += ((double)a.GetOutput()); } // divide each by total foreach (TransducerGraph.Arc a_1 in myArcs) { a_1.SetOutput(Math.Log(((double)a_1.GetOutput()) / total)); } } return(g); }
// end static class ExactBlock public static void Main(string[] args) { TransducerGraph fa = new TransducerGraph(); fa.AddArc(fa.GetStartNode(), "1", "a", string.Empty); fa.AddArc(fa.GetStartNode(), "2", "b", string.Empty); fa.AddArc(fa.GetStartNode(), "3", "c", string.Empty); fa.AddArc("1", "4", "a", string.Empty); fa.AddArc("2", "4", "a", string.Empty); fa.AddArc("3", "5", "c", string.Empty); fa.AddArc("4", "6", "c", string.Empty); fa.AddArc("5", "6", "c", string.Empty); fa.SetEndNode("6"); System.Console.Out.WriteLine(fa); ExactAutomatonMinimizer minimizer = new ExactAutomatonMinimizer(); System.Console.Out.WriteLine(minimizer.MinimizeFA(fa)); System.Console.Out.WriteLine("Starting..."); Timing.StartTime(); TransducerGraph randomFA = TransducerGraph.CreateRandomGraph(100, 10, 1.0, 10, new ArrayList()); TransducerGraph minimizedRandomFA = minimizer.MinimizeFA(randomFA); System.Console.Out.WriteLine(randomFA); System.Console.Out.WriteLine(minimizedRandomFA); Timing.Tick("done. ( " + randomFA.GetArcs().Count + " arcs to " + minimizedRandomFA.GetArcs().Count + " arcs)"); }
public virtual TransducerGraph MinimizeFA(TransducerGraph unminimizedFA) { this.unminimizedFA = unminimizedFA; this.activePairs = Generics.NewLinkedList(); this.memberToBlock = Generics.NewHashMap(); Minimize(); return(BuildMinimizedFA()); }
public virtual TransducerGraph MinimizeFA(TransducerGraph unminimizedFA) { // System.out.println(unminimizedFA); this.unminimizedFA = unminimizedFA; this.splits = new ArrayList(); this.memberToBlock = new Hashtable(); //new IdentityHashMap(); // TEG: I had to change this b/c some weren't matching Minimize(); return(BuildMinimizedFA()); }
public virtual TransducerGraph ProcessGraph(TransducerGraph graph) { // compute lambda function ClassicCounter lambda = ComputeLambda(graph); // not destructive // do the pushing TransducerGraph result = PushLambdas(graph, lambda); // creates a new one return(result); }
public static TransducerGraph CreateGraphFromPaths <T>(ClassicCounter <IList <T> > pathCounter, int markovOrder) { TransducerGraph graph = new TransducerGraph(); // empty foreach (IList <T> path in pathCounter.KeySet()) { double count = pathCounter.GetCount(path); AddOnePathToGraph(path, count, markovOrder, graph); } return(graph); }
public static bool TestGraphPaths(TransducerGraph sourceGraph, TransducerGraph testGraph, int numPaths) { for (int i = 0; i < numPaths; i++) { IList path = sourceGraph.SampleUniformPathFromGraph(); double score = sourceGraph.GetOutputOfPathInGraph(path); double newScore = testGraph.GetOutputOfPathInGraph(path); if ((score - newScore) / (score + newScore) > 1e-10) { System.Console.Out.WriteLine("Problem: " + score + " vs. " + newScore + " on " + path); return(false); } } return(true); }
/// <summary>Takes time linear in number of arcs.</summary> public virtual TransducerGraph PushLambdas(TransducerGraph graph, ClassicCounter lambda) { TransducerGraph result = null; result = graph.Clone(); // arcs have been copied too so we don't mess up graph ICollection <TransducerGraph.Arc> arcs = result.GetArcs(); foreach (TransducerGraph.Arc arc in arcs) { double sourceLambda = lambda.GetCount(arc.GetSourceNode()); double targetLambda = lambda.GetCount(arc.GetTargetNode()); double oldOutput = ((double)arc.GetOutput()); double newOutput = oldOutput + targetLambda - sourceLambda; arc.SetOutput(newOutput); } // do initialOutput double startLambda = lambda.GetCount(result.GetStartNode()); if (startLambda != 0.0) { // add it back to the outbound arcs from start (instead of adding it to the initialOutput) ICollection <TransducerGraph.Arc> startArcs = result.GetArcsBySource(result.GetStartNode()); foreach (TransducerGraph.Arc arc_1 in startArcs) { double oldOutput = ((double)arc_1.GetOutput()); double newOutput = oldOutput + startLambda; arc_1.SetOutput(newOutput); } } // do finalOutput foreach (object o in result.GetEndNodes()) { double endLambda = lambda.GetCount(o); if (endLambda != 0.0) { // subtract it from the inbound arcs to end (instead of subtracting it from the finalOutput) ICollection <TransducerGraph.Arc> endArcs = result.GetArcsByTarget(o); foreach (TransducerGraph.Arc arc_1 in endArcs) { double oldOutput = ((double)arc_1.GetOutput()); double newOutput = oldOutput - endLambda; arc_1.SetOutput(newOutput); } } } return(result); }
/// <summary>For testing only.</summary> public static void Main(string[] args) { IList pathList = new ArrayList(); TransducerGraph graph = CreateRandomGraph(1000, 10, 0.0, 10, pathList); System.Console.Out.WriteLine("Done creating random graph"); PrintPathOutputs(pathList, graph, true); System.Console.Out.WriteLine("Depth first search from start node"); StringBuilder b = new StringBuilder(); graph.DepthFirstSearch(true, b); System.Console.Out.WriteLine(b.ToString()); b = new StringBuilder(); System.Console.Out.WriteLine("Depth first search back from end node"); graph.DepthFirstSearch(false, b); System.Console.Out.WriteLine(b.ToString()); }
public static void Main(string[] args) { /* * TransducerGraph fa = new TransducerGraph(); * fa.addArc(fa.getStartNode(),"1","a",""); * fa.addArc(fa.getStartNode(),"2","b",""); * fa.addArc(fa.getStartNode(),"3","c",""); * fa.addArc("1","4","a",""); * fa.addArc("2","4","a",""); * fa.addArc("3","5","c",""); * fa.addArc("4",fa.getEndNode(),"c",""); * fa.addArc("5",fa.getEndNode(),"c",""); * System.out.println(fa); * ExactAutomatonMinimizer minimizer = new ExactAutomatonMinimizer(); * System.out.println(minimizer.minimizeFA(fa)); */ System.Console.Out.WriteLine("Starting minimizer test..."); IList pathList = new ArrayList(); TransducerGraph randomFA = TransducerGraph.CreateRandomGraph(5000, 5, 1.0, 5, pathList); IList outputs = randomFA.GetPathOutputs(pathList); TransducerGraph.IGraphProcessor quasiDeterminizer = new QuasiDeterminizer(); IAutomatonMinimizer minimizer = new FastExactAutomatonMinimizer(); TransducerGraph.INodeProcessor ntsp = new TransducerGraph.SetToStringNodeProcessor(new PennTreebankLanguagePack()); TransducerGraph.IArcProcessor isp = new TransducerGraph.InputSplittingProcessor(); TransducerGraph.IArcProcessor ocp = new TransducerGraph.OutputCombiningProcessor(); TransducerGraph detGraph = quasiDeterminizer.ProcessGraph(randomFA); TransducerGraph combGraph = new TransducerGraph(detGraph, ocp); // combine outputs into inputs TransducerGraph result = minimizer.MinimizeFA(combGraph); // minimize the thing System.Console.Out.WriteLine("Minimized from " + randomFA.GetNodes().Count + " to " + result.GetNodes().Count); result = new TransducerGraph(result, ntsp); // pull out strings from sets returned by minimizer result = new TransducerGraph(result, isp); // split outputs from inputs IList minOutputs = result.GetPathOutputs(pathList); System.Console.Out.WriteLine("Equal? " + outputs.Equals(minOutputs)); }
public static void Main(string[] args) { TransducerGraph.IGraphProcessor qd = new QuasiDeterminizer(); IList pathList = new ArrayList(); TransducerGraph graph = TransducerGraph.CreateRandomGraph(1000, 10, 1.0, 10, pathList); StringBuilder b = new StringBuilder(); graph.DepthFirstSearch(true, b); System.Console.Out.WriteLine(b.ToString()); System.Console.Out.WriteLine("Done creating random graph"); // TransducerGraph.printPathOutputs(pathList, graph, false); //System.out.println("Depth first search from start node"); //TransducerGraph.depthFirstSearch(graph, TransducerGraph.END_NODE, new HashSet(), 0, false); TransducerGraph newGraph = qd.ProcessGraph(graph); System.Console.Out.WriteLine("Done quasi-determinizing"); //TransducerGraph.printPathOutputs(pathList, newGraph, false); //System.out.println("Depth first search from start node"); //TransducerGraph.depthFirstSearch(newGraph, TransducerGraph.END_NODE, new HashSet(), 0, false); TransducerGraph.TestGraphPaths(graph, newGraph, 1000); }
/// <summary>For testing only.</summary> private static void PrintPathOutputs(IList <IList> pathList, TransducerGraph graph, bool printPaths) { int i = 0; foreach (IList path in pathList) { if (printPaths) { foreach (object aPath in path) { System.Console.Out.Write(aPath + " "); } } else { System.Console.Out.Write(i++ + " "); } System.Console.Out.Write("output: " + graph.GetOutputOfPathInGraph(path)); System.Console.Out.WriteLine(); } }
/// <summary>Takes time linear in number of arcs.</summary> public static ClassicCounter ComputeLambda(TransducerGraph graph) { ArrayList queue = new ArrayList(); ClassicCounter lambda = new ClassicCounter(); ClassicCounter length = new ClassicCounter(); IDictionary first = new Hashtable(); ISet nodes = graph.GetNodes(); foreach (object node in nodes) { lambda.SetCount(node, 0); length.SetCount(node, double.PositiveInfinity); } ISet endNodes = graph.GetEndNodes(); foreach (object o in endNodes) { lambda.SetCount(o, 0); length.SetCount(o, 0); queue.AddLast(o); } // Breadth first search // get the first node from the queue object node_1 = null; try { node_1 = queue.RemoveFirst(); } catch (NoSuchElementException) { } while (node_1 != null) { double oldLen = length.GetCount(node_1); ISet arcs = graph.GetArcsByTarget(node_1); if (arcs != null) { foreach (object arc1 in arcs) { TransducerGraph.Arc arc = (TransducerGraph.Arc)arc1; object newNode = arc.GetSourceNode(); IComparable a = (IComparable)arc.GetInput(); double k = ((double)arc.GetOutput()); double newLen = length.GetCount(newNode); if (newLen == double.PositiveInfinity) { // we are discovering this queue.AddLast(newNode); } IComparable f = (IComparable)first[newNode]; if (newLen == double.PositiveInfinity || (newLen == oldLen + 1 && a.CompareTo(f) < 0)) { // f can't be null, since we have a newLen // we do this to this to newNode when we have new info, possibly many times first[newNode] = a; // ejecting old one if necessary length.SetCount(newNode, oldLen + 1); // this may already be the case lambda.SetCount(newNode, k + lambda.GetCount(node_1)); } } } // get a new node from the queue node_1 = null; try { node_1 = queue.RemoveFirst(); } catch (NoSuchElementException) { } } return(lambda); }
// assumes that the path already has EPSILON as the last element. public static void AddOnePathToGraph(IList path, double count, int markovOrder, TransducerGraph graph) { object source = graph.GetStartNode(); for (int j = 0; j < path.Count; j++) { object input = path[j]; TransducerGraph.Arc a = graph.GetArcBySourceAndInput(source, input); if (a != null) { // increment the arc weight a.output = ((double)a.output) + count; } else { object target; if (input.Equals(TransducerGraph.EpsilonInput)) { target = "END"; } else { // to ensure they all share the same end node if (markovOrder == 0) { // we all transition back to the same state target = source; } else { if (markovOrder > 0) { // the state is described by the partial history target = path.SubList((j < markovOrder ? 0 : j - markovOrder + 1), j + 1); } else { // the state is described by the full history target = path.SubList(0, j + 1); } } } double output = count; a = new TransducerGraph.Arc(source, target, input, output); graph.AddArc(a); } source = a.GetTargetNode(); } graph.SetEndNode(source); }