1 package org.simantics.graph.matching;
3 import gnu.trove.list.array.TIntArrayList;
4 import gnu.trove.map.hash.TIntDoubleHashMap;
5 import gnu.trove.map.hash.TIntIntHashMap;
6 import gnu.trove.map.hash.TIntObjectHashMap;
7 import gnu.trove.procedure.TIntDoubleProcedure;
8 import gnu.trove.procedure.TIntObjectProcedure;
10 public enum VotingMatchingStrategy implements GraphMatchingStrategy {
13 public static void vote(
14 final TIntDoubleHashMap[] voting,
19 final String[] bNames) {
20 final TIntObjectHashMap<TIntArrayList> aMap =
21 new TIntObjectHashMap<TIntArrayList>();
22 for(Stat stat : aStat) {
23 int mp = aToB[stat.p];
24 if(mp >= 0 && aToB[stat.o] < 0) {
25 TIntArrayList l = aMap.get(mp);
27 l = new TIntArrayList(2);
33 TIntObjectHashMap<TIntArrayList> bMap =
34 new TIntObjectHashMap<TIntArrayList>();
35 for(Stat stat : bStat) {
38 if(bToA[p] >= 0 && bToA[o] < 0) {
39 TIntArrayList l = bMap.get(p);
41 l = new TIntArrayList(2);
47 /*System.out.println("---------------------------------------");
48 aMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {
50 public boolean execute(int a, TIntArrayList b) {
51 System.out.println("a " + bNames[a] + " -> " + b);
55 bMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {
57 public boolean execute(int a, TIntArrayList b) {
58 System.out.println("b " + bNames[a] + " -> " + b);
62 bMap.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {
64 public boolean execute(int p, TIntArrayList bos) {
65 TIntArrayList aos = aMap.get(p);
66 if(aos != null && aos.size() <= 4 && bos.size() <= 4) {
67 final double weight = 1.0 / bos.size();
68 for(int i=0;i<aos.size();++i)
69 for(int j=0;j<bos.size();++j)
70 voting[aos.get(i)].adjustOrPutValue(bos.get(j), weight, weight);
78 public void applyTo(GraphMatching matching) {
79 int[] aToB = matching.aToB;
80 final int[] bToA = matching.bToA;
81 int resourceCount = aToB.length;
82 Stat[][] aStatements = matching.aGraph.statements;
83 Stat[][] bStatements = matching.bGraph.statements;
84 TIntIntHashMap aInv = matching.aGraph.inverses;
85 TIntIntHashMap bInv = matching.bGraph.inverses;
87 TIntDoubleHashMap[] voting = new TIntDoubleHashMap[resourceCount];
88 for(int i=0;i<resourceCount;++i)
90 voting[i] = new TIntDoubleHashMap();
91 for(int s=0;s<resourceCount;++s) {
93 if(ms >= 0 && ms < bStatements.length)
94 vote(voting, aToB, bToA, aStatements[s], bStatements[ms], matching.bGraph.names);
97 for(int a=0;a<resourceCount;++a) {
98 TIntDoubleHashMap votes = voting[a];
99 if(votes != null && !votes.isEmpty()) {
100 final int[] best = new int[] { -1 };
101 votes.forEachEntry(new TIntDoubleProcedure() {
102 double bestWeight = 0.9;
104 public boolean execute(int b, double weight) {
105 if(weight > bestWeight && bToA[b] < 0) {
115 if(aInv.contains(a) && bInv.contains(b) && aInv.get(a) != a)
116 matching.map(aInv.get(a), bInv.get(b));