Friday, 15 August 2014

algorithm - Efficient enumeration of subsets -


I am currently working on an algorithm for a mathematical optimization problem and I have to deal with the following situation.

In many circumstances, the algorithm needs to decide which subsetting S ???? N is the best in this situation.
n = {0, 1, 2, ..., 126, 127}
| S | a???? {0, 1, 2, 3, 4, 5} (subtitle size ranges from 0 to 5)

This gives the total number of possible subsets of 265.982.833. (128, 5) + binom (128, 4) + ... + binom (128, 0))

If I make all possible subsets accurate and store them in the array, then This array

In this case, when the algorithm needs to know which element is in one, without any optimization and meaningful storage of conspiracy, without any memory footprint, 265.982.833 entries and one Memory footprint. Specific subsets with index I just need a table lookup. However large memory requirements are not acceptable.

So my question is basically if someone has to think about the algorithm, then on the basis of the index it requires a pre-filled array to calculate the elements efficiently.


Edited samples:
lookupTable [0] = {}
lookupTable [1] = {0}
... lookuplable [127] = {126}
lookupTable [128] = {127}
lookupTable [12 9] = {0, 1}
lookupTable [130] = {0, 2}
... ... lookupTable [265982832 ] = {123, 124, 125, 126, 127}

To create each subset from the previous Direct subset for It is straightforward to represent a subset in the form of a 128-bit number (although obviously most values ​​will not map to a merit subset, and I do not know if the value of 128 in question is either real or just an example. ) That's definitely the first approach I will use; If this works, then it is all O (1) and the storage cost is not high (16 bytes for index instead of 4).

If you really want to store a brief index for the subset, then I have the following recycling, where S (N, K) represents all the values ​​(or the number of subsets) size sizes ≤ k From & lt; N:

s (n, 0) = {{}}}
s (n, k) = (s (n-1, k- 1)) and Audot; {N}) and the union; S (n-1, k) if n ≥ k & gt; 0
s (n, k) = {} if n & lt; K

Where operator P & O; S means "Add s to each element of p (and therefore the result is the same size as P ). Therefore, a counting algorithm is seen as, we get:

S (n, 0) = 1
S (n, k) ) = S (n-1, k-1) + s (n -1, k) if n ≥ k & gt; 0
S (n, k) = 0 if n & lt; K

The second recurrence can be expressed again:

S (n, k) = Σ n I = s S (i-1, k-1)
(which look good with JSM, Grow.)

This is another way of saying that we will generate the set by the largest element, so we start with the set {0 ... k-1} Then with {k} as the greatest element, then with all the {k + 1} , and so on. Within each set of sets, we retrieve the (k-1) -set-shaped set, then start with at least the maximum value and with the maximum value selected by us Work for less than one.

So we can understand that the largest value in the indexed set is in the S (n, k) respectively, in the S (i-1, k -1) to i to k to n the result will be negative; So we add {i} to the result set; Reduce k by 1 and repeat with n now set to i-1 .

If we already add the relevant table of s (n, k) , of which approximately 640 are valid combinations, then instead of replacing it by looking for the code Using binary search> I is at each stage, so calculation takes time k log (n) , which is not terrible.

No comments:

Post a Comment