]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/matching/ComponentMatchingStrategy.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / matching / ComponentMatchingStrategy.java
index ef354a1c3867d15cf23e71fb40d2ea4371302b35..dabd2e8df1e3e0a61c3cba5d940929caaca57c1a 100644 (file)
-package org.simantics.graph.matching;\r
-\r
-import gnu.trove.list.array.TIntArrayList;\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.map.hash.TIntIntHashMap;\r
-import gnu.trove.map.hash.TIntObjectHashMap;\r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Comparator;\r
-\r
-/**\r
- * Matches isomorphic components of the not yet matched graphs together.\r
- * \r
- * @author Hannu Niemistö\r
- */\r
-public enum ComponentMatchingStrategy implements GraphMatchingStrategy {\r
-       INSTANCE;\r
-\r
-       static class UnionFind {\r
-               int[] canonical;\r
-               \r
-               public UnionFind(int size) {\r
-                       canonical = new int[size];\r
-                       for(int i=0;i<size;++i)\r
-                               canonical[i] = i;\r
-               }\r
-               \r
-               public int canonical(int a) {\r
-                       int b = canonical[a];\r
-                       if(b != a) {\r
-                               int c = canonical[b];\r
-                               if(b != c) {\r
-                                       c = canonical(c);\r
-                                       canonical[b] = c;                                       \r
-                                       canonical[a] = c;\r
-                                       return c;\r
-                               }\r
-                       }\r
-                       return b;\r
-               }\r
-               \r
-               public void merge(int a, int b) {\r
-                       a = canonical(a);\r
-                       b = canonical(b);\r
-                       canonical[a] = b;\r
-               }\r
-       }\r
-       \r
-       public static int[][] findComponents(int[] map, Stat[][] statements, TIntIntHashMap inverses) {\r
-               int resourceCount = map.length;\r
-               \r
-               UnionFind uf = new UnionFind(resourceCount);\r
-               for(int s=0;s<resourceCount;++s)\r
-                       if(map[s] < 0) {\r
-                               for(Stat stat : statements[s]) {\r
-                                       int o = stat.o;\r
-                                       if(s < o && map[o] < 0)\r
-                                               uf.merge(s, o);\r
-                               }\r
-                               /*if(inverses.containsKey(s))\r
-                                       uf.merge(s, inverses.get(s));\r
-                                       */\r
-                       }\r
-               \r
-               TIntObjectHashMap<TIntArrayList> components = new TIntObjectHashMap<TIntArrayList>();\r
-               for(int i=0;i<resourceCount;++i)\r
-                       if(map[i] < 0) {\r
-                               int c = uf.canonical(i);\r
-                               TIntArrayList els = components.get(c);\r
-                               if(els == null) {\r
-                                       els = new TIntArrayList(2);\r
-                                       components.put(c, els);\r
-                               }\r
-                               els.add(i);\r
-                       }\r
-               \r
-               final int[][] result = new int[components.size()][];\r
-               components.forEachValue(new TObjectProcedure<TIntArrayList>() {\r
-                       int i = 0;\r
-                       @Override\r
-                       public boolean execute(TIntArrayList els) {\r
-                               result[i++] = els.toArray();\r
-                               return true;\r
-                       }\r
-               });\r
-               return result;\r
-       }       \r
-       \r
-       public static Stat[][] neighbors(int[] map, Stat[][] statements) {\r
-               int resourceCount = map.length;\r
-               Stat[][] neighbors = new Stat[resourceCount][];\r
-               \r
-               ArrayList<Stat> stats = new ArrayList<Stat>();\r
-               for(int s=0;s<resourceCount;++s) {\r
-                       if(map[s] >= 0) {\r
-                               neighbors[s] = Stat.NO_STATS;\r
-                               continue;\r
-                       }\r
-                       \r
-                       for(Stat stat : statements[s]) {\r
-                               int pp = map[stat.p] >= 0 ? stat.p : -1;\r
-                               int oo = map[stat.o] >= 0 ? stat.o : -1;                                \r
-                               stats.add(new Stat(pp, oo));\r
-                       }\r
-                       \r
-                       if(stats.isEmpty())\r
-                               neighbors[s] = Stat.NO_STATS;\r
-                       else {\r
-                               neighbors[s] = stats.toArray(new Stat[stats.size()]);\r
-                               stats.clear();\r
-                       }\r
-               }\r
-               \r
-               return neighbors;\r
-       }\r
-       \r
-       static class Component {\r
-               int[] elements;\r
-               Stat[][] neighbors;\r
-               \r
-               public Component(int[] elements, Stat[][] neighbors) {\r
-                       this.elements = elements;\r
-                       this.neighbors = new Stat[elements.length][];\r
-                       for(int i=0;i<elements.length;++i)\r
-                               this.neighbors[i] = neighbors[elements[i]];\r
-               }\r
-               \r
-               public void map(int[] map) {\r
-                       for(Stat[] stats : neighbors)\r
-                               for(Stat stat : stats)\r
-                                       stat.map(map);\r
-               }\r
-               \r
-               static class PP {\r
-                       int element;\r
-                       Stat[] stats;\r
-                       \r
-                       public PP(int element, Stat[] stats) {\r
-                               this.element = element;\r
-                               Arrays.sort(stats, Stat.STAT_COMPARATOR);\r
-                               this.stats = stats;\r
-                       }\r
-               }\r
-               \r
-               static final Comparator<PP> PP_COMPARATOR = new Comparator<PP>() {\r
-                       @Override\r
-                       public int compare(PP o1, PP o2) {\r
-                               Stat[] stats1 = o1.stats;\r
-                               Stat[] stats2 = o2.stats;\r
-                               int l1 = stats1.length;\r
-                               int l2 = stats2.length;\r
-                               if(l1 < l2)\r
-                                       return -1;\r
-                               else if(l1 > l2)\r
-                                       return 1;\r
-                               for(int i=0;i<l1;++i) {\r
-                                       Stat s1 = stats1[i];\r
-                                       Stat s2 = stats2[i];\r
-                                       if(s1.p < s2.p)\r
-                                               return -1;\r
-                                       else if(s1.p > s2.p)\r
-                                               return 1;\r
-                                       else if(s1.o < s2.o)\r
-                                               return -1;\r
-                                       else if(s1.o > s2.o)\r
-                                               return 1;\r
-                               }\r
-                               return 0;\r
-                       }                       \r
-               };\r
-               \r
-               public void canonicalize(String[] elNames, String[] statNames) {\r
-                       PP[] pps = new PP[elements.length];\r
-                       for(int i=0;i<elements.length;++i)\r
-                               pps[i] = new PP(elements[i], neighbors[i]);\r
-                       Arrays.sort(pps, PP_COMPARATOR);\r
-                       for(int i=0;i<pps.length-1;++i)\r
-                               if(PP_COMPARATOR.compare(pps[i], pps[i+1]) == 0) {\r
-                                       System.out.println("AMB " + pps.length + " " + (elNames==statNames));\r
-                                       for(i=0;i<pps.length-1;++i) {\r
-                                               if(PP_COMPARATOR.compare(pps[i], pps[i+1]) == 0)\r
-                                                       System.out.print(">   ");\r
-                                               else\r
-                                                       System.out.print("    ");\r
-                                               System.out.println(elNames[pps[i].element]);\r
-                                               for(Stat stat : pps[i].stats)\r
-                                                       System.out.println("        " + stat.toString(statNames));\r
-                                       }\r
-                                       break;\r
-                               }\r
-                       for(int i=0;i<elements.length;++i) {\r
-                               PP pp = pps[i];\r
-                               elements[i] = pp.element;\r
-                               neighbors[i] = pp.stats;\r
-                       }\r
-               }\r
-\r
-               public boolean isIsolated() {\r
-                       for(Stat[] stats : neighbors)\r
-                               if(stats.length > 0)\r
-                                       return false;\r
-                       return true;\r
-               }\r
-       }\r
-       \r
-       static class TNeighbourObjectHashMap<T> extends THashMap<Stat[][], T> {\r
-               @Override\r
-               protected boolean equals(Object one, Object two) {\r
-                       Stat[][] o1 = (Stat[][])one;\r
-                       Stat[][] o2 = (Stat[][])two;\r
-                       if(o1.length != o2.length)\r
-                               return false;\r
-                       for(int i=0;i<o1.length;++i) {\r
-                               Stat[] ss1 = o1[i];\r
-                               Stat[] ss2 = o2[i];\r
-                               if(ss1.length != ss2.length)\r
-                                       return false;\r
-                               for(int j=0;j<ss1.length;++j) {\r
-                                       Stat s1 = ss1[j];\r
-                                       Stat s2 = ss2[j];\r
-                                       if(s1.p != s2.p || s1.o != s2.o)\r
-                                               return false;\r
-                               }\r
-                       }\r
-                       return true;\r
-               }\r
-               \r
-               @Override\r
-               protected int hash(Object obj) {\r
-                       int result = 152433;\r
-                       for(Stat[] stats : (Stat[][])obj)\r
-                               for(Stat stat : stats)\r
-                                       result = (result*31 + stat.p)*31 + stat.o;\r
-                       return result;\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void applyTo(GraphMatching matching) {\r
-               System.out.println("ComponentMatchingStrategy");\r
-               TNeighbourObjectHashMap<ArrayList<int[]>> aComponents = new TNeighbourObjectHashMap<ArrayList<int[]>>(); \r
-               {                       \r
-                       Stat[][] neighbors = neighbors(matching.aToB, matching.aGraph.statements);\r
-                       //TIntIntHashMap componentSizes = new TIntIntHashMap();\r
-                       for(int[] els : findComponents(matching.aToB, matching.aGraph.statements, matching.aGraph.inverses)) {\r
-                               /*for(int el : els)\r
-                                       System.out.print(matching.aGraph.names[el] + " ");\r
-                               System.out.println();\r
-                               componentSizes.adjustOrPutValue(els.length, 1, 1);*/\r
-                               Component component = new Component(els, neighbors);\r
-                               if(component.isIsolated())\r
-                                       continue;\r
-                               component.map(matching.aToB);\r
-                               component.canonicalize(matching.aGraph.names, matching.bGraph.names);\r
-                               ArrayList<int[]> values = aComponents.get(component.neighbors);\r
-                               if(values == null) {\r
-                                       values = new ArrayList<int[]>(1);\r
-                                       aComponents.put(component.neighbors, values);\r
-                               }\r
-                               values.add(component.elements);\r
-                       }\r
-                       /*componentSizes.forEachEntry(new TIntIntProcedure() {                          \r
-                               @Override\r
-                               public boolean execute(int a, int b) {\r
-                                       System.out.println("Components of size " + a + ": " + b);\r
-                                       return true;\r
-                               }\r
-                       });*/\r
-               }\r
-               \r
-               ArrayList<Component> bComponents = new ArrayList<Component>(); \r
-               {\r
-                       Stat[][] neighbors = neighbors(matching.bToA, matching.bGraph.statements);\r
-                       for(int[] els : findComponents(matching.bToA, matching.bGraph.statements, matching.bGraph.inverses)) {\r
-                               Component component = new Component(els, neighbors);\r
-                               if(component.isIsolated())\r
-                                       continue;\r
-                               component.canonicalize(matching.bGraph.names, matching.bGraph.names);\r
-                               bComponents.add(component);\r
-                       }\r
-               }\r
-               \r
-               for(Component c : bComponents) {\r
-                       ArrayList<int[]> candidates = aComponents.get(c.neighbors);\r
-                       if(candidates != null)\r
-                               for(int i=0;i<candidates.size();++i) {\r
-                                       int[] els = candidates.get(i);\r
-                                       if(els != null) {\r
-                                               matching.map(els, c.elements);\r
-                                               if(matching.checkMatch(els, c.elements)) {\r
-                                                       if(candidates.size() == 1)\r
-                                                               aComponents.remove(c.neighbors);\r
-                                                       else {\r
-                                                               int last = candidates.size()-1;\r
-                                                               int[] temp = candidates.remove(last);\r
-                                                               if(i < last)\r
-                                                                       candidates.set(i, temp);\r
-                                                       }\r
-                                                   break;\r
-                                               }\r
-                                               else\r
-                                                       matching.unmap(els, c.elements);\r
-                                       }       \r
-                               }                       \r
-               }\r
-       }\r
-}\r
+package org.simantics.graph.matching;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TIntIntHashMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * Matches isomorphic components of the not yet matched graphs together.
+ * 
+ * @author Hannu Niemistö
+ */
+public enum ComponentMatchingStrategy implements GraphMatchingStrategy {
+       INSTANCE;
+
+       static class UnionFind {
+               int[] canonical;
+               
+               public UnionFind(int size) {
+                       canonical = new int[size];
+                       for(int i=0;i<size;++i)
+                               canonical[i] = i;
+               }
+               
+               public int canonical(int a) {
+                       int b = canonical[a];
+                       if(b != a) {
+                               int c = canonical[b];
+                               if(b != c) {
+                                       c = canonical(c);
+                                       canonical[b] = c;                                       
+                                       canonical[a] = c;
+                                       return c;
+                               }
+                       }
+                       return b;
+               }
+               
+               public void merge(int a, int b) {
+                       a = canonical(a);
+                       b = canonical(b);
+                       canonical[a] = b;
+               }
+       }
+       
+       public static int[][] findComponents(int[] map, Stat[][] statements, TIntIntHashMap inverses) {
+               int resourceCount = map.length;
+               
+               UnionFind uf = new UnionFind(resourceCount);
+               for(int s=0;s<resourceCount;++s)
+                       if(map[s] < 0) {
+                               for(Stat stat : statements[s]) {
+                                       int o = stat.o;
+                                       if(s < o && map[o] < 0)
+                                               uf.merge(s, o);
+                               }
+                               /*if(inverses.containsKey(s))
+                                       uf.merge(s, inverses.get(s));
+                                       */
+                       }
+               
+               TIntObjectHashMap<TIntArrayList> components = new TIntObjectHashMap<TIntArrayList>();
+               for(int i=0;i<resourceCount;++i)
+                       if(map[i] < 0) {
+                               int c = uf.canonical(i);
+                               TIntArrayList els = components.get(c);
+                               if(els == null) {
+                                       els = new TIntArrayList(2);
+                                       components.put(c, els);
+                               }
+                               els.add(i);
+                       }
+               
+               final int[][] result = new int[components.size()][];
+               components.forEachValue(new TObjectProcedure<TIntArrayList>() {
+                       int i = 0;
+                       @Override
+                       public boolean execute(TIntArrayList els) {
+                               result[i++] = els.toArray();
+                               return true;
+                       }
+               });
+               return result;
+       }       
+       
+       public static Stat[][] neighbors(int[] map, Stat[][] statements) {
+               int resourceCount = map.length;
+               Stat[][] neighbors = new Stat[resourceCount][];
+               
+               ArrayList<Stat> stats = new ArrayList<Stat>();
+               for(int s=0;s<resourceCount;++s) {
+                       if(map[s] >= 0) {
+                               neighbors[s] = Stat.NO_STATS;
+                               continue;
+                       }
+                       
+                       for(Stat stat : statements[s]) {
+                               int pp = map[stat.p] >= 0 ? stat.p : -1;
+                               int oo = map[stat.o] >= 0 ? stat.o : -1;                                
+                               stats.add(new Stat(pp, oo));
+                       }
+                       
+                       if(stats.isEmpty())
+                               neighbors[s] = Stat.NO_STATS;
+                       else {
+                               neighbors[s] = stats.toArray(new Stat[stats.size()]);
+                               stats.clear();
+                       }
+               }
+               
+               return neighbors;
+       }
+       
+       static class Component {
+               int[] elements;
+               Stat[][] neighbors;
+               
+               public Component(int[] elements, Stat[][] neighbors) {
+                       this.elements = elements;
+                       this.neighbors = new Stat[elements.length][];
+                       for(int i=0;i<elements.length;++i)
+                               this.neighbors[i] = neighbors[elements[i]];
+               }
+               
+               public void map(int[] map) {
+                       for(Stat[] stats : neighbors)
+                               for(Stat stat : stats)
+                                       stat.map(map);
+               }
+               
+               static class PP {
+                       int element;
+                       Stat[] stats;
+                       
+                       public PP(int element, Stat[] stats) {
+                               this.element = element;
+                               Arrays.sort(stats, Stat.STAT_COMPARATOR);
+                               this.stats = stats;
+                       }
+               }
+               
+               static final Comparator<PP> PP_COMPARATOR = new Comparator<PP>() {
+                       @Override
+                       public int compare(PP o1, PP o2) {
+                               Stat[] stats1 = o1.stats;
+                               Stat[] stats2 = o2.stats;
+                               int l1 = stats1.length;
+                               int l2 = stats2.length;
+                               if(l1 < l2)
+                                       return -1;
+                               else if(l1 > l2)
+                                       return 1;
+                               for(int i=0;i<l1;++i) {
+                                       Stat s1 = stats1[i];
+                                       Stat s2 = stats2[i];
+                                       if(s1.p < s2.p)
+                                               return -1;
+                                       else if(s1.p > s2.p)
+                                               return 1;
+                                       else if(s1.o < s2.o)
+                                               return -1;
+                                       else if(s1.o > s2.o)
+                                               return 1;
+                               }
+                               return 0;
+                       }                       
+               };
+               
+               public void canonicalize(String[] elNames, String[] statNames) {
+                       PP[] pps = new PP[elements.length];
+                       for(int i=0;i<elements.length;++i)
+                               pps[i] = new PP(elements[i], neighbors[i]);
+                       Arrays.sort(pps, PP_COMPARATOR);
+                       for(int i=0;i<pps.length-1;++i)
+                               if(PP_COMPARATOR.compare(pps[i], pps[i+1]) == 0) {
+                                       System.out.println("AMB " + pps.length + " " + (elNames==statNames));
+                                       for(i=0;i<pps.length-1;++i) {
+                                               if(PP_COMPARATOR.compare(pps[i], pps[i+1]) == 0)
+                                                       System.out.print(">   ");
+                                               else
+                                                       System.out.print("    ");
+                                               System.out.println(elNames[pps[i].element]);
+                                               for(Stat stat : pps[i].stats)
+                                                       System.out.println("        " + stat.toString(statNames));
+                                       }
+                                       break;
+                               }
+                       for(int i=0;i<elements.length;++i) {
+                               PP pp = pps[i];
+                               elements[i] = pp.element;
+                               neighbors[i] = pp.stats;
+                       }
+               }
+
+               public boolean isIsolated() {
+                       for(Stat[] stats : neighbors)
+                               if(stats.length > 0)
+                                       return false;
+                       return true;
+               }
+       }
+       
+       static class TNeighbourObjectHashMap<T> extends THashMap<Stat[][], T> {
+               @Override
+               protected boolean equals(Object one, Object two) {
+                       Stat[][] o1 = (Stat[][])one;
+                       Stat[][] o2 = (Stat[][])two;
+                       if(o1.length != o2.length)
+                               return false;
+                       for(int i=0;i<o1.length;++i) {
+                               Stat[] ss1 = o1[i];
+                               Stat[] ss2 = o2[i];
+                               if(ss1.length != ss2.length)
+                                       return false;
+                               for(int j=0;j<ss1.length;++j) {
+                                       Stat s1 = ss1[j];
+                                       Stat s2 = ss2[j];
+                                       if(s1.p != s2.p || s1.o != s2.o)
+                                               return false;
+                               }
+                       }
+                       return true;
+               }
+               
+               @Override
+               protected int hash(Object obj) {
+                       int result = 152433;
+                       for(Stat[] stats : (Stat[][])obj)
+                               for(Stat stat : stats)
+                                       result = (result*31 + stat.p)*31 + stat.o;
+                       return result;
+               }
+       }
+       
+       @Override
+       public void applyTo(GraphMatching matching) {
+               System.out.println("ComponentMatchingStrategy");
+               TNeighbourObjectHashMap<ArrayList<int[]>> aComponents = new TNeighbourObjectHashMap<ArrayList<int[]>>(); 
+               {                       
+                       Stat[][] neighbors = neighbors(matching.aToB, matching.aGraph.statements);
+                       //TIntIntHashMap componentSizes = new TIntIntHashMap();
+                       for(int[] els : findComponents(matching.aToB, matching.aGraph.statements, matching.aGraph.inverses)) {
+                               /*for(int el : els)
+                                       System.out.print(matching.aGraph.names[el] + " ");
+                               System.out.println();
+                               componentSizes.adjustOrPutValue(els.length, 1, 1);*/
+                               Component component = new Component(els, neighbors);
+                               if(component.isIsolated())
+                                       continue;
+                               component.map(matching.aToB);
+                               component.canonicalize(matching.aGraph.names, matching.bGraph.names);
+                               ArrayList<int[]> values = aComponents.get(component.neighbors);
+                               if(values == null) {
+                                       values = new ArrayList<int[]>(1);
+                                       aComponents.put(component.neighbors, values);
+                               }
+                               values.add(component.elements);
+                       }
+                       /*componentSizes.forEachEntry(new TIntIntProcedure() {                          
+                               @Override
+                               public boolean execute(int a, int b) {
+                                       System.out.println("Components of size " + a + ": " + b);
+                                       return true;
+                               }
+                       });*/
+               }
+               
+               ArrayList<Component> bComponents = new ArrayList<Component>(); 
+               {
+                       Stat[][] neighbors = neighbors(matching.bToA, matching.bGraph.statements);
+                       for(int[] els : findComponents(matching.bToA, matching.bGraph.statements, matching.bGraph.inverses)) {
+                               Component component = new Component(els, neighbors);
+                               if(component.isIsolated())
+                                       continue;
+                               component.canonicalize(matching.bGraph.names, matching.bGraph.names);
+                               bComponents.add(component);
+                       }
+               }
+               
+               for(Component c : bComponents) {
+                       ArrayList<int[]> candidates = aComponents.get(c.neighbors);
+                       if(candidates != null)
+                               for(int i=0;i<candidates.size();++i) {
+                                       int[] els = candidates.get(i);
+                                       if(els != null) {
+                                               matching.map(els, c.elements);
+                                               if(matching.checkMatch(els, c.elements)) {
+                                                       if(candidates.size() == 1)
+                                                               aComponents.remove(c.neighbors);
+                                                       else {
+                                                               int last = candidates.size()-1;
+                                                               int[] temp = candidates.remove(last);
+                                                               if(i < last)
+                                                                       candidates.set(i, temp);
+                                                       }
+                                                   break;
+                                               }
+                                               else
+                                                       matching.unmap(els, c.elements);
+                                       }       
+                               }                       
+               }
+       }
+}