1 | package geniusweb.ip.general;
|
---|
2 |
|
---|
3 | import java.util.Arrays;
|
---|
4 |
|
---|
5 | public class SubsetEnumerator {
|
---|
6 | /**
|
---|
7 | * Object used to enumerate all subsets of size k out of n elements. Every
|
---|
8 | * subset is represented in bit format (i.e., bit mask), e.g.: - given 10
|
---|
9 | * elements, the first subset is {1,2,3}, represented as: 0000000111
|
---|
10 | *
|
---|
11 | * @param n: The total number of elements
|
---|
12 | * @param s: The size of the subsets that will be enumerated
|
---|
13 | */
|
---|
14 | final private int n;
|
---|
15 | final private int s;
|
---|
16 | private int currentSubset;
|
---|
17 |
|
---|
18 | // *********************************************************************************************************
|
---|
19 |
|
---|
20 | /**
|
---|
21 | * The constructor...
|
---|
22 | */
|
---|
23 | public SubsetEnumerator(int n, int s) {
|
---|
24 | this.n = n;
|
---|
25 | this.s = s;
|
---|
26 | }
|
---|
27 |
|
---|
28 | // *********************************************************************************************************
|
---|
29 |
|
---|
30 | /**
|
---|
31 | * An example of how to use this class (just for testing)...
|
---|
32 | */
|
---|
33 | public static void main(String[] args) {
|
---|
34 | int n = 6;
|
---|
35 | System.out.println(
|
---|
36 | " Testing the subset enumerator object \n The total number of elements is: "
|
---|
37 | + n);
|
---|
38 | // enumerate all subsets of size = 1, 2, ... n
|
---|
39 | for (int s = 1; s <= n; s++) {
|
---|
40 | System.out.println("Current subset size is: " + s);
|
---|
41 | SubsetEnumerator subsetEnumerator = new SubsetEnumerator(n, s);
|
---|
42 | int subset = subsetEnumerator.getFirstSubset(); // this will return
|
---|
43 | // the first subset
|
---|
44 | // in the list
|
---|
45 | while (subset < (1 << n)) {
|
---|
46 | // Put here the code that needs to deal with "subset", e.g.,
|
---|
47 | // printing it as below:
|
---|
48 | System.out.println("the current subset is " + Arrays.toString(
|
---|
49 | Combinations.convertCombinationFromBitToByteFormat(
|
---|
50 | subset, n, s)));
|
---|
51 | // generate the next subset
|
---|
52 | subset = subsetEnumerator.getNextSubset();
|
---|
53 | }
|
---|
54 | }
|
---|
55 | }
|
---|
56 |
|
---|
57 | // *********************************************************************************************************
|
---|
58 |
|
---|
59 | /**
|
---|
60 | * Given a subset, C, of size "s", this method returns the subset C' that is
|
---|
61 | * located just after C in the list of subsets of size s. If there is no
|
---|
62 | * such subset (i.e., if we have reached the end of the list), then the
|
---|
63 | * method returns 1<<n.
|
---|
64 | */
|
---|
65 | public int getFirstSubset() {
|
---|
66 | currentSubset = 0;
|
---|
67 | for (int i = 0; i < s; i++)
|
---|
68 | currentSubset += (1 << i);
|
---|
69 | return (currentSubset);
|
---|
70 | }
|
---|
71 |
|
---|
72 | // *********************************************************************************************************
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * If (currentSubset = C), this method sets (currentSubset = C') where C' is
|
---|
76 | * located just after C in the list of subsets of size s. If there is no
|
---|
77 | * such subset (i.e., if we have reached the end of the list), then the
|
---|
78 | * method returns "1<<n".
|
---|
79 | */
|
---|
80 | public int getNextSubset() {
|
---|
81 | currentSubset = Combinations.getPreviousCombinationInBitFormat2(n, s,
|
---|
82 | currentSubset);
|
---|
83 | return (currentSubset);
|
---|
84 | }
|
---|
85 | } |
---|