我们如何定义循环不变量?

时间:2016-11-10 03:51:11

标签: algorithm loop-invariant

我们知道循环变量被定义为在循环的每次迭代之前和之后都为真的语句。但这个定义是否过于宽松?让我们看一个具体的例子:线性搜索。

输入:n个数字序列A =(a 1 2 3 ,...,a n )和值v

输出:索引i,如果在A中找不到v,则v = A [i]或NIL

这是我的伪代码:

linear_search(A, v)
1 for i ∈ {1, 2, ..., n}
2     if A[i] = v
3         return i
4 return NIL

因此,典型的循环不变量(因为我们从左到右搜索)v不在当前索引的左侧,或者在数学上,P: ∀p ∈ {1, 2, ..., i - 1}, A[p] ≠ v.这显然是正确的,即使在开始时也是如此因为p∈Ø是假的,这使得P为真,记住每个普遍量化的陈述都可以被认为是条件陈述。 (但是非正式地思考它更容易:在开始时,v的左侧没有任何内容。)

我们还可以使用限制较少的条件语句。在这种情况下,Q: If A[i] = v, then 1 ≤ i ≤ n.显然,如果找到v,则为真。如果未找到v,则无论i的值如何,A [i] = v为假,Q变为真。如果我们将算法从右向左更改为搜索,则Q也是如此。

也许我们希望减少限制。使用始终如一的陈述怎么样? R: Either A[i] = v or A[i] ≠ v. R在循环的每次迭代之前和之后保持。

哪个语句P,Q和R有效用作循环不变量?

1 个答案:

答案 0 :(得分:0)

你想要一个的循环不变?也许你想证明你的算法是正确的,即:

linear_search(A,v) = i ⇒ A[i] = v

linear_search(A,v) = NIL ⇒ v ∉ A

第一个很容易。为了证明第二个,你可以使用你的循环不变P.因为如果函数返回NIL,i = n是真的,你有

linear_search(A,v) = NIL
⇒ ∀p ∈ {1, 2, ..., n}, A[p] ≠ v
⇒ v ∉ A

您的候选人P对此目的很有用,而其他人则不然。

此外,你不能只选择一个循环不变量 - 你必须证明它是为了证明你的算法是正确的。循环的迭代性质可以通过归纳证明,而像候选P这样的不变量很容易证明这一点。