diff --git a/src/main/java/org/fujaba/graphengine/PatternEngine.java b/src/main/java/org/fujaba/graphengine/PatternEngine.java index 110c4e9..6fc56f2 100644 --- a/src/main/java/org/fujaba/graphengine/PatternEngine.java +++ b/src/main/java/org/fujaba/graphengine/PatternEngine.java @@ -87,15 +87,16 @@ public static Graph calculateReachabilityGraph(Graph graph, ArrayList added = new ArrayList(); // a list with graphs that were added ArrayList unprocessed = new ArrayList(); // a list with currently unprocessed graphs added.add(graph); unprocessed.add(graph); + if (GraphEngine.getMainIsomorphismHandler() instanceof IsomorphismHandlerSorting) { + return calculateReachabilityGraphWithNormalForm(graph, patterns); + } + // as long as a single graph wasn't checked for successors, the search continues: while (unprocessed.size() > 0) { // looking for matches: @@ -108,13 +109,7 @@ public static Graph calculateReachabilityGraph(Graph graph, ArrayList just build edge to an existing node Node target = findGraphInReachabilityGraph(rg, successor); @@ -133,6 +128,47 @@ public static Graph calculateReachabilityGraph(Graph graph, ArrayList> patterns) { + // the first rg-node is the base-graph: + graph = GraphEngine.getMainIsomorphismHandler().normalized(graph); + Graph rg = new Graph().addNode(new Node().setAttribute("graph", graph.toString())); + ArrayList added = new ArrayList(); // a list with graphs that were added + ArrayList unprocessed = new ArrayList(); // a list with currently unprocessed graphs + added.add(graph); + unprocessed.add(graph); + // as long as a single graph wasn't checked for successors, the search continues: + while (unprocessed.size() > 0) { + // looking for matches: + ArrayList matches = calculateReachabilityNodeMatches(unprocessed.get(0), patterns); + // look up the rg-node, that represents the unprocessed graph: + Node source = findGraphInReachabilityGraph(rg, unprocessed.get(0)); + unprocessed.remove(0); + // now handle matches: + for (Match match: matches) { + // construct the graph, that's the result of this match: + Graph successor = applyMatch(match); + // check if the graph was previously added: + successor = GraphEngine.getMainIsomorphismHandler().normalized(successor); + String serializedGraph = successor.toString(); + int index = normalizedIndexOf(rg.getNodes(), serializedGraph); + if (index != -1) { + // yes, the graph already did exist => just build edge to an existing node + Node target = rg.getNodes().get(index); + source.addEdge(match.getPattern().toString(), target); // new edge + } else { + // no, the graph didn't exist before => add a new node + Node target = new Node().setAttribute("graph", serializedGraph); // new node + rg.addNode(target); + source.addEdge(match.getPattern().toString(), target); // edge to new node + added.add(successor); + unprocessed.add(successor); + } + } + } + // done + return rg; + } /** * Function to find a graph as a node inside of a reachability graph. @@ -193,10 +229,10 @@ private static int indexOf(ArrayList graphs, Graph graph) { return -1; } - private static int normalizedIndexOf(ArrayList graphs, Graph graph) { - for (int i = 0; i < graphs.size(); ++i) { - Graph g = graphs.get(i); - if (g.toString().equals(graph.toString())) { + private static int normalizedIndexOf(ArrayList nodes, String serializedGraph) { + for (int i = 0; i < nodes.size(); ++i) { + Node n = nodes.get(i); + if (n.getAttribute("graph").equals(serializedGraph)) { return i; } } diff --git a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerSorting.java b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerSorting.java index 02d618d..0461cf2 100644 --- a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerSorting.java +++ b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerSorting.java @@ -36,14 +36,43 @@ public Graph normalized(Graph graph) { nodeSortTrees.add(new NodeSortTree(graph, node)); } ArrayList nodeSortTreesCopy = null; +// // sort the list of nodeSortTrees: +// while (!nodeSortTrees.equals(nodeSortTreesCopy)) { +// nodeSortTreesCopy = (ArrayList)nodeSortTrees.clone(); +// Collections.sort(nodeSortTrees); +// for (NodeSortTree nodeSortTree: nodeSortTrees) { +// nodeSortTree.doInnerSort(nodeSortTrees); +// } +// } // sort the list of nodeSortTrees: - while (!nodeSortTrees.equals(nodeSortTreesCopy)) { - nodeSortTreesCopy = (ArrayList)nodeSortTrees.clone(); - Collections.sort(nodeSortTrees); + ArrayList nodeSortTreesStrings = new ArrayList(); + for (NodeSortTree nst: nodeSortTrees) { + nodeSortTreesStrings.add(GraphEngine.getGson().toJson(nst)); + } + ArrayList nodeSortTreesCopyStrings = null; + while (!nodeSortTreesStrings.equals(nodeSortTreesCopyStrings)) { + nodeSortTreesCopyStrings = (ArrayList)nodeSortTreesStrings.clone(); + HashMap mapping = new HashMap(); + for (NodeSortTree nst: nodeSortTrees) { + mapping.put(GraphEngine.getGson().toJson(nst), nst); + } + Collections.sort(nodeSortTreesStrings); + nodeSortTreesCopy = new ArrayList(); + for (String s: nodeSortTreesStrings) { + nodeSortTreesCopy.add(mapping.get(s)); + } + nodeSortTrees = nodeSortTreesCopy; for (NodeSortTree nodeSortTree: nodeSortTrees) { nodeSortTree.doInnerSort(nodeSortTrees); } + nodeSortTreesStrings = new ArrayList(); + for (NodeSortTree nst: nodeSortTrees) { + nodeSortTreesStrings.add(GraphEngine.getGson().toJson(nst)); + } } +// +// +// nf.getNodes().clear(); for (int i = 0; i < nodeSortTrees.size(); ++i) { Node node = nodeSortTrees.get(i).getRootNode(); diff --git a/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java b/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java index c10d5e7..cd28447 100644 --- a/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java +++ b/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java @@ -379,16 +379,16 @@ private double testRoadworkExample(boolean debug, IsomorphismHandler ih, int fro public void testRoadworkExample() { ArrayList toTest = new ArrayList(); - toTest.add(new IsomorphismHandlerParallel()); - toTest.add(new IsomorphismHandlerCombinatorial()); toTest.add(new IsomorphismHandlerCSPHighHeuristics()); toTest.add(new IsomorphismHandlerCSPLowHeuristics()); toTest.add(new IsomorphismHandlerDepthFirstBacktracking()); + toTest.add(new IsomorphismHandlerCombinatorial()); + toTest.add(new IsomorphismHandlerParallel()); toTest.add(new IsomorphismHandlerSorting()); boolean debug = false; - int fromLevel = 1; - int toLevel = 1; + int fromLevel = 2; + int toLevel = 2; boolean drawSigmaJs = false; boolean drawAlchemyJs = false;