protected TransducerGraph buildMinimizedFA() { TransducerGraph minimizedFA = new TransducerGraph(); TransducerGraph unminimizedFA = getUnminimizedFA(); for (TransducerGraph.Arc arc : unminimizedFA.getArcs()) { Object source = projectNode(arc.getSourceNode()); Object target = projectNode(arc.getTargetNode()); try { if (minimizedFA.canAddArc(source, target, arc.getInput(), arc.getOutput())) { minimizedFA.addArc(source, target, arc.getInput(), arc.getOutput()); } } catch (Exception e) { //throw new IllegalArgumentException(); } } minimizedFA.setStartNode(projectNode(unminimizedFA.getStartNode())); for (Object o : unminimizedFA.getEndNodes()) { minimizedFA.setEndNode(projectNode(o)); } return minimizedFA; }
public static <T> TransducerGraph createGraphFromPaths(ClassicCounter<List<T>> pathCounter, int markovOrder) { TransducerGraph graph = new TransducerGraph(); // empty for (List<T> path : pathCounter.keySet()) { double count = pathCounter.getCount(path); addOnePathToGraph(path, count, markovOrder, graph); } return graph; }
try { w = new PrintWriter(new FileWriter(file)); String dotString = graph.asDOTString(); w.print(dotString); w.flush();
public void depthFirstSearch(boolean forward, StringBuilder b) { if (forward) { depthFirstSearchHelper(getStartNode(), new HashSet(), 0, true, b); } else { for (Object o : getEndNodes()) { depthFirstSearchHelper(o, new HashSet(), 0, false, b); } } }
protected static TransducerGraph getGraphFromMap(Map<String, TransducerGraph> m, String o) { TransducerGraph graph = m.get(o); if (graph == null) { graph = new TransducerGraph(); graph.setEndNode(o); m.put(o, graph); } return graph; }
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", "6", "c", ""); fa.addArc("5", "6", "c", ""); fa.setEndNode("6"); System.out.println(fa); ExactAutomatonMinimizer minimizer = new ExactAutomatonMinimizer(); System.out.println(minimizer.minimizeFA(fa)); System.out.println("Starting..."); Timing.startTime(); TransducerGraph randomFA = TransducerGraph.createRandomGraph(100, 10, 1.0, 10, new ArrayList()); TransducerGraph minimizedRandomFA = minimizer.minimizeFA(randomFA); System.out.println(randomFA); System.out.println(minimizedRandomFA); Timing.tick("done. ( " + randomFA.getArcs().size() + " arcs to " + minimizedRandomFA.getArcs().size() + " arcs)"); }
result = graph.clone(); // arcs have been copied too so we don't mess up graph } catch (CloneNotSupportedException cnse) { throw new RuntimeException(cnse); Set<TransducerGraph.Arc> arcs = result.getArcs(); for (TransducerGraph.Arc arc : arcs) { double sourceLambda = lambda.getCount(arc.getSourceNode()); double startLambda = lambda.getCount(result.getStartNode()); if (startLambda != 0.0) { Set<TransducerGraph.Arc> startArcs = result.getArcsBySource(result.getStartNode()); for (TransducerGraph.Arc arc : startArcs) { double oldOutput = ((Double) arc.getOutput()).doubleValue(); for (Object o : result.getEndNodes()) { double endLambda = lambda.getCount(o); if (endLambda != 0.0) { Set<TransducerGraph.Arc> endArcs = result.getArcsByTarget(o); for (TransducerGraph.Arc arc : endArcs) { double oldOutput = ((Double) arc.getOutput()).doubleValue();
public static void addOnePathToGraph(List path, double count, int markovOrder, TransducerGraph graph) { Object source = graph.getStartNode(); for (int j = 0; j < path.size(); j++) { Object input = path.get(j); Arc a = graph.getArcBySourceAndInput(source, input); if (a != null) { // increment the arc weight a.output = new Double(((Double) a.output).doubleValue() + count); } else { Object target; if (input.equals(TransducerGraph.EPSILON_INPUT)) { target = "END"; // to ensure they all share the same end node } else 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 = new Double(count); a = new Arc(source, target, input, output); graph.addArc(a); } source = a.getTargetNode(); } graph.setEndNode(source); }
Set<Arc> arcs; if (forward) { arcs = this.getArcsBySource(node); } else { arcs = this.getArcsByTarget(node); b.append(" "); if (getEndNodes().contains(newArc.getTargetNode())) { b.append(newArc + " END\n"); } else { depthFirstSearchHelper(newArc.getTargetNode(), marked, level + 1, forward, b); } else { depthFirstSearchHelper(newArc.getSourceNode(), marked, level + 1, forward, b);
TransducerGraph randomFA = TransducerGraph.createRandomGraph(5000, 5, 1.0, 5, pathList); List outputs = randomFA.getPathOutputs(pathList); TransducerGraph combGraph = new TransducerGraph(detGraph, ocp); // combine outputs into inputs System.out.println("Minimized from " + randomFA.getNodes().size() + " to " + result.getNodes().size()); result = new TransducerGraph(result, ntsp); // pull out strings from sets returned by minimizer result = new TransducerGraph(result, isp); // split outputs from inputs List minOutputs = result.getPathOutputs(pathList); System.out.println("Equal? " + outputs.equals(minOutputs));
/** * For testing only. */ public static void main(String[] args) { List pathList = new ArrayList(); TransducerGraph graph = createRandomGraph(1000, 10, 0.0, 10, pathList); System.out.println("Done creating random graph"); printPathOutputs(pathList, graph, true); System.out.println("Depth first search from start node"); StringBuilder b = new StringBuilder(); graph.depthFirstSearch(true, b); System.out.println(b.toString()); b = new StringBuilder(); System.out.println("Depth first search back from end node"); graph.depthFirstSearch(false, b); System.out.println(b.toString()); }
public static void main(String[] args) { TransducerGraph.GraphProcessor qd = new QuasiDeterminizer(); List pathList = new ArrayList(); TransducerGraph graph = TransducerGraph.createRandomGraph(1000, 10, 1.0, 10, pathList); StringBuilder b = new StringBuilder(); graph.depthFirstSearch(true, b); System.out.println(b.toString()); System.out.println("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.out.println("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); }
protected boolean addOneUnaryRule(UnaryRule rule, Map<String, TransducerGraph> graphs) { String parentString = stateIndex.get(rule.parent); String childString = stateIndex.get(rule.child); if (isSyntheticState(parentString)) { String topcat = getTopCategoryOfSyntheticState(parentString); TransducerGraph graph = getGraphFromMap(graphs, topcat); Double output = new Double(smartNegate(rule.score())); graph.addArc(graph.getStartNode(), parentString, childString, output); return true; } else if (isSyntheticState(childString)) { // need to add Arc from synthetic state to endState TransducerGraph graph = getGraphFromMap(graphs, parentString); Double output = new Double(smartNegate(rule.score())); graph.addArc(childString, parentString, END, output); // parentString should the the same as endState graph.setEndNode(parentString); return true; } else { return false; } }
public TransducerGraph processGraph(TransducerGraph g) { g = new TransducerGraph(g); Set nodes = g.getNodes(); for (Object node : nodes) { Set<Arc> myArcs = null; if (forward) { myArcs = g.getArcsBySource(node); } else { myArcs = g.getArcsByTarget(node); } // compute a total double total = 0.0; for (Arc a : myArcs) { total += ((Double) a.getOutput()).doubleValue(); } // divide each by total for (Arc a : myArcs) { a.setOutput(new Double(Math.log(((Double) a.getOutput()).doubleValue() / total))); } } return g; } }
TransducerGraph result = TransducerGraph.createGraphFromPaths(newPathCounter, 1000); int numArcs = result.getArcs().size(); int numNodes = result.getNodes().size(); if (numArcs == 0) { continue; result = new TransducerGraph(result, ocp); // combine outputs into inputs result = new TransducerGraph(result, ntsp); // pull out strings from sets returned by minimizer result = new TransducerGraph(result, isp); // split outputs from inputs numArcs = result.getArcs().size(); numNodes = result.getNodes().size();
@Override protected TransducerGraph doCompaction(TransducerGraph graph, List l1, List l3) { TransducerGraph result = graph; if (saveGraphs) { writeFile(result, "unminimized", (String) result.getEndNodes().iterator().next()); } result = quasiDeterminizer.processGraph(result); result = new TransducerGraph(result, ocp); // combine outputs into inputs result = minimizer.minimizeFA(result); // minimize the thing //result = new TransducerGraph(graph, otsp); // for debugging result = new TransducerGraph(result, ntsp); // pull out strings from sets returned by minimizer result = new TransducerGraph(result, isp); // split outputs from inputs if (saveGraphs) { writeFile(result, "exactminimized", (String) result.getEndNodes().iterator().next()); } // for debugging do comparison of the paths accepted by graph and result //log.info(TransducerGraph.testGraphPaths(graph, result, 100)); return result; }
/** * @return true if and only if it created a new Arc and added it to the graph. */ public boolean addArc(Object source, Object target, Object input, Object output) { Arc a = new Arc(source, target, input, output); return addArc(a); }
/** * For testing only. All paths will be added to pathList as Lists. * // generate a bunch of paths through the graph with the input alphabet * // and create new nodes for each one. */ public static TransducerGraph createRandomGraph(int numPaths, int pathLengthMean, double pathLengthVariance, int numInputs, List pathList) { // compute the path length. Draw from a normal distribution int pathLength = (int) (r.nextGaussian() * pathLengthVariance + pathLengthMean); for (int i = 0; i < numPaths; i++) { // make a path List path = new ArrayList(); for (int j = 0; j < pathLength; j++) { String input = Integer.toString(r.nextInt(numInputs)); path.add(input); } // TODO: createRandomPaths had the following difference: // we're done, add one more arc to get to the endNode. //input = TransducerGraph.EPSILON_INPUT; //path.add(input); pathList.add(path); } return createGraphFromPaths(pathList, -1); }
@Override public String toString() { StringBuilder sb = new StringBuilder(); depthFirstSearch(true, sb); return sb.toString(); }
@Override public TransducerGraph clone() throws CloneNotSupportedException { super.clone(); TransducerGraph result = new TransducerGraph(this, (ArcProcessor) null); return result; }