我在读CLRS的《算法导论》。在第二章中,作者提到了“循环不变量”。什么是循环不变量?


当前回答

循环不变量属性是一个条件,适用于循环执行的每一步。For循环,while循环,等等)

这对于循环不变证明是必不可少的,如果在执行的每一步都保持循环不变属性,则可以证明算法正确执行。

对于一个正确的算法,循环不变量必须保持在:

初始化(开始)

维护(之后的每一步)

终止(当它完成时)

这被用来计算很多东西,但最好的例子是加权图遍历的贪婪算法。对于贪心算法产生最优解(穿过图的路径),它必须达到连接所有节点在最小权值路径可能。

因此,循环不变的性质是所选择的路径具有最小的权值。在开始时,我们没有添加任何边,所以这个属性为真(在这种情况下,它不是假的)。在每一步中,我们都遵循最小权值边(贪婪步),所以我们再次采用最小权值路径。最后,我们找到了最小加权路径,所以我们的性质也是成立的。

如果一个算法不这样做,我们可以证明它不是最优的。

其他回答

不变的意思是永不改变

这里循环不变量的意思是“发生在循环中的变量的变化(增加或减少)并没有改变循环条件,即条件是满足的”,因此循环不变量的概念就产生了

简单地说,它是一个循环条件,在每次循环迭代中都为真:

for(int i=0; i<10; i++)
{ }

在这里,我们可以说i的状态是i<10并且i>=0

我喜欢这个非常简单的定义:

循环不变量是(程序变量之间的)一种条件,它必须在每次循环迭代之前和之后立即为真。(请注意,在迭代过程中,这并没有说明它的真伪。)

By itself, a loop invariant doesn't do much. However, given an appropriate invariant, it can be used to help prove the correctness of an algorithm. The simple example in CLRS probably has to do with sorting. For example, let your loop invariant be something like, at the start of the loop, the first i entries of this array are sorted. If you can prove that this is indeed a loop invariant (i.e. that it holds before and after every loop iteration), you can use this to prove the correctness of a sorting algorithm: at the termination of the loop, the loop invariant is still satisfied, and the counter i is the length of the array. Therefore, the first i entries are sorted means the entire array is sorted.

一个更简单的例子:循环不变量、正确性和程序推导。

我理解循环不变量的方式是作为一个系统的,正式的工具来推理程序。我们做了一个陈述,我们专注于证明它是正确的,我们称之为循环不变量。这组织了我们的逻辑。虽然我们也可以非正式地讨论一些算法的正确性,但使用循环不变量迫使我们非常仔细地思考,并确保我们的推理无懈可击。

《如何思考算法》的定义,Jeff Edmonds著

循环不变式是放置在循环和循环顶部的断言 每次计算返回到循环的顶部时,这必须成立。

在线性搜索(根据书中给出的练习)中,我们需要在给定的数组中找到值V。

它很简单,从0 <= k < length开始扫描数组并比较每个元素。如果找到V,或者扫描到数组的长度,就终止循环。

根据我对上述问题的理解-

循环不变量(初始化): 在k - 1迭代中找不到V。第一次迭代,这是-1因此我们可以说V不在-1位置

保养: 在下一次迭代中,V不在k-1中成立

Terminatation: 如果V位于k个位置,或者k达到数组的长度,则终止循环。