source: ip/src/main/java/geniusweb/ip/general/RandomPartition.java@ 52

Last change on this file since 52 was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 2.8 KB
Line 
1package geniusweb.ip.general;
2
3import java.math.BigDecimal;
4import java.util.Random;
5
6public class RandomPartition {
7
8 private int n;
9 private double[][] probabilityOfNew;
10
11 public RandomPartition(int n) {
12 this.n = n;
13 this.calculateWeights(n);
14 }
15
16 // random partition of numbers (0, 1, ..., n-1)
17 public int[] get() {
18 int partition[] = new int[n];
19
20 Random randomGenerator = new Random();
21 int coalitionsCount = 1;
22 partition[0] = 1;
23 for (int i = 1; i < n; ++i) {
24 if (randomGenerator
25 .nextDouble() < this.probabilityOfNew[i][coalitionsCount]) {
26 partition[i] = coalitionsCount + 1;
27 ++coalitionsCount;
28 } else
29 partition[i] = randomGenerator.nextInt(coalitionsCount) + 1;
30 }
31
32 // Convert the partition to a coalition structure, where every coalition
33 // is a number in which true bits represent the members
34 int[] coalitionStructure = new int[coalitionsCount];
35 for (int i = 0; i < coalitionsCount; i++) {
36 coalitionStructure[i] = 0;
37 }
38 for (int i = 0; i < n; i++) {
39 coalitionStructure[partition[i] - 1] += (1 << i); // add agent "i+1"
40 // to the
41 // coalition
42 }
43
44 return coalitionStructure;
45 }
46
47 private void calculateWeights(int n) {
48 BigDecimal[][] weights = new BigDecimal[n + 1][n + 1];
49 double[][] weightsDouble = new double[n + 1][n + 1];
50 this.probabilityOfNew = new double[n + 1][n + 1];
51
52 weights[0][0] = BigDecimal.ONE;
53 weightsDouble[0][0] = 1;
54 BigDecimal bellNInverse = BigDecimal.ONE.divide(this.getBellNumber(n),
55 500, BigDecimal.ROUND_UP);
56 for (int i = 1; i <= n; ++i) {
57 weights[n][i] = bellNInverse;
58 weightsDouble[n][i] = weights[n][i].doubleValue();
59 }
60
61 for (int j = n - 1; j >= 1; --j) {
62 for (int k = 1; k <= j; ++k) {
63 weights[j][k] = weights[j + 1][k].multiply(new BigDecimal(k))
64 .add(weights[j + 1][k + 1]);
65 weightsDouble[j][k] = weights[j][k].doubleValue();
66 this.probabilityOfNew[j][k] = weights[j + 1][k + 1]
67 .divide(weights[j][k], 500, BigDecimal.ROUND_UP)
68 .doubleValue();
69 }
70 }
71 }
72
73 private BigDecimal getBellNumber(int n) {
74 BigDecimal[] binomials;
75 BigDecimal[] bell = new BigDecimal[n + 1];
76 bell[0] = BigDecimal.ONE;
77 bell[1] = BigDecimal.ONE;
78
79 for (int i = 2; i <= n; ++i) {
80 bell[i] = BigDecimal.ZERO;
81 binomials = computeBinomials(i - 1);
82 for (int k = 0; k < i; ++k)
83 bell[i] = bell[i].add(bell[k].multiply(binomials[k]));
84 }
85
86 return bell[n];
87 }
88
89 private BigDecimal[] computeBinomials(int n) {
90 BigDecimal[] binomials = new BigDecimal[n + 1];
91
92 binomials[0] = BigDecimal.ONE;
93 for (int i = 1; i <= Math.floor(n / 2); ++i) {
94 binomials[i] = binomials[i - 1].multiply(new BigDecimal(n - i + 1))
95 .divide(new BigDecimal(i), 100, BigDecimal.ROUND_UP);
96 }
97 for (int i = (int) Math.floor(n / 2) + 1; i <= n; ++i)
98 binomials[i] = binomials[n - i];
99
100 return binomials;
101 }
102
103}
Note: See TracBrowser for help on using the repository browser.