【问题标题】:Getting permutations of weighted items that add up to a certain amount获得加起来达到一定数量的加权项目的排列
【发布时间】:2021-06-21 15:23:20
【问题描述】:

我有元素 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 或其他库的方法吗?

【问题讨论】:

  • 这听起来像是在解决背包问题。我建议阅读现有解决方案,看看它们是否可以用于解决您的问题。
  • 谢谢!看起来这就是我要找的东西。我认为已经存在解决方案,但我无法搜索正确的单词来找到它。

标签: python permutation


【解决方案1】:

您要寻找的不是排列,而是组合。排列是对有限的元素集进行重新洗牌,没有重复,而组合是 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')]

【讨论】:

    【解决方案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')}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 2018-04-14
      相关资源
      最近更新 更多