Reputation: 69
Assume we have a list of prices items_prices = [1500, 2000, 1600, 2100, 2200, 1400, 1900]
.
We want to find all the possible combinations of putting all 7 prices into buckets containing the following number of prices in each bucket [3, 2, 2]
. It does not matter whether the price is placed inside the same bucket, but it does matter to which bucket price is placed.
How to do this? I found this answer, but it assumes we are interested only in one combination of r
length subsequence of given elements. However here, we are also interested in the remains after the first combination containing 3
prices, then 2
and lastly 2
.
Please note that the 7 prices and the combination in the given bucket is a simple case of a general problem.
Upvotes: 1
Views: 442
Reputation: 745
I may have interpreted this incorrectly, and will edit this answer if I have, but I'm assuming that the order within a single group of does not matter.
If so, there are 7C5 = 21 unique ways (e.g. in group of 3, [1500, 2000, 1600]
is the same as [2000, 1600, 1500]
). I simply do all the unique combinations (not permutations) of selecting 5 prices from 7, then split that 5 into a 3 and 2, then append the remaining 2 values not picked as the 3rd group (in either order).
They are:
((1600, 1400, 1900), (2000, 2100), (2200, 1500))
((1600, 1400, 1900), (2000, 2200), (1500, 2100))
((1600, 1400, 1900), (2000, 1500), (2200, 2100))
((1600, 1400, 1900), (2100, 2200), (2000, 1500))
((1600, 1400, 1900), (2100, 1500), (2000, 2200))
((1600, 1400, 1900), (2200, 1500), (2000, 2100))
((1600, 1400, 2000), (2100, 2200), (1500, 1900))
((1600, 1400, 2000), (2100, 1500), (2200, 1900))
((1600, 1400, 2000), (2200, 1500), (1900, 2100))
((1600, 1400, 2100), (2200, 1500), (2000, 1900))
((1600, 1900, 2000), (2100, 2200), (1400, 1500))
((1600, 1900, 2000), (2100, 1500), (1400, 2200))
((1600, 1900, 2000), (2200, 1500), (1400, 2100))
((1600, 1900, 2100), (2200, 1500), (1400, 2000))
((1600, 2000, 2100), (2200, 1500), (1400, 1900))
((1400, 1900, 2000), (2100, 2200), (1600, 1500))
((1400, 1900, 2000), (2100, 1500), (1600, 2200))
((1400, 1900, 2000), (2200, 1500), (1600, 2100))
((1400, 1900, 2100), (2200, 1500), (1600, 2000))
((1400, 2000, 2100), (2200, 1500), (1600, 1900))
((1900, 2000, 2100), (2200, 1500), (1600, 1400))
Calculated from
[(chosen_5[:3], chosen_5[3:5], tuple(set(items_prices) - set(chosen_5))) for chosen_5 in tuple(itertools.combinations(items_prices, 5))]
Note that in all 3 tuples, the actual values are not all the same, even if the order is different since we don't care what order the values are in - we can treat the 3 tuples in each order as 3 (frozen) sets.
However, if you meant that the ordering in the individual groups does matter, then there are 7! = 5040 possible permutations, which is the same as picking any 1 of 7 then after that, any 1 of the 6 remaning (since you've picked one out) then 1 of 5... down to the last 1. They can all be calculated using
[(this_permutation[:3], this_permutation[3:5], this_permutation[5:]) for this_permutation in itertools.permutations(items_prices)]
((1500, 2000, 1600), (2100, 2200), (1400, 1900))
((1500, 2000, 1600), (2100, 2200), (1900, 1400))
((1500, 2000, 1600), (2100, 1400), (2200, 1900))
((1500, 2000, 1600), (2100, 1400), (1900, 2200))
((1500, 2000, 1600), (2100, 1900), (2200, 1400))
((1500, 2000, 1600), (2100, 1900), (1400, 2200))
((1500, 2000, 1600), (2200, 2100), (1400, 1900))
((1500, 2000, 1600), (2200, 2100), (1900, 1400))
((1500, 2000, 1600), (2200, 1400), (2100, 1900))
((1500, 2000, 1600), (2200, 1400), (1900, 2100))
((1500, 2000, 1600), (2200, 1900), (2100, 1400))
((1500, 2000, 1600), (2200, 1900), (1400, 2100))
...
Note that the first and second tuple are distinct because the 2200 and 1500 are in a different order, which would not be distinguished in the other output using combinations not permutations
Upvotes: 1
Reputation: 25966
Firstly, the answer you posted does not assume anything. 'Combination' is a well-defined term. See https://mathworld.wolfram.com/Combination.html
Secondly, I would approach the problem as follows (in pseudo-code):
0
to len(items_prices) - 1
itertools.combinations
function you linked).carry on as long as you have no buckets left.
I used indices instead of elements to handle the cases where prices may be duplicated on input. If you have a constraint that they are different, you may use the actual values.
Upvotes: 0