获取加权项的排列,这些加权项加起来一定数量

2024-06-17 08:58:02 发布

您现在位置:Python中文网/ 问答频道 /正文

元素A权重为1,元素B权重为2。我需要找到A和B的可能排列,它们加起来一定量

例如,当所需金额为4时,我希望得到的是:

[A, A, A, A] 
[B, B]  
[B, A, A]  
[A, B, A]  
[A, A, B]

做这样的事情最好的方法是什么?起初,我试图通过使用itertools.permutations和手动检查求和(效率很低,但我不确定还能去哪里)来强制执行它,但对于更大的数字,这是不可能的。如果可能的话,我想知道一种不导入itertools或其他库的方法


Tags: 方法元素数字手动事情金额权重效率
2条回答
from itertools import permutations, chain


def get_permutations_count_to_n(item_dict, n, max_items=4):
    """ For a given dict with items as keys and weights as values, return a set of permutations that have a combined weight of N
    :param item_dict: dictionary with items as keys and their weight as value 
    :param n: integer that should be the combined weight of permutated items
    :param max_items: the maximum number of items that may occur in a permutation """
    item_list = list(items.keys()) * max_items
    combs = [list(permutations(item_list, i)) for i in range(1, max_items+1)]
    filtered_combs = [comb for comb in chain.from_iterable(combs) if sum(item_dict[x] for x in comb) == n]
    return set(filtered_combs)

items = {'A': 1, 'B': 2}
get_permutations_count_to_n(items, n=4)
>>> {('B', 'A', 'A'), ('B', 'B'), ('A', 'A', 'A', 'A'), ('A', 'A', 'B'), ('A', 'B', 'A')}

你要找的不是排列,而是组合。置换是在不重复的情况下重新排列有限的元素集,而组合是假定n元素之一的m字段中的每一个,在python中用itertools.computations_with_replacement表示。在代码方面:

import itertools
from functools import reduce

elements = {"A": 1, "B": 2, "C": 1}
sum_restriction = lambda x: sum(elements[i] for i in x)==4
max_els = 4 // min(elements.values()) + 1

res = reduce(lambda x,y:x+y,[list(filter(sum_restriction, itertools.combinations_with_replacement(elements.keys(), i))) for i in range(max_els+1)])

我的示例返回:

>>> res
[('B', 'B'), ('A', 'A', 'B'), ('A', 'B', 'C'), ('B', 'C', 'C'), ('A', 'A', 'A', 'A'), ('A', 'A', 'A', 'C'), ('A', 'A', 'C', 'C'), ('A', 'C', 'C', 'C'), ('C', 'C', 'C', 'C')]

相关问题 更多 >