确实是while循环的后置条件(为什么您认为“显然”不是这种情况?)。while循环不包含a的情况总是如此:退出循环时,只能是因为循环条件(此处 u + 1 ≠ v)为假。当循环在这里退出时,并不是唯一的事情(如您在类中所见,该算法实际上计算出一些有趣的东西,因此 u = [这个有趣的事情]和 v = [这个有趣的事情]也是后置条件),但这是最明显的。u + 1 = vbreak
u + 1 ≠ vu = [这个有趣的东西]v = [这个有趣的东西]
现在,要找到其他有趣的属性,没有通用的配方。实际上,从某种形式上讲,没有通用的公式可以找到循环不变式。您能做的最好的事情就是应用一些仅在某些情况下有效的技术,或者通常是去钓鱼以获得有趣的观察结果(随着经验的积累,这种方法会越来越好)。
如果循环运行一些具有值的迭代,则每次迭代都会看到:ñ
- 要么跳起来(û + v )/ 2 ;ü(u + v )/ 2
- 或跳至(u + v )/ 2。v(u + v )/ 2
特别地,小于v,并且永远不会超过v。此外,ü开始正和增大,而v开始于Ñ + 1和减小。所以,0 ≤ ü ≤ v ≤ ñ + 1是整个计划不变。üvüvn + 10 ≤ ü ≤ v ≤ Ñ + 1
不太明显的一件事是是否等于v。这很重要:如果u和v变得相等,我们将得到x = u = v,循环将永远继续下去。因此,为了证明算法正确(即不会永远循环),需要证明u和v永远不会相等。一旦确定了这种需求,就很容易证明(我将其保留为练习)u < v是循环不变式(请记住,u和v是整数,因此等效于uüvüvx = u = vüvü < vüv)。ü + 1 ≤ v
由于在节目的结束,则分别获得了后置条件也可以被写ü 2 ≤ Ñ < v 2(部分0 ≤ Ü 2是微不足道的)。我们想要一个涉及n的后置条件的原因是,我们希望将程序的结果与输入n绑定在一起。为什么要这样精确的条件?我们正在寻找尽可能精确的东西,并查看n在循环中出现的位置:v = u + 1ü2≤ Ñ < v20 ≤ ü2ñññ
- 我们有 ;ü ≤ X ≤ v
- X2≤ ñüXü2≤ñv不变);
- X2> nvXn < v2ü不变)。
ü2≤ Ñ < v2所有的时间。换句话说,我们怀疑这是一个循环不变式。验证这是读者的一项练习(请记住,一开始要检查该属性是否正确)。
ü2≤ ñ(u + 1 )2> nüñ