【问题标题】:Dynamic Programming, max subarray with constraint动态规划,带约束的最大子数组
【发布时间】:2014-11-13 07:05:59
【问题描述】:

所以我一直在研究这个问题,它与选择具有给定约束的最大子数组有关。问题如下:

Yuckdonalds 正在考虑在 Quaint Valley Highway 沿线开设一系列餐厅 (QVH)。可能的位置在一条直线上,并且这些位置的距离 从 QVH 开始的位置,以英里为单位,按升序排列, 米1;平方米; : : : ; mn

约束如下: 在每个地点,Yuckdonalds 最多可开设一家餐厅。预期的 在当地开餐厅获利 i 是 pi,其中 pi > 0 且 i = 1;2; : : : ; n

任何两家餐馆都应该至少相距 k 英里,其中 k 是一个正整数。

我已将排序后的数组 M 视为二进制堆,我的算法包括遍历二进制堆的每个索引(在数组 M 中)并选择其左/右子节点的最大值,只要它满足距离约束 k。然后用索引的左右孩子递归调用函数。

似乎我正在选择一些最佳指标,因为这是输出所暗示的,但我遗漏了一些东西,但我无法弄清楚是什么。 PS。这不是给学校的,那是一个多月前的事了,我现在正在编码它是为了好玩,我知道我的 tempProfit 变量现在没用了

def binHandle(parent, M, P, tmp, lc):

    lastchosen = lc
    i = parent
    left = 2*i
    right = 2*i + 1
    if left > len(M):
            return

    parent = M[parent]

    if right <= len(M) and left < len(M):
            childRestL = M[left]
            childRestR = M[right]

            #choose best child
            if distance(lastchosen, childRestL) >= k:
                    if P[right] > P[left]:
                            outcome = P[right]
                            lastchosen = M[right]
                            tmp += outcome
                            print outcome
                            binHandle(right , M, P, tmp, lastchosen)

                    else:
                            outcome = P[left]
                            lastchosen = M[left]
                            tmp += outcome
                            print outcome
                            binHandle(left , M, P, tmp, lastchosen)

def maxprofits(M, P, k):
    maxProf = 0
    global tempProfit
    tempProfit = 0
    n = 1

    #test each index in array
    for n in range(1, len(M)):
            binHandle(n, M, P, tempProfit, 0)
            if tempProfit > maxProf:
                    maxProf = tempProfit
            tempProfit = 0
    return maxProf

编辑:弄明白了

【问题讨论】:

  • 为什么要投反对票,这个问题写得很好,而且很努力?! ...

标签: python arrays algorithm dynamic-programming


【解决方案1】:

基本递归如下:你有你的候选集合。您决定是否选择第一家餐厅。如果你这样做,你必须摆脱离它太近的下一个候选者(距离

最后,你得到了最好的结果。现在,您的问题说明了动态编程......这是一个好主意,因为我们将使用它来改进以前的算法。我们不是从整个数组开始,而是从它的末尾开始并存储中间计算,这是它的工作原理:

INPUTS : M[0..n-1], P[0..n-1], M 按升序排列,P 使得 P[i] 是与位置 M[i] 相关的利润

  1. S[0..n-1] 是一个数值数组。我们为任何 i 设置S[i] = 0,除了 n-1,其中S[n-1] = P[n-1],然后我们将整数 i 设置为 n-1。让R[0..n-1] 成为一个列表数组。对于任何 i,R[i] = {},除了 n-1,R[n-1] = {n-1}
  2. 当我 >= 0
    1. 求 j 使得 j = min(q ∈ [|i+1, n-1|], M[q] - M[i] > k)。换句话说,我们找到满足距离标准的最小索引(在当前位置之后)。
      注意:要做到这一点,您可以在 M[i+1..n-1 上运行二进制搜索] 找到M[i] + k。只需“调整”搜索过程以返回严格优于的第一个匹配项而不是结果。
    2. S[i] = max(P[i] + S[q], S[i+1]) (如果q不存在,则考虑上式中的S[q] = 0)
    3. 取决于哪个是最佳解决方案,R[i] &lt;- {i} + R[q]R[i] &lt;- R[i+1]
  3. S[0] 现在是您可以获得的最佳利润。 R[0] 是提供此最佳结果的选定位置列表。

【讨论】:

  • 我们可以分解为加权调度问题吗?
  • 我认为S[q]应该是S[j]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 2012-10-25
  • 2022-01-13
  • 2012-11-12
相关资源
最近更新 更多