循环不变式
循环不变式主要用来帮助理解算法的正确性。对于循环不变式,必须证明它的三个性质:
- 初始化:在循环开始第一轮迭代时,循环不变式为真。
- 保持:如果在某次循环开始迭代之前循环不变式为真,那么在下一次迭代之前,循环不变式也为真
- 终止:当头两个性质满足时,就能保证循环在每一次开始之前,不变式都为真。因此我们可以利用这个性质来验证我们算法的正确性。
其实循环不变式就类似与数学归纳法。证明初始化性质满足就类似于归纳法中对基本情况的证明,对于保持性质的证明,就好像归纳法中归纳步骤的证明,只不过数学归纳法中归纳步骤是无穷的的,而我们的算法是需要适时终止归纳,否则没有意义。
举个栗子
斐波那契数列
int fib(x) {
// 循环不变式为a==fib(i)&&b==fib(i+1)
int a = 0, b = 1, tmp;
// 初始化:迭代开始之前a==0==fib(0)&&b==1==fib(1),循环不变式为真。
for (int i = 0; i < x; i++){
// 假设某次迭代开始之前a==fib(i)&&b==fib(i+1)为真
tmp = a;
// a变为fib(i+1)
a = b;
// b变为fib(i+1)+fib(i)=fib(i+2)
b = tmp + b;
// 保持:循环结束时,即下次迭代开始时即i变为i+1,a==fib(i+1)&&b==fib(i+2),因此循环不变式依然为真
}
// 终止:由与初始化和保持都满足,因此终止时不变式依然为真,此时i==x,即a==fib(x),结果正确因此算法正确。
return a;
}