测试(确定性)算法有多个或难以证明正确的正确答案


11

我想前言本认为这个问题是相似的,但我的问题不涉及随机性,只是挑剔的决定,所以回答“使用已知的种子”并没有真正适用。同样,这个问题是相似的,但是我也不希望算法会失败-我只是不知道哪种方法正确。

这个问题是在测试图形算法时出现的。但绝不仅限于此。某些算法(例如A *)可以有多个正确答案。根据您的确切实现,您可能会得到几个答案中的任何一个,每个答案都是正确的。但是,这会使他们难以测试,因为您不知道它会提前吐出哪一个,并且手工计算答案非常耗时。

在我的特定情况下,我通过修改Floyd-Warshall使其吐出所有可能的最短路径来解决它,并花了一些时间进行测试。它具有本身就是一个好的功能的好处。然后,我可以根据FW已知的正确路径测试其他功能(如果返回的路径是FW为该开始/结束对返回的路径中的任何一条,那是正确的)。当然,由于FW的工作原理,这仅适用于密集图,但它仍然很好。

但是,这对于具有此特征的所有算法可能并不总是可行的。到目前为止,我想出的最佳答案是测试正确答案的特征,而不是正确答案本身。要返回最短路径算法,您可以对照已知的正确成本检查返回路径的成本,并确保路径有效。

此方法可行,但存在更多的正确性标准时,可能冒着无法正确验证所有内容的风险,尤其是在验证本身很复杂的情况下(例如,在存在正确算法的情况下,验证最小生成树是一个已知的难题;可能比构建MST本身),在这种情况下,您现在必须广泛测试测试代码。更糟:大概您必须构造一个MST来测试MST验证算法,因此您现在遇到了一个很好的方案,其中MST测试依赖于MST验证算法的工作,而MST验证算法测试依赖于MST生成代码的工作。

最后,有一种“便宜的方法”,它涉及观察输出,手工验证输出,然后对测试进行硬编码以测试刚刚验证的输出,但这并不是一个好主意,因为您可能每次都要修改测试稍微更改实现(这是自动化测试应该避免的)。

显然,答案取决于您在某种程度上要测试的确切算法,但是我想知道是否有“最佳实践”来验证具有几个确定的,确定性的“正确”输出的算法,但是这些精确的正确输出很难做到提前知道,可能事后甚至很难核实。


3
如果语言允许,您可以证明其正确性而不是对其进行测试
miniBill 2014年

有很多文字,但没有问题。那么,您到底在问什么?
BЈовић

@BЈовић“我应该如何测试具有多个和/或难以验证正确输出的算法的实现?” 抱歉,我不确定如何使它更清楚。我同意,根据您的观点,它可能被认为有点宽泛,但我认为它是不确定的。
LinearZoetrope 2014年

我还是不明白 您的算法不依赖于随机性,但是它仍然可以产生不同的输出。那根本没有道理。对于设置的输入,每种算法都必须具有相同的输出。这就是在单元测试中完成和测试的内容。甚至您链接的论文中的算法。
BЈовић

@BЈовић当然是确定性的,但它也非常敏感,例如,图返回节点的后继者的顺序。可能会导致蝴蝶效应。如果您都将顶点A压入堆栈B之前,如果两者都导致最短路径,则将导致输出不同。使用非稳定排序或最小堆之类的库函数只会加剧该问题。
LinearZoetrope 2014年

Answers:


5

我不确定您是否要测试正确的属性,这会引起歧义。

图形算法的目的不是寻找最短路径(这是一个副作用),而是最小化或最大化在边和顶点集上定义的某些成本函数。因此,您可以通过测试此功能的最终值并断言第一个和最后一个节点是实际需要的节点,来检查解决方案的正确性。

如果您可以为每个可能的路径预先计算最终成本函数值(通常是不现实的),则只需检查被测实现提供的解决方案的成本是否等于该组中的最低成本(绝对比较) )。如果您“仅”拥有黄金标准算法和/或实现,则应将其输出成本与被测算法之一进行比较(相对比较)

例如,一个简单的测试设置将是:

  1. 用贪婪算法计算测试图中Va和Vb之间的所有可能路径。
  2. 为这些路径中的每条路径计算成本函数(例如,如果所有边缘权重均等于1,则为长度),并找到最小值。
  3. 应用被测算法。
  4. 在单元测试中断言所测试的算法成本值等于贪婪解的最小值。

如果您想了解有关基于图的优化的更多信息,可以在这里查看Yuri Boykov的出版物,尽管是在另一种情况下(计算机视觉问题)。


我赞成,但我会稍等一下。这是我在问题中提到的“测试正确答案的特征”。问题总是出在确保您验证正确的事情上。例如,我一次检查了返回的费用并确保路径有效。当然这条路是有效的!这只是开始节点!因此,我必须更改测试以确保路径本身实际具有返回的正确成本。当然,这是一个愚蠢的错误,但是您的输出像这样进行的交互越多,它们发生的可能性就越大。
LinearZoetrope 2014年

以我的观点,@ Jsor是测试的持续改进优势:您无法首先弄清解决方案的所有正确性,然后有一天会出现一些故障,改进测试等等。
sansuiso 2014年

这个答案建议测试的正确答案的特点,但重要的是要选择哪个特点让一个很好的考验。在此示例中,验证答案是否是从A到B的路径,以及成本函数等于最小值,将为您提供两个标准,所有正确答案都将满足,而没有错误答案将满足这两个条件。如果还没有给出这个答案,我会推荐类似的东西。诚然,通常不容易知道要测试哪些特性。
大卫·K

0

我认为您问题的直接答案是选择更好的测试用例。我想知道您正在使用的测试用例。您使用的图形可以是罐状图形,在此图形中,人们相对容易确定期望的响应。尝试找出您想要确保算法能够处理的“边缘”情况,并为人类易于计算的每个特定边缘情况创建一个罐头图。例如,在Djikstra算法的情况下,即使实际系统可能是500x500,也可以创建一些5x5或7x7的图形来覆盖所有边缘情况。

然后,作为最终的健全性检查,您可以创建一个或更现实的图形测试用例。但是无论如何,我认为sansuiso在指出需要指出的地方确定您正在测试正确的属性。

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.