X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fmatching%2FCanonicalizingMatchingStrategy.java;h=5ceb87b6ad0728efa51484a157531b3909e3e4f7;hb=aab6399f20c07b61a0dbf9614614f44a2e0ea325;hp=06ecb3c3e604c2eb43f8befbc1dc840f15ac9317;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/matching/CanonicalizingMatchingStrategy.java b/bundles/org.simantics.graph/src/org/simantics/graph/matching/CanonicalizingMatchingStrategy.java index 06ecb3c3e..5ceb87b6a 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/matching/CanonicalizingMatchingStrategy.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/matching/CanonicalizingMatchingStrategy.java @@ -1,412 +1,412 @@ -package org.simantics.graph.matching; - -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.TIntHashSet; - -import java.util.Arrays; -import java.util.Comparator; - -import org.simantics.databoard.binding.mutable.Variant; - -public enum CanonicalizingMatchingStrategy implements GraphMatchingStrategy { - INSTANCE; - - private static class Vertex { - int graph; - int original; - int pos; - Stat[] stats; - - public Vertex(int graph, int original, int pos, Stat[] stats) { - this.graph = graph; - this.original = original; - this.pos = pos; - this.stats = stats; - } - } - - private static final Comparator VERTEX_COMPARATOR = new Comparator() { - @Override - public int compare(Vertex o1, Vertex o2) { - int pos1 = o1.pos; - int pos2 = o2.pos; - if(pos1 < pos2) - return -1; - if(pos1 > pos2) - return 1; - Stat[] stats1 = o1.stats; - Stat[] stats2 = o2.stats; - if(stats1.length < stats2.length) - return -1; - if(stats1.length > stats2.length) - return 1; - for(int i=0;i o2.graph) - return 1; - if(o1.original < o2.original) - return -1; - if(o1.original > o2.original) - return 1; - return 0; - } - }; - - private static int[] generateMapA(int[] aToB) { - int[] map = new int[aToB.length]; - for(int i=0;i= 0) - map[i] = -1 - c; - else - map[i] = 0; - } - return map; - } - - private static int[] generateMapB(int[] bToA) { - int[] map = new int[bToA.length]; - for(int i=0;i= 0) - map[i] = -1 - i; - else - map[i] = 0; - } - return map; - } - - private static Vertex[] generateVertices(int graph, int[] map, Stat[][] statements) { - int size = 0; - for(int s=0;s { - @Override - protected boolean equals(Object one, Object two) { - return Arrays.equals((byte[])one, (byte[])two); - } - - @Override - protected int hash(Object obj) { - return Arrays.hashCode((byte[])obj); - } - } - - private boolean separateByValues(Vertex[] can, int begin, int end, Variant[] aValues, Variant[] bValues) { - int valueCount = 0; - TObjectIntHashMap valueIds = new TObjectIntHashMap(); - int[] ids = new int[end-begin]; - for(int i=begin;i 1) { - Vertex[] vs = Arrays.copyOfRange(can, begin, end); - int[] temp = new int[valueCount]; - for(int id : ids) - ++temp[id]; - int cur = begin; - for(int i=0;i 2) - modified |= separateByValues(can, begin, end, aValues, bValues); - } - return modified; - } - - private boolean hasBigGroups(Vertex[] can, int[] groupPos) { - for(int i=0;i 2 && can[begin].graph == 0 && can[end-1].graph == 1) - return true; - } - return false; - } - - static class UnionFind { - int[] canonical; - - public UnionFind(int size) { - canonical = new int[size]; - for(int i=0;i= 0) - uf.merge(i, stat.p); - if(stat.o >= 0) - uf.merge(i, stat.o); - } - } - - TIntHashSet done = new TIntHashSet(); - for(int i=0;i 2 && can[begin].graph == 0 && can[end-1].graph == 1) { - int c = uf.canonical(begin); - if(done.add(c)) { - int middle = begin+1; - while(can[middle].graph==0) - ++middle; - int j; - for(j=0;begin+j < middle && middle+j < end;++j) { - can[begin+j].pos = begin + j*2; - can[middle+j].pos = begin + j*2; - } - int pos = begin+j*2; - for(;begin+j < middle;++j) - can[begin+j].pos = pos; - for(;middle+j < end;++j) - can[middle+j].pos = pos; - } - } - } - } - - @Override - public void applyTo(GraphMatching matching) { - if(matching.size == matching.aGraph.resourceCount || - matching.size == matching.bGraph.resourceCount) - return; - long begin1 = System.nanoTime(); - int[] aMap = generateMapA(matching.aToB); - int[] bMap = generateMapB(matching.bToA); - Vertex[] aVertices = generateVertices(0, - aMap, matching.aGraph.statements); - Vertex[] bVertices = generateVertices(1, - bMap, matching.bGraph.statements); - Vertex[] can = concat(aVertices, bVertices); - if(GraphMatching.TIMING) - System.out.println(" Init: " + (System.nanoTime()-begin1)*1e-6 + "ms"); - - int[] groupPos = null; - boolean doneSeparationByValues = false; - while(true) { - long begin2 = System.nanoTime(); - Arrays.sort(can, VERTEX_COMPARATOR); - if(GraphMatching.TIMING) - System.out.println(" Sort: " + (System.nanoTime()-begin2)*1e-6 + "ms"); - - long begin3 = System.nanoTime(); - if(!updatePositions(can)) { - groupPos = groupPositions(can); - if(!hasBigGroups(can, groupPos)) - break; - - boolean modified = false; - if(!doneSeparationByValues) { - modified = separateByValues(can, groupPos, matching.aGraph.values, matching.bGraph.values); - doneSeparationByValues = true; - if(GraphMatching.TIMING) - System.out.println(" - separate by values"); - } - - if(!modified) { - guessIsomorphism(can, groupPos); - if(GraphMatching.TIMING) - System.out.println(" - guess isomorphism"); - } - } - if(GraphMatching.TIMING) - System.out.println(" Update1: " + (System.nanoTime()-begin3)*1e-6 + "ms"); - - long begin4 = System.nanoTime(); - updateMap(aVertices, aMap); - updateMap(bVertices, bMap); - if(GraphMatching.TIMING) - System.out.println(" Update2: " + (System.nanoTime()-begin4)*1e-6 + "ms"); - long begin5 = System.nanoTime(); - updateVertices(aVertices, aMap, matching.aGraph.statements); - updateVertices(bVertices, bMap, matching.bGraph.statements); - if(GraphMatching.TIMING) - System.out.println(" Update3: " + (System.nanoTime()-begin5)*1e-6 + "ms"); - } - - for(int i=0;i 2) { - System.out.println("----"); - for(int j=begin;j VERTEX_COMPARATOR = new Comparator() { + @Override + public int compare(Vertex o1, Vertex o2) { + int pos1 = o1.pos; + int pos2 = o2.pos; + if(pos1 < pos2) + return -1; + if(pos1 > pos2) + return 1; + Stat[] stats1 = o1.stats; + Stat[] stats2 = o2.stats; + if(stats1.length < stats2.length) + return -1; + if(stats1.length > stats2.length) + return 1; + for(int i=0;i o2.graph) + return 1; + if(o1.original < o2.original) + return -1; + if(o1.original > o2.original) + return 1; + return 0; + } + }; + + private static int[] generateMapA(int[] aToB) { + int[] map = new int[aToB.length]; + for(int i=0;i= 0) + map[i] = -1 - c; + else + map[i] = 0; + } + return map; + } + + private static int[] generateMapB(int[] bToA) { + int[] map = new int[bToA.length]; + for(int i=0;i= 0) + map[i] = -1 - i; + else + map[i] = 0; + } + return map; + } + + private static Vertex[] generateVertices(int graph, int[] map, Stat[][] statements) { + int size = 0; + for(int s=0;s { + @Override + protected boolean equals(Object one, Object two) { + return Arrays.equals((byte[])one, (byte[])two); + } + + @Override + protected int hash(Object obj) { + return Arrays.hashCode((byte[])obj); + } + } + + private boolean separateByValues(Vertex[] can, int begin, int end, Variant[] aValues, Variant[] bValues) { + int valueCount = 0; + TObjectIntHashMap valueIds = new TObjectIntHashMap(); + int[] ids = new int[end-begin]; + for(int i=begin;i 1) { + Vertex[] vs = Arrays.copyOfRange(can, begin, end); + int[] temp = new int[valueCount]; + for(int id : ids) + ++temp[id]; + int cur = begin; + for(int i=0;i 2) + modified |= separateByValues(can, begin, end, aValues, bValues); + } + return modified; + } + + private boolean hasBigGroups(Vertex[] can, int[] groupPos) { + for(int i=0;i 2 && can[begin].graph == 0 && can[end-1].graph == 1) + return true; + } + return false; + } + + static class UnionFind { + int[] canonical; + + public UnionFind(int size) { + canonical = new int[size]; + for(int i=0;i= 0) + uf.merge(i, stat.p); + if(stat.o >= 0) + uf.merge(i, stat.o); + } + } + + TIntHashSet done = new TIntHashSet(); + for(int i=0;i 2 && can[begin].graph == 0 && can[end-1].graph == 1) { + int c = uf.canonical(begin); + if(done.add(c)) { + int middle = begin+1; + while(can[middle].graph==0) + ++middle; + int j; + for(j=0;begin+j < middle && middle+j < end;++j) { + can[begin+j].pos = begin + j*2; + can[middle+j].pos = begin + j*2; + } + int pos = begin+j*2; + for(;begin+j < middle;++j) + can[begin+j].pos = pos; + for(;middle+j < end;++j) + can[middle+j].pos = pos; + } + } + } + } + + @Override + public void applyTo(GraphMatching matching) { + if(matching.size == matching.aGraph.resourceCount || + matching.size == matching.bGraph.resourceCount) + return; + long begin1 = System.nanoTime(); + int[] aMap = generateMapA(matching.aToB); + int[] bMap = generateMapB(matching.bToA); + Vertex[] aVertices = generateVertices(0, + aMap, matching.aGraph.statements); + Vertex[] bVertices = generateVertices(1, + bMap, matching.bGraph.statements); + Vertex[] can = concat(aVertices, bVertices); + if(GraphMatching.TIMING) + System.out.println(" Init: " + (System.nanoTime()-begin1)*1e-6 + "ms"); + + int[] groupPos = null; + boolean doneSeparationByValues = false; + while(true) { + long begin2 = System.nanoTime(); + Arrays.sort(can, VERTEX_COMPARATOR); + if(GraphMatching.TIMING) + System.out.println(" Sort: " + (System.nanoTime()-begin2)*1e-6 + "ms"); + + long begin3 = System.nanoTime(); + if(!updatePositions(can)) { + groupPos = groupPositions(can); + if(!hasBigGroups(can, groupPos)) + break; + + boolean modified = false; + if(!doneSeparationByValues) { + modified = separateByValues(can, groupPos, matching.aGraph.values, matching.bGraph.values); + doneSeparationByValues = true; + if(GraphMatching.TIMING) + System.out.println(" - separate by values"); + } + + if(!modified) { + guessIsomorphism(can, groupPos); + if(GraphMatching.TIMING) + System.out.println(" - guess isomorphism"); + } + } + if(GraphMatching.TIMING) + System.out.println(" Update1: " + (System.nanoTime()-begin3)*1e-6 + "ms"); + + long begin4 = System.nanoTime(); + updateMap(aVertices, aMap); + updateMap(bVertices, bMap); + if(GraphMatching.TIMING) + System.out.println(" Update2: " + (System.nanoTime()-begin4)*1e-6 + "ms"); + long begin5 = System.nanoTime(); + updateVertices(aVertices, aMap, matching.aGraph.statements); + updateVertices(bVertices, bMap, matching.bGraph.statements); + if(GraphMatching.TIMING) + System.out.println(" Update3: " + (System.nanoTime()-begin5)*1e-6 + "ms"); + } + + for(int i=0;i 2) { + System.out.println("----"); + for(int j=begin;j