【问题标题】:Find combinations of size r from a set with decreasing sum value从总和值递减的集合中找到大小 r 的组合
【发布时间】:2023-12-01 00:47:01
【问题描述】:

我有一组数字,例如。 [100,90,80,70,60,50] 并希望找到大小为 r=3 的所有组合,但按总和递减的顺序。 按降序排列数字不起作用,例如。

(100, 90, 80) 270
(100, 90, 70) 260
(100, 90, 60) 250
(100, 90, 50) **240**
(100, 80, 70) **250**
(100, 80, 60) 240

我怎样才能找到这样一个总和值递减的组合集。

【问题讨论】:

标签: algorithm combinations combinatorics discrete-mathematics


【解决方案1】:

这里是代码

import itertools

array = [100,90,80,70,60,50]
size = 3
answer = [] # to store all combination
order = [] # to store order according to sum
number = 0 # index of combination

for comb in itertools.combinations(array,size):
    answer.append(comb)
    order.append([sum(comb),number]) # Storing sum and index
    number += 1

order.sort(reverse=True)  # sorting in decreasing order

for key in order:
    print key[0],answer[key[1]] # key[0] is sum of combination

上述代码的输出是

270 (100, 90, 80)
260 (100, 90, 70)
250 (100, 80, 70)
250 (100, 90, 60)
240 (90, 80, 70)
240 (100, 80, 60)
240 (100, 90, 50)
230 (90, 80, 60)
230 (100, 70, 60)
230 (100, 80, 50)
220 (90, 70, 60)
220 (90, 80, 50)
220 (100, 70, 50)
210 (80, 70, 60)
210 (90, 70, 50)
210 (100, 60, 50)
200 (80, 70, 50)
200 (90, 60, 50)
190 (80, 60, 50)
180 (70, 60, 50)

【讨论】:

    【解决方案2】:

    第一个(也是天真的)解决方案是遍历所有可能的排列,并将这些集合保存在最小堆中。最后,只需一一删除所有集合。
    运行时间:假设 x = n 选择 r,所以 O(xlogx)

    第二个稍微复杂一点:
    * 您需要保存到目前为止找到的最小数量
    * 现在您正在迭代与您的示例完全一样的一个更改,要知道您要移动到的下一组是什么,您必须用数组中的下一个数字替换当前集合中的每个数字,并替换 max 选项小于比您节省的最低金额。当然,将最小值设置为新的最小值。
    运行时间:O((n 选择 r)*r)

    【讨论】:

    • 为什么不呢?下一步必须小于或等于的条件将保证您将始终递减,并且所有选项的最大值将保证您不会错过任何选项
    • “用数组中的下一个数字替换当前集合中的每个数字”将跳过有效组合。我怀疑这就是你的意思。但是替换一个元素并不能保证找到下一个更小的组合。
    最近更新 更多