【问题标题】:What is the fastest way of testing correctness of a sorting function?测试排序函数正确性的最快方法是什么?
【发布时间】:2018-09-22 17:29:13
【问题描述】:

使用遗传算法,我找到了这个比较列表:

compareAndSwap(x[0],x[2]);
compareAndSwap(x[3],x[4]);
compareAndSwap(x[2],x[4]);
compareAndSwap(x[0],x[3]);
compareAndSwap(x[2],x[3]);
compareAndSwap(x[1],x[3]);
compareAndSwap(x[1],x[2]);
compareAndSwap(x[0],x[1]);
compareAndSwap(x[3],x[4]);

但我需要测试它是否适用于所有情况。在某些情况下,数组元素的数量(目前为 5 个)可以增长到 100 个。这意味着要检查的案例数量正在快速增长,超过pow(2,100)

如果我只给出一个相反排序的数组作为最坏的情况,那不会检查关于中间元素x[2] 比较的任何错误。比如5,4,3,2,1被某个函数排序成1,2,3,4,5, by

compareAndSwap(x[0],x[4]);
compareAndSwap(x[1],x[3]);

单独使用,这肯定不会对许多 5 元素数组的情况进行排序。

尝试了样本数组的随机数生成器,但不确定它是否可以接受:

      std::random_device rd;
      std::mt19937 rng(rd());
      std::uniform_real_distribution<double> dist(0,1);

      for(int k=0;k<500;k++)
      {
        std::vector<double> arraySorted;
        for(int i=0;i<5;i++)
            arraySorted.push_back(dist(rng));

      //sortNetwork(arraySorted.data());

      //if(!std::is_sorted(arraySorted.begin(),arraySorted.end())) 
            throw std::runtime_error("error");
      }

即使这样仍然会遗漏一些部分。有没有快速测试排序算法的方法?

如果它是 1000 个元素的数组呢?这些是在某些定理和已知算法中使用数学、笔和纸进行测试,还是使用超级计算机进行测试?

只是 4 个元素的一些示例:

1 2 3 4   
1 2 4 3   
2 1 3 4    
2 1 4 3   
1 2 0 1                        
1 2 1 0                         
2 1 0 1
2 1 1 0
3 4 2 1                           
3 4 1 2
4 3 2 1
4 3 1 2
1 1 1 1

似乎有不止 pow(2,n) 个案例。

在生成测试数据时,排序网络是否可以像图形问题一样处理?

【问题讨论】:

  • 你能证明它适用于某些 n 元素的情况,然后通过归纳证明它适用于 n + 1 元素吗?跨度>
  • 你的意思是我应该用 2 个元素然后 3 个元素然后 4 个......直到超过时间限制并接受算法为“有效”?我无法理解“感应”部分。是否类似于使用 n=2 分拣机来测试 n=3 分拣机?如何?还是要测试生成排序网络的算法的正确性?
  • 归纳证明是一种成熟的方法:Mathematical induction.
  • 然后是关于生成排序函数的算法。我会试试这个方法,谢谢。如果方法包含随机性并且可以不时改变它的行为,这样我在查看 1000 个元素的排序器时会感到不安全怎么办?
  • permutations 的数量为 n!。因此,对于较大的 n,测试每个排列并不容易。您的 compareAndSwap 代码是为每个 n 生成还是手动编写的?

标签: arrays performance sorting testing correctness


【解决方案1】:

虽然您可以检查每个可能列表的每次迭代,但正如您所指出的那样,这太慢了。测试与proving the algorithm correct 无关,因为你需要做一个证明。测试是通过测试它可能隐藏的所有地方来减少错误的可能性。测试很少尝试覆盖整个可能的空间,而是尝试覆盖可能的类型错误。

这里有一些例子来练习排序功能。

  • 一个空列表
  • 单个元素列表
  • 全零列表
  • 有序列表
  • 反向列表
  • 所有相同元素的列表
  • 一个非常大的列表
  • 包含奇怪元素(例如 Unicode、负数、重载数字)的列表

然后有错误的输入应该返回错误而不是垃圾。垃圾进,错误出。

  • 空指针
  • 空值列表
  • 列表太大(如果您的函数有大小限制)

是的,随机化。生成随机有效大小的随机有效列表,然后验证排序结果是否有序。这有助于涵盖您可能错过的任何情况,并避免您可能做出的任何错误假设。这在测试函数"black box" 时尤为重要,这意味着测试人员不了解其内部结构。每次针对函数运行更多随机列表时,都会进一步降低出现错误的可能性。

请务必输出使用的随机种子,以便在失败时重复测试。

最后,使用test coverage 来确保您的测试能够触及代码的所有行和分支。代码可能由 AI 生成,但您仍然可以对其进行覆盖分析以识别您的测试差距。在可能不可读的 AI 生成的代码上运行代码美化器将帮助您了解需要更多测试的地方。

【讨论】:

  • 然后我拿笔和纸做一些微积分来找出它。也许通过遵循比较结果的概率或类似的东西。谢谢。
猜你喜欢
  • 2010-10-08
  • 2019-06-13
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2011-01-24
相关资源
最近更新 更多