循环不变性(loop invariant)-证明算法的正确性的一种方法
2014-03-02 04:21
309 查看
循环不变性是在算法中循环的前后都保持不变的一种属性。
利用循环不变性证明算法正确应该满足3个条件:(算法导论中提到的)
初始条件: 首次循环前不变性成立
保持条件: 一次循环前不变性如果成立,则下次循环开始前不变性成立
终止条件: 循环结束后,循环不变性应能表明程序的正确性
例1(正确的程序)
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 1 A[0] 为非降值排序的 成立
保持条件: 已知A[0]到A[j-1]是非降值排序的,第j次循环,会把A[j]排到适当的位置使执行完j=j+1语句后A[0]到A[j-1]仍然是非降值排序的
终止条件: 循环结束后,j = len(A), 则A[0]到A[len(A)-1]都是非降值排序的,这就表明了非降值插入排序算法正确
例2(初始条件错误的程序)
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 2 A[0] 到A[1]不一定为非降序排列的, 算法不正确
例3(终止条件错误的程序)
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 1 A[0] 为非降值排序的, 成立
保持条件: 已知A[0]到A[j-1]是非降值排序的,第j次循环,会把A[j]排到适当的位置使执行完j=j+1语句后A[0]到A[j-1]仍然是非降值排序的
终止条件: 循环结束后,j = len(A) -1 , 则A[0]到A[len(A)-2]都是非降值排序的,但不能证明A[0]到A[len(A)-1]都是非降值排序的,算法不正确
既然是不变的特性,如果方便的话,就可以用程序来判断其正确性了,加入断言可以达到这个效果,下面这个例子未必恰当,只是展示如何用断言判断不变性:
利用循环不变性证明算法正确应该满足3个条件:(算法导论中提到的)
初始条件: 首次循环前不变性成立
保持条件: 一次循环前不变性如果成立,则下次循环开始前不变性成立
终止条件: 循环结束后,循环不变性应能表明程序的正确性
例1(正确的程序)
def INSERTION_SORT(A): j = 1 while j < len(A): key = A[j] i = j - 1 while i >= 0 and key < A[i]: A[i+1] = A[i] i = i -1 A[i+1] = key j = j + 1
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 1 A[0] 为非降值排序的 成立
保持条件: 已知A[0]到A[j-1]是非降值排序的,第j次循环,会把A[j]排到适当的位置使执行完j=j+1语句后A[0]到A[j-1]仍然是非降值排序的
终止条件: 循环结束后,j = len(A), 则A[0]到A[len(A)-1]都是非降值排序的,这就表明了非降值插入排序算法正确
例2(初始条件错误的程序)
def INSERTION_SORT(A): j = 2 while j < len(A): key = A[j] i = j - 1 while i >= 0 and key < A[i]: A[i+1] = A[i] i = i -1 A[i+1] = key j = j + 1
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 2 A[0] 到A[1]不一定为非降序排列的, 算法不正确
例3(终止条件错误的程序)
def INSERTION_SORT(A): j = 1 while j < len(A) - 1: key = A[j] i = j - 1 while i >= 0 and key < A[i]: A[i+1] = A[i] i = i -1 A[i+1] = key j = j + 1
要证明: 非降值插入排序算法正确
循环不变性:A[0]到A[j-1]是非降值排序的
初始条件: j = 1 A[0] 为非降值排序的, 成立
保持条件: 已知A[0]到A[j-1]是非降值排序的,第j次循环,会把A[j]排到适当的位置使执行完j=j+1语句后A[0]到A[j-1]仍然是非降值排序的
终止条件: 循环结束后,j = len(A) -1 , 则A[0]到A[len(A)-2]都是非降值排序的,但不能证明A[0]到A[len(A)-1]都是非降值排序的,算法不正确
既然是不变的特性,如果方便的话,就可以用程序来判断其正确性了,加入断言可以达到这个效果,下面这个例子未必恰当,只是展示如何用断言判断不变性:
#!python #Insertion sort def is_sorted(A, j): if j == 0: return True for i in range(1, j): if A[i] < A[i-1]: print "error: A[%d] < A[%d]" % (i, i-1) return False return True def INSERTION_SORT(A): j = 1 assert is_sorted(A, j) while j < len(A): assert is_sorted(A, j) key = A[j] i = j - 1 while i >= 0 and key < A[i]: A[i+1] = A[i] i = i -1 A[i+1] = key j = j + 1 assert is_sorted(A, j) assert j== len(A) a = [5, 2, 4, 6, 1, 3] if __name__ == "__main__": print "the length of list a is:", len(a) print "list a have:", a INSERTION_SORT(a) print "After insert-sort, a is:", a
相关文章推荐
- oracle 跳出loop循环方法
- MySQL 循环方法 while loop repeat 详解
- C++11新特性:range based for loop-范围for循环基本使用方法
- FIFO 非阻塞写+非阻塞读+延时循环读的一种方法
- java中如何跳出多重循环,方法不止break一种
- 一种Furture模式处理请求中循环独立的任务的方法
- 由July师兄二分查找代码及编程珠玑有感:循环不变性(断言)证明程序的正确性及发现bug
- c++循环包含一种解决方法
- 使用less的loop(循环)方法根据类名生成元素
- 数组循环左移的一种方法
- Velocity 循环指令一种好的解决方法
- 加快LOOP嵌套循环的一个方法
- [Java学习笔记] 猜猜看(2) ~ 中断循环语句的一种方法(能够中断所有进行中的循环)
- swiper在vue项目中loop循环轮播失效的解决方法
- for循环的一种加速方法
- 定义一个循环的 loop 宏方法
- python类中显示重写__del__方法引起循环引用的对象无法释放,一种循环引用的检测方法
- for循环的一种加速方法
- 在点阵液晶显示中,一种菜单循环的方法
- FIFO 非阻塞写+非阻塞读+延时循环读的一种方法