[英]Find all the combinations from the given set of numbers that apply to some rules
感谢您对以下问题的帮助:
我有一个数字列表和一本字典:
my_list = [400, 200, 100, 50, 25]
my_dict = {400: 8, 200:4, 100: 2, 50: 2, 25: 2}
我需要找到可以从 my_list 中的数字构建的所有可能组合,当它们应该应用以下规则时:
[400, 400, 400]
是有效组合)[400, 200, 100]
[100, 200, 400]
对我来说与[100, 200, 400]
相同)my_dict[my_list_item]
的总和不应超过 24(例如[400, 400, 400, 100]
无效,因为my_dict[400]+my_dict[400]+my_dict[400]+my_dict[100] = 8+8+8+2 = 26
,因此它不是一个有效的组合)解决这个问题的python算法的任何想法。 谢谢
这是使用迭代器递归执行此操作的代码,以避免在内存中保留太多内容。
#! /usr/bin/env python3
def combs (numbers, value_of, max_numbers=1200, max_value=24, min_i=0):
if len(numbers) <= min_i:
yield []
else:
for comb in combs(numbers, value_of, max_numbers, max_value, min_i+1):
yield comb
comb_copy = [n for n in comb] # Copy to avoid sharing bugs.
numbers_sum = sum(comb)
values_sum = sum([value_of[i] for i in comb])
while True:
comb_copy.append(numbers[min_i])
numbers_sum += numbers[min_i]
if max_numbers < numbers_sum:
break
values_sum += value_of[numbers[min_i]]
if max_value < values_sum:
break
yield comb_copy
my_list = [400, 200, 100, 50, 25]
my_dict = {400: 8, 200:4, 100: 2, 50: 2, 25: 2}
for c in combs(my_list, my_dict):
print(c)
假设你想“名单及每个重复组合”列表中,我写了一个代码,它计算。
它使用一个 while 循环,每次都会增加组合长度计数器。 由于组合的长度可以无限增长,因此该指标用于停止循环,当未找到单个组合时激活该循环。
from itertools import combinations_with_replacement
my_list = [400, 200, 100, 50, 25]
my_dict = {400: 8, 200:4, 100: 2, 50: 2, 25: 2}
final_list = []
combinationLength = 1
while True:
c = list(combinations_with_replacement(my_list, combinationLength)) #generate every combination of length combinationLength
countNextCombination = False #indicator to break the while loop
for combination in c:
if (sum(combination) <= 1200):
dicsum=0
for j in combination:
dicsum+=my_dict[j]
if (dicsum<=24):
final_list.append(list(combination))
countNextCombination = True
if countNextCombination == False: #if not a single combination was valid, finish the loop
break
combinationLength += 1
print (final_list)
使用 itertools,您将不需要递归解决方案。 combine_with_replacement 迭代器将为您提供组合,您只需要检查您的条件。 根据您的要求,您将需要一组强大的组合(即所有尺寸的组合):
例如:
from itertools import combinations_with_replacement as combine
my_list = [400, 200, 100, 50, 25]
my_dict = {400: 8, 200:4, 100: 2, 50: 2, 25: 2}
for size in range(2,len(my_list)+1):
for combo in combine(my_list, size):
if sum(combo) <= 1200 \
and sum(my_dict[c] for c in combo) <= 24:
print(combo)
如果您打算以某种方式处理组合,您可以将它放在一个函数中并使用yield combo
而不是print(combo)
输出:
(400, 400)
(400, 200)
(400, 100)
(400, 50)
(400, 25)
...
(50, 50, 50, 50, 50)
(50, 50, 50, 50, 25)
(50, 50, 50, 25, 25)
(50, 50, 25, 25, 25)
(50, 25, 25, 25, 25)
(25, 25, 25, 25, 25)
请注意,这是一种非优化的蛮力方法,对于小数据集可能没问题,但随着您拥有更多数据,将花费指数级的时间。 有更高级的方法(使用递归)可以通过检查部分总和和/或使用 meoization 来跳过整个组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.