Python 如何生成给定长度的所有可能组合
假设我们有一个价格清单Python 如何生成给定长度的所有可能组合,python,python-3.x,combinations,Python,Python 3.x,Combinations,假设我们有一个价格清单项目\u价格=[1500、2000、1600、2100、2200、1400、1900] 我们希望找到所有可能的组合,将所有7种价格放入包含每个桶中以下数量价格的桶中[3,2,2]。价格是否放在同一个桶内并不重要,但放在哪个桶的价格才重要 如何做到这一点?我发现了,但它假设我们只对给定元素的r长度子序列的一个组合感兴趣。然而,在这里,我们也对包含3价格、然后是2和最后是2的第一个组合后的剩余部分感兴趣 请注意,给定区间中的7个价格和组合是一个一般问题的简单例子。首先,您发布的
项目\u价格=[1500、2000、1600、2100、2200、1400、1900]
我们希望找到所有可能的组合,将所有7种价格放入包含每个桶中以下数量价格的桶中[3,2,2]
。价格是否放在同一个桶内并不重要,但放在哪个桶的价格才重要
如何做到这一点?我发现了,但它假设我们只对给定元素的r
长度子序列的一个组合感兴趣。然而,在这里,我们也对包含3
价格、然后是2
和最后是2
的第一个组合后的剩余部分感兴趣
请注意,给定区间中的7个价格和组合是一个一般问题的简单例子。首先,您发布的答案没有任何假设。”“组合”是一个定义明确的术语。看 其次,我将按以下方式处理问题(在伪代码中):
- 生成从
到0
len(项目价格)-1的所有索引列表
- 从给定索引生成长度为3的所有组合的列表(使用组合的正式定义和链接的
函数)itertools.combines
- 对于每个生成的组合:
- 删除选定的索引
- 从剩余的索引列表中为下一个bucket(在长度2的示例中)生成组合
我使用指数而不是元素来处理价格可能在输入上重复的情况。如果您有一个约束,即它们是不同的,您可以使用实际值。我可能错误地解释了这一点,如果我有,将编辑此答案,但我假设单个组中的顺序并不重要 如果是这样,则有7C5=21种独特的方式(例如,在3组中,
[1500,2000,1600]
与[2000,1600,1500]
相同)。我只是简单地做了所有独特的组合(不是排列),从7中选择5个价格,然后将这5个价格分成3和2,然后附加剩余的2个未选择的值作为第三组(按任意顺序)
它们是:
((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))
根据
[(chosen_5[:3], chosen_5[3:5], tuple(set(items_prices) - set(chosen_5))) for chosen_5 in tuple(itertools.combinations(items_prices, 5))]
请注意,在所有3个元组中,实际值并不完全相同,即使顺序不同,因为我们不关心值的顺序-我们可以将每个顺序中的3个元组视为3个(冻结)集
但是,如果您的意思是单个组中的顺序确实重要,那么有7个!=5040个可能的排列,这与选择7个中的任意1个相同,然后再选择6个还押中的任意1个(因为您选择了一个),然后选择5个中的1个。。。一直到最后一个1。它们都可以使用
[(this_permutation[:3], this_permutation[3:5], this_permutation[5:]) for this_permutation in itertools.permutations(items_prices)]
请注意,第一个元组和第二个元组是不同的,因为2200和1500的顺序不同,在使用组合而非排列的其他输出中无法区分这两个元组您能提供您期望的输出吗?请给出两个示例以澄清什么是,什么不是,在价格安排上很重要。分开的桶有什么区别吗?我看不出
ABCDEFG
和三个单独的桶ABC
和DE
和FG
之间有什么区别。我们的目标是最大限度地降低价格。假设我们桶里的物品越多,一桶里最便宜的物品的折扣就越多。比方说,当2件物品在桶中时,我们可以享受10%的折扣;当3件物品在桶中时,我们可以享受20%的折扣,依此类推。然而,为了获得更高的价格,将商品分成几个桶可能是值得的,而不是在一个桶中全部购买。目前还不清楚3/2/2范围内的商品顺序是否重要。如果秩序确实重要,那么@YossiLevi的解决方案就很好了。如果顺序不重要,那么您需要使用itertools.combinations提取三个元素,然后使用嵌套的itertools.combinations处理其他四个元素。答案的第一部分是我一直在寻找的。我们不关心单个bucket中的顺序(在tuple中)。很好的一行。
((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))
...