]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/matching/VotingMatchingStrategy.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / matching / VotingMatchingStrategy.java
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/matching/VotingMatchingStrategy.java b/bundles/org.simantics.graph/src/org/simantics/graph/matching/VotingMatchingStrategy.java
new file mode 100644 (file)
index 0000000..2220b6e
--- /dev/null
@@ -0,0 +1,122 @@
+package org.simantics.graph.matching;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.map.hash.TIntDoubleHashMap;\r
+import gnu.trove.map.hash.TIntIntHashMap;\r
+import gnu.trove.map.hash.TIntObjectHashMap;\r
+import gnu.trove.procedure.TIntDoubleProcedure;\r
+import gnu.trove.procedure.TIntObjectProcedure;\r
+\r
+public enum VotingMatchingStrategy implements GraphMatchingStrategy {\r
+       INSTANCE;\r
+\r
+       public static void vote(\r
+                       final TIntDoubleHashMap[] voting, \r
+                       int[] aToB,\r
+                       int[] bToA,\r
+                       Stat[] aStat,\r
+                       Stat[] bStat,\r
+                       final String[] bNames) {\r
+               final TIntObjectHashMap<TIntArrayList> aMap =\r
+                       new TIntObjectHashMap<TIntArrayList>();         \r
+               for(Stat stat : aStat) {\r
+                       int mp = aToB[stat.p];\r
+                       if(mp >= 0 && aToB[stat.o] < 0) {\r
+                               TIntArrayList l = aMap.get(mp);\r
+                               if(l == null) {\r
+                                       l = new TIntArrayList(2);\r
+                                       aMap.put(mp, l);\r
+                               }\r
+                               l.add(stat.o);\r
+                       }\r
+               }\r
+               TIntObjectHashMap<TIntArrayList> bMap =\r
+                       new TIntObjectHashMap<TIntArrayList>();\r
+               for(Stat stat : bStat) {\r
+                       int p = stat.p;\r
+                       int o = stat.o;\r
+                       if(bToA[p] >= 0 && bToA[o] < 0) {\r
+                               TIntArrayList l = bMap.get(p);\r
+                               if(l == null) {\r
+                                       l = new TIntArrayList(2);\r
+                                       bMap.put(p, l);\r
+                               }\r
+                               l.add(o);\r
+                       }\r
+               }\r
+               /*System.out.println("---------------------------------------");\r
+               aMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {\r
+                       @Override\r
+                       public boolean execute(int a, TIntArrayList b) {\r
+                               System.out.println("a " + bNames[a] + " -> " + b);\r
+                               return true;\r
+                       }\r
+               });\r
+               bMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {\r
+                       @Override\r
+                       public boolean execute(int a, TIntArrayList b) {\r
+                               System.out.println("b " + bNames[a] + " -> " + b);\r
+                               return true;\r
+                       }\r
+               });*/\r
+               bMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {                    \r
+                       @Override\r
+                       public boolean execute(int p, TIntArrayList bos) {\r
+                               TIntArrayList aos = aMap.get(p);\r
+                               if(aos != null && aos.size() <= 4 && bos.size() <= 4) {\r
+                                       final double weight = 1.0 / bos.size();\r
+                                       for(int i=0;i<aos.size();++i)\r
+                                               for(int j=0;j<bos.size();++j)\r
+                                                       voting[aos.get(i)].adjustOrPutValue(bos.get(j), weight, weight);\r
+                               }\r
+                               return true;\r
+                       }\r
+               });\r
+       }\r
+       \r
+       @Override\r
+       public void applyTo(GraphMatching matching) {\r
+               int[] aToB = matching.aToB;\r
+               final int[] bToA = matching.bToA;\r
+               int resourceCount = aToB.length;\r
+               Stat[][] aStatements = matching.aGraph.statements;\r
+               Stat[][] bStatements = matching.bGraph.statements;\r
+               TIntIntHashMap aInv = matching.aGraph.inverses;\r
+               TIntIntHashMap bInv = matching.bGraph.inverses;\r
+               \r
+               TIntDoubleHashMap[] voting = new TIntDoubleHashMap[resourceCount];\r
+               for(int i=0;i<resourceCount;++i)\r
+                       if(aToB[i] < 0)\r
+                               voting[i] = new TIntDoubleHashMap();\r
+               for(int s=0;s<resourceCount;++s) {\r
+                       int ms = aToB[s];\r
+                       if(ms >= 0 && ms < bStatements.length)\r
+                               vote(voting, aToB, bToA, aStatements[s], bStatements[ms], matching.bGraph.names);\r
+               }\r
+               \r
+               for(int a=0;a<resourceCount;++a) {\r
+                       TIntDoubleHashMap votes = voting[a];\r
+                       if(votes != null && !votes.isEmpty()) {\r
+                               final int[] best = new int[] { -1 };\r
+                               votes.forEachEntry(new TIntDoubleProcedure() {\r
+                                       double bestWeight = 0.9;\r
+                                       @Override\r
+                                       public boolean execute(int b, double weight) {\r
+                                               if(weight > bestWeight && bToA[b] < 0) {\r
+                                                       bestWeight = weight;\r
+                                                       best[0] = b;\r
+                                               }\r
+                                               return true;\r
+                                       }\r
+                               });\r
+                               if(best[0] >= 0) {\r
+                                       int b = best[0];\r
+                                       matching.map(a, b);\r
+                                       if(aInv.contains(a) && bInv.contains(b) && aInv.get(a) != a)\r
+                                               matching.map(aInv.get(a), bInv.get(b));\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+}\r