2013-07-19 10:29:14
最近看《编程珠玑》、《算法导论》,其中有一个术语“循环不变式”,多次看到,一致不是很理解,查了一些资料,还不是很懂,下面是收集到的的一些靠谱的资料。
下面转自:http://www.cnblogs.com/bamboo-talking/archive/2011/02/05/1950197.html
We use loop invariants to help us understand why an algorithm is correct. We must show three things about a loop invariant:
· Initialization: It is true prior to the first iteration of the loop.
· Maintenance: If it is true before an iteration of the loop, it remains true before the next iteration.
· Termination: When the loop terminates, the invariant gives us a useful property that helps show that the algorithm is correct.
循环不变式(loop invariant)与数学归纳法(induction)进行对比:
When the first two properties hold, the loop invariant is true prior to every iteration of the loop. Note the similarity to mathematical induction, where to prove that a property holds, you prove a base case and an inductive step. Here, showing that the invariant holds before the first iteration is like the base case, and showing that the invariant holds from iteration to iteration is like the inductive step.
The third property is perhaps the most important one, since we are using the loop invariant to show correctness. It also differs from the usual use of mathematical induction, in which the inductive step is used infinitely; here, we stop the "induction" when the loop terminates.
利用循环不变式(loop invariant)来证明循环的正确性与用数学归纳法(induction)证明数学等式的相同点在于:需要验证初值,或初始状态是否满足条件。之后再证明在归纳或递推的过程中仍然满足这种条件。(这个条件在数学归纳中叫做递推关系,在循环中就是循环不变式(loop invariant))。
循环不变式(loop invariant)与数学归纳法(induction)的区别在于:数学归纳可能是无限的,是无限地腿的,但循环不变式所要证明的循环是要结束并给出正确结果的。
在插入排序的例子中:
INSERTION-SORT(A)
1 for j ← 2 to length[A]
2 do key ← A[j]
3 ▹ Insert A[j] into the sorted sequence A[1 ‥ j - 1].
4 i ← j - 1
5 while i > 0 and A[i] > key
6 do A[i + 1] ← A[i]
7 i ← i - 1
8 A[i + 1] ← key
· Initialization: We start by showing that the loop invariant holds before the first loop iteration, when j = 2.[1] The subarray A[1 ‥ j - 1], therefore, consists of just the single element A[1], which is in fact the original element in A[1]. Moreover, this subarray is sorted (trivially, of course), which shows that the loop invariant holds prior to the first iteration of the loop.
Maintenance: Next, we tackle the second property: showing that each iteration maintains the loop invariant. Informally, the body of the outerfor loop works by moving A[ j - 1], A[ j - 2], A[ j - 3], and so on by one position to the right until the proper position for A[ j] is found (lines 4-7), at which point the value of A[j] is inserted (line 8). A more formal treatment of the second property would require us to state and show a loop invariant for the "inner" while loop. At this point, however, we prefer not to get bogged down in such formalism, and so we rely on our informal analysis to show that the second property holds for the outer loop.
Termination: Finally, we examine what happens when the loop terminates. For insertion sort, the outer for loop ends when j exceeds n, i.e., when j = n + 1. Substituting n + 1 for j in the wording of loop invariant, we have that the subarray A[1 ‥ n] consists of the elements originally in A[1 ‥ n], but in sorted order. But the subarray A[1 ‥ n] is the entire array! Hence, the entire array is sorted, which means that the algorithm is correct
在这个例子中,“At the start of each iteration of the for loop of lines 1-8, the subarray A[1 ‥ j - 1] consists of the elements originally in A[1 ‥ j - 1] but in sorted order.”,也就是,每当算法进行到第一行时,数组A中从第1个至第j-1个元素仍然是算法执行前数组中第1个至第j-1个元素,只是执行算法后,这些元素是排好序的,以上就是这个算法的for循环的循环不变式。(就是一个条件。)
再循环的Initialization阶段,j的初值为2,数组A[1 .. j-1]即是A[1],是排好序的,而且其元素仍然是原数组A[1]的,只是现在排好序了。
Maintenance:这个阶段要证明的是每一次循环的结果都满足先前提到的的循环不变式。
Termination:这个阶段要证明,当循环结束时,数组A中的所有元素都排好序。
再看算法第一行,当j=length[A]+1时循环结束,由于满足循环不变式,所以,数组A[1 .. length[A]]是排好序的,且是原数组的那些元素。
至此,可以说明算法正确。
再来说一下如何找循环不变式。由于算法是一步步执行的,那么如果每一步(包括初试和结束)都满足一个共同的条件,那么这个条件就是要找的循环不变式(loop invariant)。再说上面的例子,要得到的结果是排序且元素不改变的数组,所以循环不变式就是数组A中从第1个至第j-1个元素是排好序的且是与原数组的元素是一致的。
百度知道的回答:http://zhidao.baidu.com/question/558630518.html
问题描述:算法导论中的 循环不变式怎么理解
书本上举了一个插入排序的例子
我想知道 循环不变式 是指代码中的 特定部分的代码段 还是说只是一个思想
我没看懂 请懂的朋友指点迷津 请勿抄袭 粘贴 其他贴吧的
谢谢合作
就是个思想,说明正确算法的循环过程中总是存在一个维持不变的特性,这个特性一直保持到循环结束乃至算法结束,这样就可以保证算法的正确了。
比方说插入排序,算法每次循环后,前n个数一定是排好序的(n为已经循环的次数)。由于这个特性一直成立,到算法结束时,所有N个数一定是排好序的。
关于这个思想,不要小看了,很多算法的正确性都是这么保证的。
这个思想 不是证明排序算法的正确性 不是分三个部分 我们去证明的过程 应把握那些着重点 证明那些特性 才能保证正确性 在直接点就是 课后题有关于
交换排序的正确性证明 怎么去证明他也是正确的算法
要寻找循环不变的特性,一般都是循环结束时数据具有的特性。如何寻找循环不变量,没有一般方法,不过这是证明算法正确性的最正规的方法。
比如冒泡排序,算法中存在两次循环:外层循环可以保证第n次循环后第n位的数比上面所有数都大;内部循环可以保证第n次循环后第n+1位都是上面n+1位中最大的。
内部循环可以保证每次外层循环的正确性;
外部循环可以保证最后是排好序的。