看似正确但不正确的算法和证明示例


15

在我的编程入门课程中,我们正在学习初始化-维护-终止方法,该方法证明算法可以达到预期的效果。但是我们只需要证明已知正确的算法是正确的即可。我们从未被要求证明算法不正确。

有没有看起来正确的经典算法示例,但不是吗?我正在寻找“初始化-维护-终止”方法捕获了第一眼直觉无法理解的情况的情况。


5
DW

5
赞成,因为我认为这是一个非常重要的教学问题。它稍微超出了cstheory的范围,但是我不知道它有一个更好的平台,并且cstheory社区中有很多算法讲师。大多数算法设计课程仅向学生介绍正确的现有算法以及使用已知技术可以轻松解决的问题。这增强了对学生的吸引力,使人们可以放心地相信一个看似合理的算法是正确的直观感觉。好的算法设计课程应该相反!
Neal Young

3
我希望有这样的收藏。
Chandra Chekuri

Answers:


20

二维局部最大值

输入:二维数组Añ×ñ一种

输出:局部最大值-一对,使得 A [ i j ]在数组中没有包含严格更大值的相邻像元。 一世Ĵ一种[一世Ĵ]

(相邻的单元格是数组中存在的中的单元格。)因此,例如,如果A一种[一世Ĵ+1个]一种[一世Ĵ-1个]一种[一世-1个Ĵ]一种[一世+1个Ĵ]一种

01个343231个2501个401个3

那么每个加粗的单元格都是局部最大值。每个非空数组都有至少一个局部最大值。

算法。有一个时间算法:只需检查每个单元格即可。这是一个更快,递归算法的想法。Øñ2

给定,将十字X定义为由中间列中的单元格和中间行中的单元格组成。首先检查X中的每个单元,以查看该单元是否为A中的局部最大值。如果是这样,则返回这样的单元格。否则,令i j X中具有最大值的像元。由于i j 不是局部最大值,因此它必须具有较大值的相邻像元i 'j '一种XX一种一世ĴX一世Ĵ一世Ĵ

分区(数组,减去在细胞中X)成四个象限-左上,右上,左下和右下象限-在自然的方式。值较大的相邻像元i 'j '必须在这些象限之一中。拨打该象限一个一种X一种X一世Ĵ一种

引理。 象限包含的本地最大的一个一种一种

证明。 考虑从单元格。如果不是局部最大值,请移至值较大的邻居。可以重复此过程,直到到达一个局部最大值的像元为止。最后一个单元格必须位于A ′中,因为A ′的所有侧面都由其值小于单元格i j 值的单元格限制。这证明了引理。一世Ĵ一种一种一世Ĵ

该算法在n处递归调用自身个子数组A'在此处找到局部最大值ij,然后返回该像元。ñ2×ñ2一种一世Ĵ

一个n × n矩阵的运行时间满足T n = T n / 2 + O n ,因此T n = O n Ťññ×ñŤñ=Ťñ/2+ØñŤñ=Øñ

因此,我们证明了以下定理:

定理。 有一种时间算法可以在n × n数组中找到局部最大值。Øññ×ñ

还是我们?


初读时,我发现的唯一错误是重复解决方案。那是唯一的错误吗?
Radu GRIGore

1
复发是正确的。该算法不是!
Neal Young,

1
啊,是的,我的重复犯了一个愚蠢的错误。我看到了问题:您证明存在的最大值不是(有必要)找到的最大值。而且你发现了什么忽略X.
拉杜格里戈里

3
21个433001个01个230001个023002222222333233300323000032300

2
一种一种
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.