Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 等于或超过给定数字的所有组合_Algorithm_Language Agnostic_Combinations_Subset Sum - Fatal编程技术网

Algorithm 等于或超过给定数字的所有组合

Algorithm 等于或超过给定数字的所有组合,algorithm,language-agnostic,combinations,subset-sum,Algorithm,Language Agnostic,Combinations,Subset Sum,这与换硬币问题不同 给定一个dictx=[a:1,b:2,c:1,d:3,e:2],我需要计算所有可能的键组合,使与这些键相关的值之和刚好超过或等于给定值,比如5。仅超过5意味着,如果所选元素小于5,我们可以再添加一个元素,即使它超过5,但一旦我们超过或等于5,就不能再添加更多元素 有两个问题使我的方法复杂化- 请注意,有些值是重复的,例如1和2各出现两次,需要单独考虑 在这种情况下订购物品 订购事宜也是如此,[b,c,d],[b,d,c],[c,b,d],[d,b,c],[d,b,c],[d,

这与换硬币问题不同

给定一个dict
x=[a:1,b:2,c:1,d:3,e:2]
,我需要计算所有可能的键组合,使与这些键相关的值之和刚好超过或等于给定值,比如5。仅超过5意味着,如果所选元素小于5,我们可以再添加一个元素,即使它超过5,但一旦我们超过或等于5,就不能再添加更多元素

有两个问题使我的方法复杂化-

  • 请注意,有些值是重复的,例如1和2各出现两次,需要单独考虑
  • 在这种情况下订购物品
  • 订购事宜也是如此,
    [b,c,d],[b,d,c],[c,b,d],[d,b,c],[d,b,c],[d,c,b]
    均单独包含在内。理想情况下,只有当我们超过5时,排序才重要,只要总和正好是5,排序就不重要

    因此,上述问题的一些解决方案是使用和7的
    [a,b,c,d]
    ,使用和6的
    [a,b,c,e]
    ,使用和6的
    [b,c,d]
    ,使用和5的
    [d,e]
    ,等等

    我如何处理这个问题。我曾考虑使用硬币兑换的输出,然后在每个结果列表中添加一个元素,但这并不能涵盖所有情况

    编辑1:确定问题框架的更好方法可能是找到所有组合,使总和(i)等于5或(ii)刚好超过5,直到最后一个元素小于5,因此添加最后一个元素使其大于5。一旦我们有5个或>5个,就不会添加额外的元素

    编辑2:澄清订购问题。为了提供一点上下文,键是设备,值是它所需要的资源。可用资源总量为5。并且设备根据其密钥分配资源,即首先服务第一个密钥-值对(按照密钥字母顺序排序)。对于
    b
    ,它需要2个,但假设只有1个资源可用-它将被分配1个,其余1个将在下一次运行中分配(溢出)。因此,当总和正好为5时,顺序并不重要,因为每个人都得到了自己想要的东西,并且不会溢出到下一个插槽。例如,
    ed
    de
    意味着两者都得到了他们想要的东西,因此它们都应该被包括在内。
    但是对于仅仅由于添加了最后一个元素而超过5的列表,排序问题只会对最后一个元素产生溢出效应。例如,
    dce
    表示d和c分别得到3和1,E只得到1(1溢出到下一次运行)。类似地,
    ced
    意味着c和d分别得到1和3,溢出效应发生在d上,因为它只得到1。

    我认为这样改变换币算法可以解决问题

    import itertools
    def subset_sum(numbers, target, partial=[]):
        exceed = sum([ v for k, v in partial[:-1]])
        s = sum([ v for k, v in partial])
        if exceed >= target:
            return
        elif s == target: 
            print (partial,sum([ v for k, v in partial]), target)
        elif s > target:
            print("print all permutation")
            p = list(itertools.permutations(partial))
            for state in p:
                legit = sum([v for k, v in state[:-1]])
                if (legit < target):
                    print(state)
    
        for i in range(len(numbers)):
            k, v = numbers[i]
            remaining = numbers[i+1:]
            subset_sum(remaining, target, partial + [(k,v)])
    
    if __name__ == "__main__":
        subset_sum([('a',1),('b',2),('c',1),('d',3),('e',2)],5)
    
    导入itertools
    def subset_sum(数字、目标、部分=[]):
    超过=总和([v代表k,v代表部分[:-1]]
    s=总和([v代表k,v代表部分])
    如果超过>=目标:
    返回
    elif s==目标:
    打印(部分,求和([v代表k,v代表部分]),目标)
    elif s>目标:
    打印(“打印所有排列”)
    p=列表(itertools.置换(部分))
    对于p中的状态:
    legit=总和([v代表k,v处于状态[:-1]])
    如果(合法<目标):
    打印(状态)
    对于范围内的i(len(数字)):
    k、 v=数字[i]
    剩余=数字[i+1:]
    子集_和(剩余,目标,部分+[(k,v)])
    如果名称=“\uuuuu main\uuuuuuuu”:
    子集和([('a',1),('b',2),('c',1),('d',3),('e',2)],5)
    
    更新的答案 关于需求的更多细节已添加到问题中。我认为这个版本与他们相符。但是没有指定预期的输出结构,因此这是一个猜测。它最终会得到如下一系列结果:

    {首字母:{a:1,b:2,c:1},末字母:{d:3}
    
    或者像这样:

    {initial:{b:2,c:1,e:2}
    
    它通过首先使用函数
    partitions
    查找初始值的所有子集及其补码来实现<代码>分区(['a','b','c','d'])将有16个元素,包括
    [[a','b','d'],['c']]
    [[b','d'],['a','c','d']
    [[],['a','b','c','d']]

    然后,对于每个分区,如果其左半部分的和等于目标,我们将其包括在内。如果总和小于目标值,我们将在右半部分的每个值中包含一个结果,使我们超过目标值

    下面是一个Javascript实现:

    //实用程序函数
    const last=(xs)=>
    xs[xs.length-1]
    常量分区=(xs)=>
    xs.length==0
    ? [[[], []]]
    :分区(xs.slice(0,-1)).flatMap([p,q])=>[
    [p,last(xs)],q],
    [p,[…q,last(xs)]]
    ])
    //辅助函数
    常量总计=(xs)=>
    x.reduce((a[k,v])=>a+v,0)
    //主要功能
    const sumTo=(n,xs,parts=分区(xs))=>
    parts.flatMap(([incl,excl],[uuu,[uuuuu,t=total(incl))=>[
    …(t==n?[{initial:incl}]:[]),
    …(tv+t>n)
    .map(e=>({首字母:incl,last:[e]}))
    : []
    )
    ])
    //公共职能
    常量子类=(n,dict)=>
    sumTo(n,Object.entries(dict))
    .map({initial,last})=>({
    首字母:Object.fromEntries(首字母),
    …(last?{last:Object.fromEntries(last)}:{})
    }))
    //样本数据
    常量dict={a:1,b:2,c:1,d:3,e:2}
    //演示
    console.log(subsetSum(5,dict))

    .as console wrapper{max height:100%!important;top:0}
    您需要它是正确的,还是快速正确的?@b我想了解如何解决这个问题,所以它必须首先是正确的。一旦我有了一个工作代码,我将尝试看看如何使它变得更好