【问题标题】:Biggest possible sum of multiples最大可能的倍数之和
【发布时间】:2015-09-25 10:04:42
【问题描述】:

你会怎么解决这个问题?

您有 2 个数组,每个数组有 n 个数字,n

例如:

n = 4;
first array contains : 16 6 2 10
second array contains : 3 8 12 9
Output : 336

对于第二个数组中的第一个数字 - 3 - 您可以从 16,6 和 2. 最好的选择是选择 2. 现在总和是 3 * 2 = 6;
对于第二个数组中的第二个数字 - 8 - 您可以从 16、6、10 中选择(数字 2 是 已经使用过的)。最好的选择是选择 6。将 8 * 6 加到 sum 上,所以 sum 是 现在 54.
对于第二个数组中的第三个数字 - 12 您可以选择 16,10(2 号和 6 号已使用)。最好的选择是选择 16。 加 12 * 16 到 sum,所以 sum 现在是 246。
从第二个开始的最后一个数字 数组 - 9 - 你只能选择 10。将 9 * 10 加到 sum 中,所以 sum 现在是 336.

我的想法很少,但每个想法都是错误的。例如,我尝试对两个数组进行排序,然后第二个数组中的最大数字乘以第一个数组中的最大可能数字(因为 1. 第二个数组中的数字只能从第一个数组中的 1.-3. 位置中选择,第二个数字只能选择从 1.-4. 等),但这是不对的。另外我还有一些解决方案,但我很难解释它们,因为我不知道如何用英语表达它(但我可以发布代码并尝试解释它),而且它们也不正确。
编辑:我发现了一些可能解决我的问题的算法。第一个是Hungarian algorithm,第二个是Auction Algorithm。这是我第一次接触线性规划...我了解匈牙利算法的工作原理,但我无法实现。在拍卖算法中,我什至不确定它是如何工作的。另外,我不知道他们是否足够快。匈牙利算法的时间复杂度是 O(n^3),在我的例子中我是 n Assignment problem 中,每个“工人”都可以做每一个“工作”,但在我的情况下,这不是真的。
也许可以是Max flow problem,但我不太确定,因为我需要一个完美的匹配——这意味着每个顶点都匹配——我不知道这个算法是否能保证。

【问题讨论】:

  • 你可以用蛮力做吗?
  • 不,我无法使用暴力破解
  • 为什么不用蛮力?作业/理论问题?你想这么解决“真正的问题”(多大)?
  • 这是来自网页的任务,具有测试条目和时间限制,这就是为什么没有暴力破解的原因。我通过此页面执行任务以提高我的技能。

标签: c++ arrays sum mathematical-optimization linear-programming


【解决方案1】:

首先,就我而言,不清楚为什么对于第二个数组中的第一个数字,我们应该只使用第一个数组中的三个第一项,而对于第二个数组中的其他数字,我们使用第一个数组中的任何数字。

但是,我们可以将这两个数组表示为二分图,其中第二个数组中的每个数字都连接到第一个数组中的(每个?*)数字。在该图中,每条边 (u,v) 的权重等于数组 (u*v) 中两个数字的乘积。 对于给定的图表,您应该解析max flow problem

* 如果我正确理解了这个问题,您应该将第二个数组的第一个数字与第一个数组的前 3 个数字连接起来,并将第二个数组的每个其他数字与第一个数组的每个数字连接起来。

【讨论】:

  • 您应该将第二个数组中的每个数字与第一个数组中的前 3 个未使用的数字连接起来。因此,对于第二个数组中的每个数字,您只有 3 个选项。
  • @JozefBugoš,哦,我明白了。因此,您可以创建一个图表,其中第二个数组中的第一个数字将与第一个数组中的前 3 个数字相连;第二个数组中的第二个数字应与第一个数组中的前 4 个项目相连;第三个数字,第一个数组中的前 5 个数字等等……对于这个图,您可以实现(或仅使用)最大流算法。
  • 我也在考虑这个问题,但是在二分图中使用最大流量时遇到了问题。但就在片刻之前,我发现了这个:Maximum Bipartite Matching 和这个matching。我还没有仔细阅读它,但我认为这可能是我的解决方案,对吧?
  • 但是现在我已经阅读了这两篇文章我不确定,因为我需要一个完美的匹配——这意味着每个顶点都匹配。但我也发现了这一点,这似乎与我的问题一模一样:Assignment problem
  • 快速浏览后,我认为匹配问题或分配问题(匈牙利算法)对您没有帮助。对我来说,这看起来像是一个 NP 完全问题。也许我会有一些时间来考虑更多。我认为这种“硬度”的原因是“只有前三个”规则。此规则添加了一些依赖项,这些依赖项导致了顺序依赖的效果。如果这个问题和我想的一样难:基于分支定界的算法/整数规划或约束规划是解决这个问题的自然选择!
【解决方案2】:

继续这样做,直到使用完每个数字。写出这些倍数的最大可能和

这看起来像是一个离散的组合优化问题。我想到的第一个解决这个问题的算法是使用 Branch and Bound 算法。

它允许回溯,你可以用递归来实现它。

【讨论】:

  • 我去看看。
  • @JozefBugoš 你可能需要一些时间来消化它的工作原理,但我很确定它可以解决这个问题。
【解决方案3】:

我使用JuMPJulia 中实现了混合整数编程方法。它适用于您的示例,一般概念应该有效,但可能需要更多测试!

即使你不熟悉 julia,它也应该很容易阅读。请记住,索引从 1 开始(如在 Matlab 中)而不是 0(如在 C、Java、...中)

基本思想如下(阅读 cmets 以了解更多信息):定义一个具有维度 (N,N) 的二进制变量 X:如果 X[a,b] == 1 -> A[b] 在步骤a。

最难理解的部分是 bigM-Formulation,它只是 cmets 中解释的逻辑的一个不同的公式。它的唯一目的是线性化

using JuMP

N = 4
A = [16 6 2 10]
B = [3 8 12 9]

# MODEL
m = Model()

# VARS
@defVar(m, x[1:N, 1:N], Bin)  # N steps, N vars/indices // binary

# CONSTRAINTS
# (1) exactly one var chosen in each step
for s = 1:N 
    @addConstraint(m, sum(x[s,:]) == 1)
end

# (2) each var is chosen exactly once
for v = 1:N 
    @addConstraint(m, sum(x[:,v]) == 1) 
end 

# (3) if var v chosen in step s -> are enough predecessors already taken away -> is in positions 1:3?
for s = 1:N 
    for v = 1:N 
        needed_pops_before = v - 3
        if needed_pops_before > 0
            # bigM formulation:
            # formula: (x[s,v] == 1) -> sum of predecessors taken away until now >= needed_pops
            #   use deMorgan-law -> !(x[s,v] == 1) -> sum >= needed_pops    
            #   formulate with bigM = N because needed_pops limited by N-3
            @addConstraint(m, N * (1-x[s,v])  + sum{x[ss,jj], ss=1:s-1, jj=1:v-1} >= needed_pops_before)
        end 
    end 
end

# OBJECTIVE
@setObjective(m, Max, sum{B[s] * A[v] * x[s,v], s=1:N, v=1:N})

# SOLVE
status = solve(m)

# OUTPUT
println("Objective is: ", getObjectiveValue(m))
println("Solution: ")
for s = 1:N 
    for v = 1:N 
        if getValue(x[s,v]) > 0.00001
            print(A[v], " ")
        end 
    end
end

输出:

Objective is: 336.0
Solution:
2 6 16 10

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多