简体   繁体   English

如何证明算法的正确性?

[英]How can I prove algorithm correctness?

I have a problem with this exercise in Java, I don't understand how to prove this sum method in Java我在 Java 中的这个练习有问题,我不明白如何在 Java 中证明这个 sum 方法

This is what I made :这是我做的:

P(0) : If r=0 and i=0 => r=0+a[0]

p(i+1) : r'= r + a[i] and i'=i+1
       r'=r + a[i] + a[i+1]


public static int sum(int[] a) {
    int r = 0;
    int i = 0;
    while (i < a.length) {
        r = r + a[i];
        i = i + 1;
    }

    return r;
} 

The loop invariant should express that r equals the sum of the elements of a from index 0 to index i , excluded.循环不变量应该表示r等于a从索引0到索引i的元素之和,不包括在内。 Ie r = Sum(k<i: a[k]) .r = Sum(k<i: a[k])

Then we can annotate然后我们可以注释

int r = 0;
int i = 0;
/* r = Sum(k<i: a[k]) */
while (i < a.length) {
    r = r + a[i];
    /* r = Sum(k<i: a[k]) + a[i] = Sum(k<i+1: a[k]) */
    i = i + 1;
    /* r = Sum(k<i: a[k]) */
}
/* r = Sum(k<=a.length: a[k]) */

The crux of the proof is证明的关键是

Sum(k<i: a[k]) + a[i] = Sum(k<i+1: a[k])

expressing that the sum is obtained incrementally.表示总和是递增获得的。

The easiest method is to define a set of inputs along with their expected outputs.最简单的方法是定义一组输入及其预期输出。 If this is for an exercise, you may be given these values, or you may need to calculate a handful of them by hand.如果这是用于练习,您可能会获得这些值,或者您可能需要手动计算其中的一些值。 Then I would write unit tests using those known inputs to see if each output matches the expected value.然后我将使用这些已知输入编写单元测试,以查看每个输出是否与预期值匹配。 If you find places where they don't match, double check both your algorithm and the expected values.如果您发现它们不匹配的地方,请仔细检查您的算法预期值。 Work through the steps of each side-by-side and figure out which one is wrong (or if both are wrong).并排完成每个步骤并找出哪个是错误的(或者两者是否都错误)。

Another option is to write the same algorithm in another language;另一种选择是用另一种语言编写相同的算法; ideally, one where you can't copy-paste the algorithm's implementation to prevent sharing common bugs.理想情况下,您不能复制粘贴算法的实现以防止共享常见错误。 Then run both with a ton of inputs.然后使用大量输入运行两者。 If both implementations have matching results for every input, you can have a higher confidence that both are correct.如果两个实现对每个输入都有匹配的结果,您就可以更有把握地认为两者都是正确的。

A third option is to find a set of invariants, ie things that are provably true at various stages of the algorithm.第三种选择是找到一组不变量,即在算法的各个阶段可证明为真的事物。 Then write tests (or just throw in assert statements) at all of those points that show that the invariants hold.然后在所有那些表明不变量成立的点上编写测试(或只是抛出assert语句)。 Things like for every iteration of the "i" loop, r' >= r . for every iteration of the "i" loop, r' >= r之类for every iteration of the "i" loop, r' >= r事情。 Then run it against a large range of inputs, and if any of those assertions fail, you can start digging in and figuring out what edge case you forgot to handle in your algorithm (eg What if the input is empty? How do I handle negative numbers? etc.)然后针对大范围的输入运行它,如果这些断言中的任何一个失败,您可以开始深入研究并找出您忘记在算法中处理的边缘情况(例如,如果输入为空怎么办?我如何处理否定数字?等)

One of the possibilities that prove that your algorithm has an expected response is to cover it with unit tests.证明您的算法具有预期响应的可能性之一是用单元测试覆盖它。

@Test
public void sumWorksFineWithNaturalValues() {

    int[] input = {1, 2, 3, 4};
    int expectedResponse = 10;

    assertThat(sum(input)).isEqualTo(expectedResponse);
}

@Test
public void sumCanHandleNegativeValues() {

    int[] input = {0, 1, -2, -3, 4};
    int expectedResponse = 0;

    assertThat(sum(input)).isEqualTo(expectedResponse);
}

@Test
public void sumCanHandleEmptyArray() {

    int[] input = {};
    int expectedResponse = 0;

    assertThat(sum(input)).isEqualTo(expectedResponse);
}

I have used assertj library for java tests我已经将assertj库用于 Java 测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在代码中证明递归“搜索”算法的正确性? - How to prove the the correctness of recursive “search” algorithm in the code? 我如何证明 Java 中的一种算法比另一种算法快 - How can I prove that one algorithm is faster than another in Java 如何自动化测试以检查JSF应用程序的正确性? - How can I automate tests to check correctness of a JSF application? 如何证明HTTP POST方法不是幂等的? - How can I prove HTTP POST Method is not Idempotent? 线程优先级算法的正确性 - Correctness of thread priority algorithm 验证FFT算法的正确性 - Verifying correctness of FFT algorithm 您如何证明或说明快速合并排序是一种不稳定的算法? - How do you prove or illustrate that fast merge sort is an unstable algorithm? 算法的实验分析 - 如何证明图形是 O(nlogn)? - Experimental Analysis of an Algorithm - How to prove that the graph is O(nlogn)? 如何数学上证明Nginx平滑权重负载均衡算法? - How to prove the Nginx smoothing weight load balancing algorithm mathematically? 我选择UDP作为我的对等2对等服务,如何在我的情况下证明它是可靠的 - I chose to UDP as my peer 2 peer service, and how can I prove it's reliable in my situation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM