[英]How to generate all possible combinations of given length
Assume we have a list of prices items_prices = [1500, 2000, 1600, 2100, 2200, 1400, 1900]
.假设我们有一个价格列表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]
.我们想要找到将所有 7 个价格放入每个桶中包含以下价格数量的桶的所有可能组合[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.我找到了这个答案,但它假设我们只对给定元素的r
长度子序列的一种组合感兴趣。 However here, we are also interested in the remains after the first combination containing 3
prices, then 2
and lastly 2
.然而,在这里,我们也对包含3
价格的第一个组合之后的剩余部分感兴趣,然后是2
,最后是2
。
Please note that the 7 prices and the combination in the given bucket is a simple case of a general problem.请注意,给定桶中的 7 个价格和组合是一般问题的简单情况。
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 (eg in group of 3, [1500, 2000, 1600]
is the same as [2000, 1600, 1500]
).如果是这样,则有 7C5 = 21 种独特的方式(例如,在 3 组中, [1500, 2000, 1600]
与[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).我只是做所有独特的组合(不是排列),从 7 中选择 5 个价格,然后将 5 分成 3 和 2,然后附加剩余的 2 个没有被选为第 3 组的值(按任一顺序)。
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.请注意,在所有 3 个元组中,实际值并不完全相同,即使顺序不同,因为我们不关心值的顺序 - 我们可以将每个顺序中的 3 个元组视为 3 个(冻结)集.
However, if you meant that the ordering in the individual groups does matter, then there are 7!但是,如果您的意思是各个组中的排序确实很重要,那么有 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 = 5040 个可能的排列,这与选择 7 个中的任意 1 个相同,然后是 6 个剩余中的任意一个(因为您已经选择了一个),然后是 5 个中的 1 个......直到最后一个。他们都可以计算使用
[(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请注意,第一个和第二个元组是不同的,因为 2200 和 1500 的顺序不同,在使用组合而非排列的其他输出中不会区分
Firstly, the answer you posted does not assume anything.首先,您发布的答案不假设任何内容。 'Combination' is a well-defined term. “组合”是一个定义明确的术语。 See https://mathworld.wolfram.com/Combination.html见https://mathworld.wolfram.com/Combination.html
Secondly, I would approach the problem as follows (in pseudo-code):其次,我会按如下方式处理问题(在伪代码中):
0
to len(items_prices) - 1
生成从0
到len(items_prices) - 1
的所有索引的列表itertools.combinations
function you linked).从给定的索引生成长度为 3 的所有组合的列表(使用您链接的 Combination 和itertools.combinations
函数的正式定义)。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.如果您有不同的约束,您可以使用实际值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.