9af8d02ee14802c3344d78edc6fce1000b71a535
[IRC.git] / Robust / src / Analysis / Scheduling / CombinationUtil.java
1 package Analysis.Scheduling;
2
3 import java.util.Random;
4 import java.util.Vector;
5
6 public class CombinationUtil {
7   static CombinationUtil cu;
8
9   public CombinationUtil() {
10   }
11
12   public static CombinationUtil allocateCombinationUtil() {
13     if(cu == null) {
14       cu = new CombinationUtil();
15     }
16     return cu;
17   }
18
19   public static RootsGenerator allocateRootsGenerator(Vector<Vector<ScheduleNode>> snodevecs,
20                                                       int rootNum) {
21     return CombinationUtil.allocateCombinationUtil().new RootsGenerator(snodevecs, rootNum);
22   }
23
24   public static CombineGenerator allocateCombineGenerator(Vector<Vector<ScheduleNode>> rootnodes,
25                                                           Vector<Vector<ScheduleNode>> node2combine) {
26     return CombinationUtil.allocateCombinationUtil().new CombineGenerator(rootnodes, node2combine);
27   }
28
29   public static RandomGenerator allocateRandomGenerator(Vector<Vector<ScheduleNode>> snodevecs,
30                                                         int rootNum) {
31     return CombinationUtil.allocateCombinationUtil().new RandomGenerator(snodevecs, rootNum);
32   }
33
34   public class RootsGenerator {
35     Vector<Vector<ScheduleNode>> sNodeVecs;
36     Vector<Vector<ScheduleNode>> node2Combine;
37     Vector<Vector<ScheduleNode>> rootNodes;
38     int rootNum;
39
40     public RootsGenerator(Vector<Vector<ScheduleNode>> snodevecs,
41                           int rootNum) {
42       this.sNodeVecs = snodevecs;
43       this.rootNum = rootNum;
44       this.node2Combine = null;
45       this.rootNodes = null;
46     }
47
48     public void clear() {
49       this.sNodeVecs = null;
50       this.node2Combine.clear();
51       this.node2Combine = null;
52       this.rootNodes.clear();
53       this.rootNodes = null;
54       this.rootNum = 0;
55     }
56
57     public boolean nextGen() {
58       boolean trial = false;
59       if(this.rootNodes == null) {
60         int num2choose = this.rootNum;
61         this.rootNodes = new Vector<Vector<ScheduleNode>>();
62         this.rootNodes.add(new Vector<ScheduleNode>());
63         Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(0);
64         for(int i = 0; i < toadd.size(); i++) {
65           // should be only one element: startup object
66           this.rootNodes.elementAt(0).add(toadd.elementAt(i));
67           num2choose--;
68         }
69         int next = 1;
70         trial = trial(num2choose, next);
71         toadd = null;
72       } else {
73         if(this.rootNodes.size() == 1) {
74           return false;
75         }
76         int next = this.rootNodes.lastElement().elementAt(0).getCid() + 1;
77         int num2choose = 0;
78         while(next == this.sNodeVecs.size()) {
79           // backtrack
80           num2choose = this.rootNodes.lastElement().size();
81           this.rootNodes.removeElementAt(this.rootNodes.size() - 1);
82           if(this.rootNodes.size() == 1) {
83             // only startup object left, no more choices
84             return false;
85           }
86           next = this.rootNodes.lastElement().elementAt(0).getCid() + 1;
87         }
88         num2choose++;
89         // reduce one from the last one
90         this.rootNodes.lastElement().removeElementAt(this.rootNodes.lastElement().size() - 1);
91         if(this.rootNodes.lastElement().size() == 0) {
92           this.rootNodes.removeElementAt(this.rootNodes.size() - 1);
93         }
94
95         trial = trial(num2choose, next);
96       }
97       if(trial) {
98         // remaining nodes are all to be combined
99         this.node2Combine = new Vector<Vector<ScheduleNode>>();
100         int next = 1;
101         int index = 0;
102         for(int i = 1; i < this.rootNodes.size(); i++) {
103           int tmp = this.rootNodes.elementAt(i).elementAt(0).getCid();
104           while(next < tmp) {
105             Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(next);
106             if(toadd != null) {
107               this.node2Combine.add(new Vector<ScheduleNode>());
108               for(index = 0; index < toadd.size(); index++) {
109                 this.node2Combine.lastElement().add(toadd.elementAt(index));
110               }
111               toadd = null;
112             } else {
113               this.node2Combine.add(null);
114             }
115             next++;
116           }
117           Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(tmp);
118           if(toadd.size() > this.rootNodes.elementAt(i).size()) {
119             this.node2Combine.add(new Vector<ScheduleNode>());
120             for(index = this.rootNodes.elementAt(i).size(); index < toadd.size(); index++) {
121               this.node2Combine.lastElement().add(toadd.elementAt(index));
122             }
123           }
124           toadd = null;
125           next++;
126         }
127         while(next < this.sNodeVecs.size()) {
128           Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(next);
129           if(toadd != null) {
130             this.node2Combine.add(new Vector<ScheduleNode>());
131             for(index = 0; index < toadd.size(); index++) {
132               this.node2Combine.lastElement().add(toadd.elementAt(index));
133             }
134             toadd = null;
135           } else {
136             this.node2Combine.add(null);
137           }
138           next++;
139         }
140       }
141       return trial;
142     }
143
144     private boolean trial(int num2choose,
145                           int next) {
146       int index = 0;
147       boolean first = true;
148       while(num2choose > 0) {
149         if(first) {
150           if(next == this.sNodeVecs.size()) {
151             // no more nodes available to add
152             return false;
153           }
154         }
155         if(this.sNodeVecs.elementAt(next) != null) {
156           if(first) {
157             this.rootNodes.add(new Vector<ScheduleNode>());
158             first = false;
159           }
160           this.rootNodes.lastElement().add(this.sNodeVecs.elementAt(next).elementAt(index));
161           num2choose--;
162           index++;
163           if(index == this.sNodeVecs.elementAt(next).size()) {
164             index = 0;
165             next++;
166             first = true;
167           }
168         } else {
169           next++;
170           first = true;
171         }
172       }
173       return true;
174     }
175
176     public Vector<Vector<ScheduleNode>> getNode2Combine() {
177       return node2Combine;
178     }
179
180     public Vector<Vector<ScheduleNode>> getRootNodes() {
181       return rootNodes;
182     }
183   }
184
185   public class Combine {
186     public ScheduleNode node;
187     public int root;
188     public int index;
189
190     public Combine(ScheduleNode n) {
191       this.node = n;
192       this.root = -1;
193       this.index = -1;
194     }
195   }
196
197   public class CombineGenerator {
198     Vector<Vector<ScheduleNode>> rootNodes;
199     Vector<Vector<int[]>> rootNStates;
200     Vector<Vector<ScheduleNode>> node2Combine;
201     Vector<Vector<Combine>> combine;
202     int[] lastchoices;
203     boolean first4choice;
204     Random rand;
205     int limit;
206     int[][] rootLoads;
207
208     public CombineGenerator(Vector<Vector<ScheduleNode>> rootnodes,
209                             Vector<Vector<ScheduleNode>> node2combine) {
210       this.rootNodes = rootnodes;
211       this.node2Combine = node2combine;
212       this.rootNStates = new Vector<Vector<int[]>>();
213       int rootnum = 0;
214       for(int i = 0; i < this.rootNodes.size(); i++) {
215         this.rootNStates.add(new Vector<int[]>());
216         for(int j = 0; j < this.rootNodes.elementAt(i).size(); j++) {
217           this.rootNStates.elementAt(i).add(new int[this.node2Combine.size()]);
218           for(int k = 0; k < this.node2Combine.size(); k++) {
219             this.rootNStates.elementAt(i).elementAt(j)[k] = 0;
220           }
221           rootnum++;
222         }
223       }
224       this.combine = new Vector<Vector<Combine>>();
225       int tomapnum = 0;
226       for(int i = 0; i < this.node2Combine.size(); i++) {
227         if(this.node2Combine.elementAt(i) == null) {
228           this.combine.add(null);
229         } else {
230           this.combine.add(new Vector<Combine>());
231           for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
232             this.combine.elementAt(i).add(new Combine(this.node2Combine.elementAt(i).elementAt(j)));
233             tomapnum++;
234           }
235         }
236       }
237       this.lastchoices = null;
238       this.first4choice = false;
239       this.rand = new Random();
240
241       this.limit = (tomapnum-1)/rootnum+1;
242       this.rootLoads = null;
243     }
244
245     public void clear() {
246       this.rootNodes = null;
247       this.rootNStates.clear();
248       this.rootNStates = null;
249       this.node2Combine = null;
250       this.combine.clear();
251       this.combine = null;
252       this.lastchoices = null;
253       this.first4choice = false;
254     }
255
256     public Vector<Vector<Combine>> getCombine() {
257       return combine;
258     }
259
260     // generate next mapping randomly evenly
261     public boolean randomGenE() {
262       this.rootLoads = new int[this.rootNodes.size()][];
263       for(int i = 0; i < this.rootNodes.size(); i++) {
264         this.rootLoads[i] = new int[this.rootNodes.elementAt(i).size()];
265       }
266       int rootx = this.rootNodes.size();
267       for(int i = 0; i < this.node2Combine.size(); i++) {
268         for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
269           Combine tmp = this.combine.elementAt(i).elementAt(j);
270           do {
271             int x = Math.abs(rand.nextInt()) % rootx;
272             int y = Math.abs(rand.nextInt()) % this.rootNodes.elementAt(x).size();
273             if(this.rootLoads[x][y] < this.limit) {
274               tmp.root  = x;
275               tmp.index = y;
276               this.rootLoads[tmp.root][tmp.index]++;
277               break;
278             }
279           } while(true);
280         }
281       }
282       return true;
283     }
284
285     public boolean randomGen() {
286       int rootx = this.rootNodes.size();
287       for(int i = 0; i < this.node2Combine.size(); i++) {
288         for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
289           Combine tmp = this.combine.elementAt(i).elementAt(j);
290           tmp.root = Math.abs(rand.nextInt()) % rootx;
291           tmp.index = Math.abs(rand.nextInt()) % this.rootNodes.elementAt(tmp.root).size();
292         }
293       }
294       return true;
295     }
296
297     public boolean nextGen() {
298       boolean trial = false;
299       if(this.lastchoices == null) {
300         // first time
301         this.lastchoices = new int[this.node2Combine.size()];
302         for(int i = 0; i < this.lastchoices.length; i++) {
303           this.lastchoices[i] = 0;
304         }
305         this.first4choice = true;
306         trial = trial();
307       } else {
308         trial = trial();
309         while(!trial) {
310           // no more available combination under this choice
311           // choose another choice
312           int next = this.node2Combine.size() - 1;
313           boolean iter = false;
314           do {
315             if(this.node2Combine.elementAt(next) != null) {
316               this.lastchoices[next]++;
317               if((this.lastchoices[next] == this.rootNodes.size() ||
318                   (this.rootNodes.elementAt(this.lastchoices[next]).elementAt(0).getCid() >
319                    this.node2Combine.elementAt(next).elementAt(0).getCid()))) {
320                 // break the rule that a node can only be combined to nodes with smaller colorid.
321                 // or no more buckets
322                 // backtrack
323                 next--;
324                 iter = true;
325               } else {
326                 iter = false;
327               }
328             } else {
329               next--;
330               iter = true;
331             }
332           } while(iter && !(next < 0));
333           if(next < 0) {
334             return false;
335           }
336           for(next += 1; next < this.node2Combine.size(); next++) {
337             this.lastchoices[next] = 0;
338           }
339           this.first4choice = true;
340           trial = trial();
341         }
342       }
343       return trial;
344     }
345
346     private boolean trial() {
347       boolean suc = false;
348       if(this.first4choice) {
349         // first time for each choice
350         // put all the objects of one color into the first bucket indicated by the choice
351         int next = 0;
352         suc = firstexpand(next, this.first4choice);
353         this.first4choice = false;
354       } else {
355         int next = this.node2Combine.size() - 1;
356         int layer = 0;
357         suc = innertrial(next, layer);
358       }
359       return suc;
360     }
361
362     private boolean firstexpand(int next,
363                                 boolean first) {
364       for(int i = next; i < this.node2Combine.size(); i++) {
365         if(this.node2Combine.elementAt(i) != null) {
366           int choice = this.lastchoices[i];
367           for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
368             Combine tmp = this.combine.elementAt(i).elementAt(j);
369             if(!first) {
370               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
371             }
372             tmp.root = choice;
373             tmp.index = 0;
374             if(!first) {
375               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
376             }
377           }
378           if(first) {
379             this.rootNStates.elementAt(choice).elementAt(0)[i] = this.node2Combine.elementAt(i).size();
380             for(int j = 1; j < this.rootNodes.elementAt(choice).size(); j++) {
381               this.rootNStates.elementAt(choice).elementAt(j)[i] = 0;
382             }
383           }
384         }
385       }
386       return true;
387     }
388
389     private boolean innertrial(int next,
390                                int layer) {
391       if((this.combine.elementAt(next) == null) ||
392          (this.combine.elementAt(next).size() < 2)) {
393         // skip over empty buckets and bucket with only one obj ( make sure
394         // at least one obj is existing in the chosen bucket)
395         if(next - 1 < 0) {
396           return false;
397         } else {
398           return innertrial(next - 1, ++layer);
399         }
400       }
401       Combine tmp = this.combine.elementAt(next).lastElement();
402       // try to move it backward
403       int root = tmp.root;
404       int index = tmp.index;
405       index++;
406       if(index == this.rootNodes.elementAt(root).size()) {
407         // no more place in this color bucket
408         index = 0;
409         root++;
410       } else if(this.rootNStates.elementAt(root).elementAt(index - 1)[next] <
411                 this.rootNStates.elementAt(root).elementAt(index)[next] + 2) {
412         // break the law of non-increase order inside one color bucket
413         // try next bucket of another color
414         index = 0;
415         root++;
416       }
417       if(root == this.rootNodes.size()) {
418         // no more bucket
419         // backtrack
420         root = tmp.root;
421         index = tmp.index;
422         int t = this.combine.elementAt(next).size() - 2;
423         while(true) {
424           while(!(t < 0)) {
425             tmp = this.combine.elementAt(next).elementAt(t);
426             if ((tmp.root != root) || (tmp.index != index)) {
427               break;
428             }
429             t--;
430           }
431           if(t < 0) {
432             // try the bucket in node2combine before
433             if(next - 1 < 0) {
434               return false;
435             } else {
436               return innertrial(next - 1, ++layer);
437             }
438           } else if(tmp.root != root) {
439             if((tmp.root == this.lastchoices[next]) &&
440                (this.rootNStates.elementAt(this.lastchoices[next]).elementAt(0)[next] == 1)) {
441               // only 1 obj left in the chosen bucket
442               // can not move this one
443               // try the bucket in node2combine before
444               if(next - 1 < 0) {
445                 return false;
446               } else {
447                 return innertrial(next - 1, ++layer);
448               }
449             }
450             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
451             //tmp.root = root;
452             int newroot = tmp.root + 1;
453             tmp.root = newroot;
454             tmp.index = 0;
455             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
456             // make all left things in this color bucket reset
457             for(t++; t < this.combine.elementAt(next).size(); t++) {
458               tmp = this.combine.elementAt(next).elementAt(t);
459               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
460               tmp.root = newroot;
461               tmp.index = 0;
462               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
463             }
464             if(layer != 0) {
465               return firstexpand(next+1, this.first4choice);
466             }
467             return true;
468           } else if(tmp.index != index) {
469             if(this.rootNStates.elementAt(root).elementAt(tmp.index)[next] ==
470                this.rootNStates.elementAt(root).elementAt(index)[next]) {
471               // break the law of non-increase order inside one color bucket
472               // go on search forward
473               index = tmp.index;
474             } else if(this.rootNStates.elementAt(root).elementAt(tmp.index)[next] <
475                       this.rootNStates.elementAt(root).elementAt(index)[next] + 2) {
476               // break the law of non-increase order inside one color bucket
477               // and now they only differ by 1
478               // propagate this difference to see if it can fix
479               boolean suc = propagateOne(next, root, index, t, tmp);
480               if(suc) {
481                 return suc;
482               } else {
483                 // go on search forward
484                 index = tmp.index;
485               }
486             } else {
487               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
488               int tmproot = tmp.root;
489               int tmpindex = tmp.index;
490               tmp.root = root;
491               tmp.index = index;
492               this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
493               int desroot = tmp.root;
494               int desindex = tmp.index;
495               // make all left things in this color bucket reset
496               t++;
497               boolean first = true;
498               while(t < this.combine.elementAt(next).size()) {
499                 int k = 0;
500                 if(first) {
501                   k = 1;
502                   first = false;
503                 }
504                 for(; (k < this.rootNStates.elementAt(tmproot).elementAt(tmpindex)[next]) && (t < this.combine.elementAt(next).size()); t++) {
505                   tmp = this.combine.elementAt(next).elementAt(t);
506                   this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
507                   tmp.root = desroot;
508                   tmp.index = desindex;
509                   this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
510                 }
511                 if(k == this.rootNStates.elementAt(tmproot).elementAt(tmpindex)[next]) {
512                   desindex++;
513                 }
514               }
515               if(layer != 0) {
516                 return firstexpand(next+1, this.first4choice);
517               }
518               return true;
519             }
520           }
521         }
522       } else {
523         if((tmp.root != this.lastchoices[next]) ||
524            (this.rootNStates.elementAt(this.lastchoices[next]).elementAt(0)[next] > 1)) {
525           this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
526           tmp.root = root;
527           tmp.index = index;
528           this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
529           if(layer != 0) {
530             return firstexpand(next+1, this.first4choice);
531           }
532           return true;
533         } else {
534           // only 1 obj with the color next exist on the chosen bucket this time,
535           // can not move it, try objs in forward color bucket
536           if(next - 1 < 0) {
537             return false;
538           } else {
539             return innertrial(next - 1, ++layer);
540           }
541         }
542       }
543     }
544
545     private boolean propagateOne(int next,
546                                  int rooti,
547                                  int indexi,
548                                  int ti,
549                                  Combine tmp) {
550       int root = rooti;
551       int index = indexi;
552       int t = ti;
553       int rootbk = tmp.root;
554       int indexbk = tmp.index;
555       this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
556       tmp.root = root;
557       tmp.index = index;
558       this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
559       t += 2;
560       Combine tmpt = null;
561       if(this.rootNStates.elementAt(root).elementAt(index - 1)[next] <
562          this.rootNStates.elementAt(root).elementAt(index)[next]) {
563         // need to continue propagate
564         while(t < this.combine.elementAt(next).size()) {
565           tmpt = this.combine.elementAt(next).elementAt(t);
566           if ((tmpt.root != root) || (tmpt.index != index)) {
567             break;
568           }
569           t++;
570         }
571         if(t == this.combine.elementAt(next).size()) {
572           // last element of this color bucket
573           if(index + 1 < this.rootNodes.elementAt(root).size()) {
574             // there is available place inside the same color bucket
575             Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
576             boolean suc = propagateOne(next, root, index + 1, t - 1, tmpbk);
577             /*if(!suc) {
578                 // fail, roll back
579                 this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
580                 tmp.root = rootbk;
581                 tmp.index = indexbk;
582                 this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
583                }*/
584             return suc;
585           } else if(root+1 < this.rootNodes.size()) {           // check if there are another bucket
586             // yes
587             this.rootNStates.elementAt(tmpt.root).elementAt(tmpt.index)[next]--;
588             tmpt.root = root + 1;
589             tmpt.index = 0;
590             this.rootNStates.elementAt(tmpt.root).elementAt(tmpt.index)[next]++;
591             return firstexpand(next+1, this.first4choice);
592           } else {
593             // no, roll back
594             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
595             tmp.root = rootbk;
596             tmp.index = indexbk;
597             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
598             return false;
599           }
600         } else if(tmpt.root != root) {
601           Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
602           this.rootNStates.elementAt(tmpbk.root).elementAt(tmpbk.index)[next]--;
603           tmpbk.root = tmpt.root;
604           tmpbk.index = 0;
605           this.rootNStates.elementAt(tmpbk.root).elementAt(tmpbk.index)[next]++;
606           root = tmpt.root;
607           index = tmpt.index;
608           // make all left things in this color bucket reset
609           for(t += 1; t < this.combine.elementAt(next).size(); t++) {
610             tmpt = this.combine.elementAt(next).elementAt(t);
611             this.rootNStates.elementAt(tmpt.root).elementAt(tmpt.index)[next]--;
612             tmpt.root = root;
613             tmpt.index = 0;
614             this.rootNStates.elementAt(tmpt.root).elementAt(tmpt.index)[next]++;
615           }
616           return firstexpand(next+1, this.first4choice);
617         } else if(tmpt.index != index) {
618           Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
619           boolean suc = propagateOne(next, root, tmpt.index, t - 1, tmpbk);
620           if(!suc) {
621             // fail, roll back
622             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
623             tmp.root = rootbk;
624             tmp.index = indexbk;
625             this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
626           }
627           return suc;
628         }
629         // won't reach here, only to avoid compiler's complain
630         return true;
631       } else {
632         return true;
633       }
634     }
635   }
636
637   public class RandomGenerator {
638     Vector<Vector<ScheduleNode>> sNodeVecs;
639     Vector<Vector<ScheduleNode>> mapping;
640     int rootNum;
641     Random rand;
642
643     public RandomGenerator(Vector<Vector<ScheduleNode>> snodevecs,
644                            int rootNum) {
645       this.sNodeVecs = snodevecs;
646       this.rootNum = rootNum;
647
648       this.mapping = new Vector<Vector<ScheduleNode>>();
649       for(int i = 0; i < this.rootNum; i++) {
650         this.mapping.add(null);
651       }
652       this.rand = new Random();
653     }
654
655     public void clear() {
656       this.sNodeVecs = null;
657       this.rootNum = 0;
658       this.mapping = null;
659     }
660
661     public boolean nextGen() {
662       this.mapping = null;
663       this.mapping = new Vector<Vector<ScheduleNode>>();
664       for(int i = 0; i < this.rootNum; i++) {
665         this.mapping.add(null);
666       }
667
668       // randomly choose a core for each node in sNodeVecs
669       for(int i = 0; i < this.sNodeVecs.size(); i++) {
670         Vector<ScheduleNode> sNodes = this.sNodeVecs.elementAt(i);
671         for(int j = 0; j < sNodes.size(); j++) {
672           ScheduleNode snode = sNodes.elementAt(j);
673           int core = Math.abs(rand.nextInt()) % this.rootNum;
674           if(this.mapping.elementAt(core) == null) {
675             this.mapping.setElementAt(new Vector<ScheduleNode>(), core);
676           }
677           this.mapping.elementAt(core).add(snode);
678         }
679       }
680       return true;
681     }
682
683     public Vector<Vector<ScheduleNode>> getMapping() {
684       return this.mapping;
685     }
686   }
687 }