Reputation: 9435
Hello say I have some data A -> ....
(n data points). Now I take from this data a given number of values (m) - and now I wish to iterate over all unique combinations of these values.
An example for 5 values where you take 2 unique: A unique combination would be a something like "a + b" or "a + c" - however "c + d" is the same as "b + c". And "B + E" is the same as "A + D"
A x x x x
B x x x
C x x
D x x
E x
Those describe some geometrical "lines", and the whole specimen can be "mirrored" around the middle point. So for an arbitrary number of lines, is there a clever algorithm to iterate over everything considering this "mirror ability"?
And what is a formula to calculate the number of elements given the set size n and the number of items m?
---- an example with "3 out 6":
It also resembles closely the function combine(6,3) - however now I marked the duplicate rows with - instead of x.
1 1 1 1 1 1 1 1 1 1 2
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
A x x x x x x x x - - A
B x x x x x x - - - - B
C x x x x x x - - - - C
D x x x - x - - - - - D
E x x x - x - - - - - E
F x x - - - - - - - - - F
So possible list would be:
ABC, ABD, ABE, ABF, ACD, ACE, ACF, ADE, BCD, BCE
10 out of 20 potential candidates ignoring the symetry.
Upvotes: 2
Views: 113
Reputation: 66922
Not easily. In fact it's quite difficult. But here's the rundown:
for_each_unmirrored()
mark first element as part of the set.
mark last element as definitely NOT part of the set.
//we know no matter whats inside, this isnt't semetrical, so all combinations
for_each_mirrored() on all elements between these.
mark first element as part of the set.
mark last element as part of the set.
//ends are semetrical, so insides cannot be
for_each_unmirrored() on all elements between these
mark first element as definitely not part of the set.
mark last element as definitely not in the set.
//ends are semetrical, so insides cannot be
for_each_unmirrored() on all elements between these
for_each_mirrored()
for each element
mark it as part of the set.
if more elements are needed
for_each_mirrored on elements to the right but in range
Yeah, even the abreviated pseudocode is complicated. The real code is here: http://ideone.com/WDEn40 (including showing that it works for 6 elements pick 3). The linked code isn't as simple as it could be, because I optimized it to avoid allocations and minimize function calls. (As a side effect, the for_each_call_helper
isn't threadsafe. If this needs to be threadsafe, simply remove the static
keyword from the variables in this function.)
Upvotes: 1
Reputation: 571
I confess that I don't fully understand the question either. However, the general way to solve problems like this is to come up with a good notation and a canonical form, and an algorithm to convert something to canonical form. Then you just do the heavy stuff on canonical forms, and don't repeat.
Upvotes: 0