理解循环不变量。找到并证明它们的算法

时间:2015-09-15 21:03:34

标签: loops

我需要一些帮助来理解循环不变量。我只需要有人解释如何找到循环不变量并证明它适用于以下算法:

public int sumSquares ( int n )
{
    int sum = 0 ;
    for ( int i = 1 ; i <= n ; i++)
    {
        sum += i ∗ i ;
    }
    return sum ;
}

3 个答案:

答案 0 :(得分:3)

循环不变量是一个在循环的每次迭代之前和之后立即可证明为真的语句。事实证明,有很多这些,但诀窍是证明一个实际上有帮助。

例如,

确实如此
  

i的值在每次迭代之前和之后始终等于i

不是非常有用。相反,想想你要证明什么

  

i等于n时,sum等于前n个方格的总和

在这种情况下,如果要证明算法产生前n个方格的总和,则需要声明以下不变量。对于每个i

  

sum的值等于第一个i正方形

的总和

答案 1 :(得分:1)

您还可以注意到与数学归纳的相似性。

当您证明财产成立时,您将证明基本情况和归纳步骤。

如果在第一次迭代之前保持不变,则它与基本情况类似。显示从迭代到迭代的不变循环类似于归纳步骤。

答案 2 :(得分:1)

正如其他人所说,在每次迭代之前和之后,不变量都是正确的。一般来说,它在循环内部的某处变得无效,稍后会被恢复。

要建立证明,您可以跟踪各个陈述之间的条件,并将它们与不变量相关联。

对于给定的示例,请按照注释;为清楚起见,for语句被重写为while

    int sum = 0 ;
    i= 1;
    // This trivially establishes the invariant: sum == 0 == Σ k² for 0<=k<i=1
    while (i <= n)
    {
        // The invariant is still true here (nothing changed)
        sum += i ∗ i ;
        // We now have sum == Σ k² for 0<=k<=i (notice the <=; this differs from the invariant)
        i++;
        // As i has been increased, sum == Σ k² for 0<=k<i is restored
    }
    // Here the invariant holds, as well as i == n+1
    // Hence sum == Σ k² for 0<=k<n+1
    return sum ;

一般来说,不变量表示我们已经解决了问题的一部分。在给定的示例中,它表示已计算了部分和。最初,部分解决方案是微不足道的(并且无用)。随着迭代的进展,部分解决方案越来越接近完整的解决方案。