diff --git a/src/main/java/org/fujaba/graphengine/GraphEngine.java b/src/main/java/org/fujaba/graphengine/GraphEngine.java index 4e102db..121fa11 100644 --- a/src/main/java/org/fujaba/graphengine/GraphEngine.java +++ b/src/main/java/org/fujaba/graphengine/GraphEngine.java @@ -12,7 +12,8 @@ import org.fujaba.graphengine.graph.adapter.GraphToSigmaJsAdapter; import org.fujaba.graphengine.graph.adapter.NodeAdapter; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandler; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPWithHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPHighHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPLowHeuristics; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerSorting; import org.fujaba.graphengine.isomorphismtools.sort.NodeSortTree; import org.fujaba.graphengine.isomorphismtools.sort.adapter.NodeSortTreeAdapter; @@ -51,7 +52,7 @@ public static void setMainIsomorphismHandler(IsomorphismHandler isomorphismHandl */ public static IsomorphismHandler getMainIsomorphismHandler() { if (mainIsomorphismHandler == null) { - mainIsomorphismHandler = new IsomorphismHandlerCSPWithHeuristics(); + mainIsomorphismHandler = new IsomorphismHandlerCSPLowHeuristics(); } return mainIsomorphismHandler; } @@ -61,7 +62,7 @@ public static IsomorphismHandler getMainIsomorphismHandler() { */ public static IsomorphismHandler getMappingFallback() { if (mappingFallback == null) { - mappingFallback = new IsomorphismHandlerCSPWithHeuristics(); + mappingFallback = new IsomorphismHandlerCSPLowHeuristics(); } return mappingFallback; } @@ -81,7 +82,7 @@ public static IsomorphismHandler getNormalizationFallback() { */ public static IsomorphismHandler getSplitGraphFallback() { if (splitGraphFallback == null) { - splitGraphFallback = new IsomorphismHandlerCSPWithHeuristics(); + splitGraphFallback = new IsomorphismHandlerCSPLowHeuristics(); } return splitGraphFallback; } diff --git a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithMoreHeuristics.java b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPHighHeuristics.java similarity index 79% rename from src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithMoreHeuristics.java rename to src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPHighHeuristics.java index 7b336ca..07c1d8e 100644 --- a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithMoreHeuristics.java +++ b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPHighHeuristics.java @@ -9,7 +9,7 @@ import org.fujaba.graphengine.graph.Node; import org.fujaba.graphengine.isomorphismtools.heuristics.NodeWithConflict; -public class IsomorphismHandlerCSPWithMoreHeuristics extends IsomorphismHandler { +public abstract class IsomorphismHandlerCSPHighHeuristics extends IsomorphismHandler { private static ArrayList getDepthFirstSortedNodeList(Graph graph) { // obtain all parts of the graph - where each part's nodes are connected with each other: @@ -42,10 +42,10 @@ public HashMap mappingFrom(Graph subGraphInitial, Graph baseGraph) { } // now I'm trying to find 'loosely matched candidates': Graph subGraph = subGraphInitial.clone(); - ArrayList> couldMatch2 = new ArrayList>(); + ArrayList> couldMatch = new ArrayList>(); for (int i = 0; i < subGraph.getNodes().size(); ++i) { Node subNode = subGraph.getNodes().get(i); - couldMatch2.add(new ArrayList()); + couldMatch.add(new ArrayList()); nodeMatch: for (int j = 0; j < baseGraph.getNodes().size(); ++j) { Node node = baseGraph.getNodes().get(j); // check existence of outgoing edges and their count: @@ -62,68 +62,24 @@ public HashMap mappingFrom(Graph subGraphInitial, Graph baseGraph) { continue nodeMatch; } } - couldMatch2.get(couldMatch2.size() - 1).add(node); + couldMatch.get(couldMatch.size() - 1).add(node); } - if (couldMatch2.get(couldMatch2.size() - 1).size() == 0) { + if (couldMatch.get(couldMatch.size() - 1).size() == 0) { return null; // no mapping for this node => fail } } - couldMatch2 = removeImpossibleCandidates(couldMatch2); - if (couldMatch2 == null) { + couldMatch = removeImpossibleCandidates(couldMatch); + if (couldMatch == null) { // after removing 'impossible' candidates, there's no match anymore => fail return null; } if (subGraph.getNodes().size() == 1) { // a single node with a candidate is a match => success HashMap singleNodeMapping = new HashMap(); - singleNodeMapping.put(subGraph.getNodes().get(0), couldMatch2.get(0).get(0)); + singleNodeMapping.put(subGraph.getNodes().get(0), couldMatch.get(0).get(0)); return singleNodeMapping; } - /* - * here I'm starting the application of the heuristics of the maximum restricted variable (H1) and the minimum node order (H2): - */ - // first save the old order of the matches: - HashMap oldIndices = new HashMap(); - for (int i = 0; i < subGraph.getNodes().size(); ++i) { - oldIndices.put(subGraph.getNodes().get(i), i); - } - // now check for the maximum restricted variables (H1): - ArrayList minimumIndices = new ArrayList(); - int minimumValue = Integer.MAX_VALUE; - for (int i = 0; i < subGraph.getNodes().size(); ++i) { // minimum candidates - if (couldMatch2.get(i).size() <= minimumValue) { - if (couldMatch2.get(i).size() < minimumValue) { - minimumIndices = new ArrayList(); - minimumValue = couldMatch2.get(i).size(); - } - minimumIndices.add(i); - } - } - // now check within those for the minimum node order (H2): - int indicesIndex = -1; - minimumValue = Integer.MAX_VALUE; - for (int i = 0; i < minimumIndices.size(); ++i) { // minimum node order (outgoing) - int outgoingCount = 0; - Node currentNode = subGraph.getNodes().get(minimumIndices.get(i)); - for (String key: currentNode.getEdges().keySet()) { - outgoingCount += currentNode.getEdges(key).size(); - } - if (outgoingCount < minimumValue) { - minimumValue = outgoingCount; - indicesIndex = i; - } - } - // here we have the 'best' node to start with: - Node heuristicallySelectedFirstNode = subGraph.getNodes().get(minimumIndices.get(indicesIndex)); - subGraph.getNodes().remove(heuristicallySelectedFirstNode); // remove from old position - subGraph.getNodes().add(0, heuristicallySelectedFirstNode); // put in front - // now order the nodes in a depth-first fashion, with the heuristically selected first node as 'root': ArrayList sortedNodes = getDepthFirstSortedNodeList(subGraph); - // restore the matches to the new order: - ArrayList> couldMatch = new ArrayList>(); - for (int i = 0; i < sortedNodes.size(); ++i) { - couldMatch.add(couldMatch2.get(oldIndices.get(sortedNodes.get(i)))); - } // and build candidates into objects, that contain an additional conflict-value and are sortable ArrayList> couldMatchWithConflict = new ArrayList>(); for (int i = 0; i < couldMatch.size(); ++i) { @@ -164,13 +120,13 @@ public HashMap mappingFrom(Graph subGraphInitial, Graph baseGraph) { * here I'm starting the application of the heuristics of the maximum restricted variable (H1) and the minimum node order (H2): */ // first save the old order of the matches: - oldIndices = new HashMap(); + HashMap oldIndices = new HashMap(); for (int i = 0; i < sortedNodes.size(); ++i) { oldIndices.put(sortedNodes.get(i), i); } // now check for the maximum restricted variables (H1): - minimumIndices = new ArrayList(); - minimumValue = Integer.MAX_VALUE; + ArrayList minimumIndices = new ArrayList(); + int minimumValue = Integer.MAX_VALUE; for (int i = startThisHeuristicsAtIndex; i < sortedNodes.size(); ++i) { // minimum candidates if (couldMatchWithConflict.get(i).size() <= minimumValue) { if (couldMatchWithConflict.get(i).size() < minimumValue) { @@ -181,7 +137,7 @@ public HashMap mappingFrom(Graph subGraphInitial, Graph baseGraph) { } } // now check within those for the minimum node order (H2): - indicesIndex = -1; + int indicesIndex = -1; minimumValue = Integer.MAX_VALUE; for (int i = 0; i < minimumIndices.size(); ++i) { // minimum node order (outgoing) int outgoingCount = 0; @@ -195,9 +151,9 @@ public HashMap mappingFrom(Graph subGraphInitial, Graph baseGraph) { } } // here we have the 'best' node to start with: - heuristicallySelectedFirstNode = subGraph.getNodes().get(minimumIndices.get(indicesIndex)); -// sortedNodes.remove(heuristicallySelectedFirstNode); // remove from old position -// sortedNodes.add(startThisHeuristicsAtIndex, heuristicallySelectedFirstNode); // put in front + Node heuristicallySelectedFirstNode = subGraph.getNodes().get(minimumIndices.get(indicesIndex)); + sortedNodes.remove(heuristicallySelectedFirstNode); // remove from old position + sortedNodes.add(startThisHeuristicsAtIndex, heuristicallySelectedFirstNode); // put in front // restore the matches to the new order: ArrayList> couldMatchWithConflict2 = new ArrayList>(); for (int i = 0; i < sortedNodes.size(); ++i) { diff --git a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithHeuristics.java b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPLowHeuristics.java similarity index 96% rename from src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithHeuristics.java rename to src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPLowHeuristics.java index b0e854d..86801ac 100644 --- a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPWithHeuristics.java +++ b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSPLowHeuristics.java @@ -7,7 +7,7 @@ import org.fujaba.graphengine.graph.Graph; import org.fujaba.graphengine.graph.Node; -public class IsomorphismHandlerCSPWithHeuristics extends IsomorphismHandler { +public class IsomorphismHandlerCSPLowHeuristics extends IsomorphismHandler { private static ArrayList getDepthFirstSortedNodeList(Graph graph) { // obtain all parts of the graph - where each part's nodes are connected with each other: diff --git a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSP.java b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerDepthFirstBacktracking.java similarity index 96% rename from src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSP.java rename to src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerDepthFirstBacktracking.java index 11374d1..797d8a3 100644 --- a/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerCSP.java +++ b/src/main/java/org/fujaba/graphengine/isomorphismtools/IsomorphismHandlerDepthFirstBacktracking.java @@ -7,7 +7,7 @@ import org.fujaba.graphengine.graph.Graph; import org.fujaba.graphengine.graph.Node; -public class IsomorphismHandlerCSP extends IsomorphismHandler { +public class IsomorphismHandlerDepthFirstBacktracking extends IsomorphismHandler { private static ArrayList getDepthFirstSortedNodeList(Graph graph) { // obtain all parts of the graph - where each part's nodes are connected with each other: diff --git a/src/test/java/org/fujaba/graphengine/unitTests/GraphTest.java b/src/test/java/org/fujaba/graphengine/unitTests/GraphTest.java index 0e3a2fb..8e7865e 100644 --- a/src/test/java/org/fujaba/graphengine/unitTests/GraphTest.java +++ b/src/test/java/org/fujaba/graphengine/unitTests/GraphTest.java @@ -7,7 +7,7 @@ import org.fujaba.graphengine.graph.Graph; import org.fujaba.graphengine.graph.Node; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandler; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPWithHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPLowHeuristics; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCombinatorial; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerSorting; import org.junit.Assert; @@ -367,7 +367,7 @@ public void testIsomorphismTestGraph() { IsomorphismHandler isomorphismHandler = null; // isomorphismHandler = GraphEngine.getMainIsomorphismHandler(); -// isomorphismHandler = new IsomorphismHandlerCSPWithHeuristics(); +// isomorphismHandler = new IsomorphismHandlerCSPLowHeuristics(); // isomorphismHandler = new IsomorphismHandlerSorting(); isomorphismHandler = new IsomorphismHandlerCombinatorial(); long start = System.nanoTime(); diff --git a/src/test/java/org/fujaba/graphengine/unitTests/PatternTest.java b/src/test/java/org/fujaba/graphengine/unitTests/PatternTest.java index b85673e..1f4a2fc 100644 --- a/src/test/java/org/fujaba/graphengine/unitTests/PatternTest.java +++ b/src/test/java/org/fujaba/graphengine/unitTests/PatternTest.java @@ -10,7 +10,7 @@ import org.fujaba.graphengine.PatternEngine; import org.fujaba.graphengine.graph.Graph; import org.fujaba.graphengine.graph.Node; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPWithHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPLowHeuristics; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerSorting; import org.fujaba.graphengine.pattern.PatternAttribute; import org.fujaba.graphengine.pattern.PatternEdge; @@ -267,9 +267,9 @@ public void testNegativePatternVariantsWithDifferentIsomorphismCheckApproaches() System.out.println("GraphEngine: " + duration + "ms"); begin = System.nanoTime(); - Assert.assertTrue(new IsomorphismHandlerCSPWithHeuristics().isIsomorphTo(carGraph, carGraphChangedNodeOrder)); + Assert.assertTrue(new IsomorphismHandlerCSPLowHeuristics().isIsomorphTo(carGraph, carGraphChangedNodeOrder)); duration = (System.nanoTime() - begin) / 1e6; - System.out.println("IsomorphismHandlerCSPWithHeuristics: " + duration + "ms"); + System.out.println("IsomorphismHandlerCSPLowHeuristics: " + duration + "ms"); begin = System.nanoTime(); Assert.assertTrue(new IsomorphismHandlerSorting().isIsomorphTo(carGraph, carGraphChangedNodeOrder)); diff --git a/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java b/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java index 3590924..d7ccc12 100644 --- a/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java +++ b/src/test/java/org/fujaba/graphengine/unitTests/RoadworkExample.java @@ -10,9 +10,9 @@ import org.fujaba.graphengine.graph.Graph; import org.fujaba.graphengine.graph.Node; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandler; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSP; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPWithHeuristics; -import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPWithMoreHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerDepthFirstBacktracking; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPLowHeuristics; +import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCSPHighHeuristics; import org.fujaba.graphengine.isomorphismtools.IsomorphismHandlerCombinatorial; import org.fujaba.graphengine.pattern.PatternAttribute; import org.fujaba.graphengine.pattern.PatternEdge; @@ -312,8 +312,8 @@ public void testRoadworkExample() { Graph reachabilityGraph; - GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerCSPWithMoreHeuristics()); - System.out.println("\nnew IsomorphismHandlerCSPWithMoreHeuristics()"); + GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerDepthFirstBacktracking()); + System.out.println("\nnew IsomorphismHandlerDepthFirstBacktracking()"); @@ -325,7 +325,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - System.out.println("\n(minimal + 1) starting to build reachability graph for RoadworkExample..."); begin = System.nanoTime(); @@ -335,7 +334,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - // System.out.println("\n(original) starting to build reachability graph for RoadworkExample..."); // begin = System.nanoTime(); @@ -345,11 +343,13 @@ public void testRoadworkExample() { // System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); // System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); // System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); + +// new GraphDumper(reachabilityGraph).dumpGraph("roadwork.html"); + + - - - GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerCSP()); - System.out.println("\nnew IsomorphismHandlerCSP()"); + GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerCSPLowHeuristics()); + System.out.println("\nnew IsomorphismHandlerCSPLowHeuristics()"); @@ -361,7 +361,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - System.out.println("\n(minimal + 1) starting to build reachability graph for RoadworkExample..."); begin = System.nanoTime(); @@ -371,7 +370,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - // System.out.println("\n(original) starting to build reachability graph for RoadworkExample..."); // begin = System.nanoTime(); @@ -382,11 +380,12 @@ public void testRoadworkExample() { // System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); // System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - // new GraphDumper(reachabilityGraph).dumpGraph("roadwork.html"); + + - GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerCSPWithHeuristics()); - System.out.println("\nnew IsomorphismHandlerCSPWithHeuristics()"); + GraphEngine.setMainIsomorphismHandler(new IsomorphismHandlerCombinatorial()); + System.out.println("\nnew IsomorphismHandlerCombinatorial()"); @@ -398,7 +397,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - System.out.println("\n(minimal + 1) starting to build reachability graph for RoadworkExample..."); begin = System.nanoTime(); @@ -408,7 +406,6 @@ public void testRoadworkExample() { System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60) + " m"); System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); - // System.out.println("\n(original) starting to build reachability graph for RoadworkExample..."); // begin = System.nanoTime(); @@ -419,7 +416,8 @@ public void testRoadworkExample() { // System.out.println("== " + ((System.nanoTime() - begin) / 1e9 / 60 / 60) + " h"); // System.out.println(reachabilityGraph.getNodes().size() + " node" + (reachabilityGraph.getNodes().size() != 1 ? "s" : "") + " in the 'reachabilityGraph'"); -// new GraphDumper(reachabilityGraph).dumpGraph("test.html"); +// new GraphDumper(reachabilityGraph).dumpGraph("roadwork.html"); + GraphEngine.prepareGraphAsJsonFileForSigmaJs( GraphEngine.getGson().fromJson(