用归纳法证明线性最大子阵算法

时间:2014-10-12 21:24:32

标签: algorithm ocaml proof

我在这里实施了我写过OCaml的Kadane algorihm:

let rec helper max_now max_so_far f n index = 
  if n < index then max_so_far
  else if max_now + f index < 0 
  then helper 0 max_so_far f n (index+1)
  else helper (max_now + (f index)) 
      (max max_so_far (max_now + (f index))) f n (index+1)

let max_sum f n = helper 0 0 f n 1

现在我想正式证明它是正确的。我的代码规范:

参数1到n的函数f返回一个整数。 具有参数f n的函数max_sum应该返回最大的总和 总和:

sum

其中1&lt; = a&lt; = b&lt; = n。

您不需要分析我的代码 - 我只是想证明Kadane的算法使用归纳法。问题是我不知道如何处理这个问题 - 证明简单的程序,如因子或因子是非常简单的,但是当涉及到更抽象的事情,比如找到最大数量的子阵列我甚至不知道在哪里开始。任何提示?

2 个答案:

答案 0 :(得分:3)

归纳的基础不会通过,因为算法和规范不同意是否允许空子阵列(具有和0)。我将遵循规范,不允许空子阵列。

归纳步骤如下。对于所有k,请定义

max_now  = max_{a in 1..k  } sum_{i in a..k  } f(i)
max_now' = max_{a in 1..k+1} sum_{i in a..k+1} f(i)
max_so_far  = max_{b in 1..k  } max_{a in 1..b} sum_{i in a..b} f(i)
max_so_far' = max_{b in 1..k+1} max_{a in 1..b} sum_{i in a..b} f(i).

我们需要展示

max_now' = max(max_now, 0) + f(k+1)
max_so_far' = max(max_so_far, max_now').

通过拆分max来证明两种等式。

max_now' =      max_{a in 1..k+1} sum_{i in a  ..k+1} f(i)
         = max( max_{a in 1..k  } sum_{i in a  ..k+1} f(i),
                                  sum_{i in k+1..k+1} f(i))
         = max((max_{a in 1..k  } sum_{i in a  ..k  } f(i)) + f(k+1),
                                                              f(k+1))
         = max(max_now, 0) + f(k+1)

max_so_far' =     max_{b in 1..k+1} max_{a in 1..b  } sum_{i in a..b  } f(i)
            = max(max_{b in 1..k  } max_{a in 1..b  } sum_{i in a..b  } f(i),
                                    max_{a in 1..k+1} sum_{i in a..k+1} f(i))
            = max(max_so_far, max_now')

答案 1 :(得分:0)

让maxSum [i]是在索引i处结束的最大连续数组和。
我想证明一下kadane算法的这一说法-
maxSum[i] = max(maxSum[i-1] + a[i], a[i])

if a[i] > maxSum[i-1] + a[i]

on considering a[i+1], 
a[i] + a[i+1] > maxSum[i-1] + a[i] + a[i+1]

所以最好打破连续性并从第ith个索引开始新的子数组