本文属于《程序员的数学》读书笔记系列。作者从送1到100之前求和为例介绍数学归纳法。
一 高斯求和
我印象中是在小学,数学老师提问的同样的问题。1+2+3+。。。+100=?
我觉得简单粗暴的就是直接算,好像还是学珠算的练手的一个例子。但是高斯是这么想的,
1+2+3+...+100的计算结果和100+99+98+...+1的计算结果是一样的,那么就可以将这两串数字进行纵向相加,如下:
如此一来,变成了100个101相加,就简单多了。10100,不过是要求的数的2倍,结果还得除以2,是5050.
归纳
高斯使用了以下等式
如果用变量n来将“1到100”归纳为“1到n”,这样上面的等式变为如下形式
1+2+3+...+n=
那么这个等式对于0以上的任意整数n都成立吗?如果成立该如何证明呢?这时就需要用到数学归纳法了。
二 数学归纳法
断言G(n):0到n的整数之和为
数学归纳法是证明有关整数的断言对于0以上的所有整数是否成立时所用的方法。
假设现在要用数学归纳法来证明“断言P(n)对于0以上的所有整数n都成立”,则证明步骤如下:
● 步骤1
证明“P(0)成立”;
● 步骤2
证明n不论为0以上的哪个整数,“若P(n)成立,则P(n+1)也成立”。
在上面的证明步骤中,我们将步骤1称为基底,步骤2称为归纳。如果步骤1和步骤2都能得到证明,就证明了“断言P(n)对于0以上的所有整数n都成立”。
首先证明在某个起点值时命题成立,然后证明从一个值到下一个值的过程有效。当这两点都已经证明,那么任意值都可以通过反复使用这个方法推导出来。把这个方法想成多米诺效应也许更容易理解一些。例如:你有一列很长的直立着的多米诺骨牌,如果你可以:
-
证明第一张骨牌会倒。
-
证明只要任意一张骨牌倒了,那么与其相邻的下一张骨牌也会倒。
2.1用数学归纳法证明高斯断言
● 步骤1:证明基底成立
证明G(0)成立。
G(0)就是“0到0的整数之和与0*(0+1)/2”相等;
可以直接通过计算证明,0到0的整数之和为0,0*(0+1)/2的结果也是0;
步骤1证明完毕。
● 步骤2:归纳的证明
证明n为0以上的任一整数时,“若G(k)成立,则G(k+1)也成立”。
先假设G(k)成立,这时,以下等式成立:
下面来证明,G(K+1) 时成立。
现在进行如下计算,左边
G(k+1) =
G(k+1)左边和右边的计算结果相同
由此,G(k)到G(k+1)的推导成功,步骤2得到了证明。
至此,通过数学归纳法的步骤1、步骤2都证明了G(n),也就是说通过数学归纳法证明了断言G(n)对于0以上的任意整数n都成立。
练习:求出奇数的和
1+3+5+7+。。。+(2n-1) =
注意作者还介绍了反面的例子,黑白棋的问题。
三 编程和数学归纳法
递归是首先想到的。比如求和方法sum
比如方法:
int sum(int n) {...} 就是计算加到n的和,我们当然可以把高斯公式带入,但是试着把数学归纳法的语言翻译为程序?
第一步:证明n=1是成立的:
if (n == 1) { return 1 };
第二步:
①假设对于n-1成立
sum(n-1) 返回加到n-1的和
②把假设的结论带进去
return sum(n-1) + n;
循环不变式
就是常见的for循环。 循环不变式(loop invariant)属于计算机科学的概念,它是指某段程序循环在循环前后该段程序的某种性质(通常指程序的正确性)保持不变。其分为三步:
(1)初始化(循环第一次迭代之前)的时候,A[1‥ j -1]的“有序性”是成立的;
(2)在循环的每次迭代过程中,A[1 ‥j -1]的“有序性”仍然保持;
(3)循环结束的时候,A[1 ‥ j-1]的“有序性”仍然成立。
看这个有些抽象,看书上的例子会好很多。
这里开始跟编程实际有关联了。