您如何证明算法有效?

时间:2018-07-17 21:01:10

标签: algorithm

TL; DR:如何证明算法可以对每个n值起作用?

概述:

我是一位自学成才的程序员,具有数学背景,直到线性代数。最近,我需要编写一种算法来解决n = 100的问题,从而证明关系是递归的。

当我找到解决方案时,我到达那里的方式被认为是不可接受的。与我交谈的人说,我的算法是“统计”算法,而不是实际证明存在递归关系并证明我的算法可以工作。

我一直在解决网站上的一些问题,例如代码信号,hackerrank等,但这是我第一次遇到这种将解决方案归纳为正式证明的概念。

问题: 我如何证明一种算法对n的每个值都适用?

示例: 让我们以二进制搜索为例,而忘记我遇到的实际问题。

如果您有一个由100个整数组成的数组,并按升序排序,那么如何证明您的二进制搜索算法适用于任何数组和任何n个数组?

在下面的示例中,假设我们的数组为

arr = list(range(100))

我建议的问题是:

  

编写一个递归算法,如果数组中的值为'42',则返回True,否则返回False。

您如何证明(如形式上的证明)该算法有效?请注意在算法从启发式解决方案转变为证明算法的那一刻背后的思维过程和直觉?

2 个答案:

答案 0 :(得分:4)

42不被丢弃

如果对数组A进行了排序,那么我们可以显示A[x] > 42,然后显示A[x + 1] > 42。这是因为,如果对数组进行排序,则每个元素都大于或等于其前任元素(即A[x + 1] > A[x] > 42)。我们知道这一点是因为>运算符是可传递的。

相反,<运算符也是如此。

二元搜索应在每个步骤中,通过对单个可能性进行采样并确定所有在一侧的输入也都在其中,拒绝所有大于或小于所需输入的输入。需要拒绝(如上所述)。

(编辑:如果x > 42x < 42为true,则x = 42必须为false。)

数组变小

在每个步骤中,至少删除数组的一个元素,除非它等于42。这是因为,如果该元素不是42,则将删除该元素(也许连同其他一些元素)。

如果数组越来越小(假设没有在42点采样),并且从不删除42,那么在某个时候,要么采样42,要么数组为空

结论

如果数组为空,并且由于没有丢弃42,则永远不会有42。

如果我们对42进行采样,则因为没有新的元素引入数组,所以42就是从那里开始的。

证明!

其他评论

要证明递归算法有效,您要证明它

  1. 结束
  2. 产生正确的结果。

它结束是因为在每个递归步骤中,数组都变小了(但不能低于[])。产生正确的结果是因为从未删除或添加过42,所以最后,如果我们找不到42,那是因为它从未出现过。在我看来,您的论点不应依赖任何具体示例,除非是基本情况,否则可能是统计上的。您需要从数学意义上“证明”它。

答案 1 :(得分:1)

对于简单的正确性证明:您需要证明您的算法可以成功完成其设计目的。

因此,以关于输入案例数据的陈述为前提。并计算出它应该暗示输出中需要的后期条件。这证明算法是正确的。

P:关于给定输入的声明

Q:所需输出的声明。

证明P表示Q。

照顾角落的情况。 确保在所有情况下都终止算法。 如果它是递归算法,则必须严格证明该算法终止/退出。

  

编写一个递归算法,如果值'42'为   在数组中,否则为False。

对于此类问题,您还可以使用矛盾证明。首先尝试假设如果不存在42,该算法将得出true ,或者如果存在42,该算法将返回false 。然后,通过算法流程证明您的假设合理,并尝试证明这是不可能的,这是一个矛盾。