在我的编程入门课程中,我们正在学习初始化-维护-终止方法,该方法证明算法可以达到预期的效果。但是我们只需要证明已知正确的算法是正确的即可。我们从未被要求证明算法不正确。
有没有看起来正确的经典算法示例,但不是吗?我正在寻找“初始化-维护-终止”方法捕获了第一眼直觉无法理解的情况的情况。
在我的编程入门课程中,我们正在学习初始化-维护-终止方法,该方法证明算法可以达到预期的效果。但是我们只需要证明已知正确的算法是正确的即可。我们从未被要求证明算法不正确。
有没有看起来正确的经典算法示例,但不是吗?我正在寻找“初始化-维护-终止”方法捕获了第一眼直觉无法理解的情况的情况。
Answers:
二维局部最大值
输入:二维数组A
输出:局部最大值-一对,使得 A [ i ,j ]在数组中没有包含严格更大值的相邻像元。
(相邻的单元格是数组中存在的中的单元格。)因此,例如,如果A为
那么每个加粗的单元格都是局部最大值。每个非空数组都有至少一个局部最大值。
算法。有一个时间算法:只需检查每个单元格即可。这是一个更快,递归算法的想法。
给定,将十字X定义为由中间列中的单元格和中间行中的单元格组成。首先检查X中的每个单元,以查看该单元是否为A中的局部最大值。如果是这样,则返回这样的单元格。否则,令(i ,j )为X中具有最大值的像元。由于(i ,j )不是局部最大值,因此它必须具有较大值的相邻像元(i ',j ')。
分区(数组甲,减去在细胞中X)成四个象限-左上,右上,左下和右下象限-在自然的方式。值较大的相邻像元(i ',j ')必须在这些象限之一中。拨打该象限一个“。
引理。 象限包含的本地最大的一个。
证明。 考虑从单元格。如果不是局部最大值,请移至值较大的邻居。可以重复此过程,直到到达一个局部最大值的像元为止。最后一个单元格必须位于A ′中,因为A ′的所有侧面都由其值小于单元格(i ′,j ′)值的单元格限制。这证明了引理。⋄
该算法在n处递归调用自身个子数组A'在此处找到局部最大值(i,j),然后返回该像元。
一个n × n矩阵的运行时间满足T (n )= T (n / 2 )+ O (n ),因此T (n )= O (n )。
因此,我们证明了以下定理:
定理。 有一种时间算法可以在n × n数组中找到局部最大值。
还是我们?