【问题标题】:Combinations that add up to a number - Julia lang加起来就是一个数字的组合 - Julia lang
【发布时间】:2026-01-13 02:15:02
【问题描述】:

我是 Julia 的新手。有没有办法将列表中的元素加起来达到某个值目标?我已经使用 Python 的 itertools 库完成了此操作,如下例所示,但我发现对于较大的数据集来说它非常慢。

import itertools
numbers = [1, 2, 3, 7, 7, 9, 10]
result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == 10]
print result  

【问题讨论】:

    标签: arrays julia method-combination


    【解决方案1】:

    这被称为Knapsack problem,它没有已知的有效解决方案,这意味着唯一已知的解决方案的时间复杂度随着数字的数量增加 eksponentiel (NPC) 如果你碰巧找到了解决这个问题的有效方法,你将赢得一百万美元,因为 P 与 NP 的问题是千年问题之一

    【讨论】:

    • 这应该是没有已知的高效解决方案,不是吗?
    • 猜你是对的。但你明白了:-)
    【解决方案2】:

    虽然正如 Kermit 所提到的,这个问题是 NP 难的,但仍然值得知道如何解决这些问题。 虽然其中一些类型有专门的启发式算法,但您可以做的最简单、最快的事情就是使用求解器:

    using JuMP, Cbc
    numbers = [1, 2, 3, 7, 7, 9, 10]
    target = 35
    m = Model(Cbc.Optimizer)
    
    @variable(m, x[1:length(numbers)], Bin)
    @constraint(m, numbers'*x == target)
    optimize!(m)
    
    res_x = round.(Int,value.(x))
    
    @assert numbers'*res_x == target
    

    对于较大的数字集,此代码将比您的代码快几个数量级。使用商业求解器(Gurobi、CPLEX、Fico)代替 Cbc 可以进一步提高速度。

    但是 CBC 似乎相当不错(即使对于较大的应用程序也是如此)。看看numbers 的这个基准测试,它有50_000 元素,需要 17 秒才能用 Cbc 解决:

    using JuMP, Cbc, StatsBase, Random
    Random.seed!(0)
    numbers = rand(1:30_000,50_000)
    target = sum(sample(numbers,45_000,replace=false))
    m = Model(Cbc.Optimizer)
    
    @variable(m, x[1:length(numbers)], Bin)
    @constraint(m, numbers'*x == target)
    

    现在:

    julia> @time optimize!(m)
    ...
    Result - Optimal solution found
    
    Objective value:                0.00000000
    Enumerated nodes:               605
    Total iterations:               615
    Time (CPU seconds):             7.57
    Time (Wallclock seconds):       7.57
    
    Total time (CPU seconds):       7.60   (Wallclock seconds):       7.60
    
     17.666201 seconds (40.22 M allocations: 2.372 GiB, 5.82% gc time, 0.83% compilation time)
    

    【讨论】:

    • 您好,感谢您之前的帮助,我已经在“组合加到一个目标 - Julia lang”下稍微扩展了这个问题。
    最近更新 更多