我应该如何测试遗传算法

时间:2009-06-24 15:26:09

标签: unit-testing language-agnostic genetic-algorithm non-deterministic

我做了很少的遗传算法;他们工作(他们很快找到合理的解决方案)。但我现在发现了TDD。有没有办法以TDD方式编写genetic algorithm(严重依赖于随机数)?

更一般地提出问题,如何测试非确定性方法/功能。以下是我的想法:

  1. 使用特定种子。如果我首先在代码中犯了一个错误,但在重构时有助于发现错误,那将无济于事。

  2. 使用已知的数字列表。与上述类似,但我可以手工操作代码(这将非常繁琐)。

  3. 使用常数。至少我知道会发生什么。当RandomFloat(0,1)总是返回1时,确保骰子总是读数为6是好的。

  4. 尝试尽可能多地从GA中移出非确定性代码。这似乎是愚蠢的,因为这是它的目的的核心。

  5. 关于测试的非常好的书籍的链接也将受到赞赏。

10 个答案:

答案 0 :(得分:14)

在我看来,测试一致逻辑的唯一方法是应用一致输入,...或将每次迭代视为单个自动机,其状态在迭代之前和之后进行测试,根据确定性迭代值将整个非确定性系统转换为可测试组件。

对于迭代中的变体/繁殖/属性继承,在每次迭代的边界上测试这些值,并根据成功迭代 - 子测试的已知输入/输出测试所有迭代的全局输出...

由于算法是迭代的,您可以在测试中使用归纳来确保它适用于1次迭代,n + 1次迭代以证明它将为给定的结果产生正确的结果(无论数据确定性如何)输入范围/域以及输入中可能值的约束。

修改我发现这个strategies for testing nondeterministic systems可能会提供一些见解。一旦TDD /开发过程证明逻辑合理,对实时结果进行统计分析可能会有所帮助。

答案 1 :(得分:4)

我会通过多次测试随机函数并分析返回值的分布是否符合统计预期(这涉及一些统计知识)来测试随机函数。

答案 2 :(得分:2)

如果你正在谈论TDD,我会说从一开始就选择一个常数并从那里开始你的测试套件。我已经完成了一些高度数学问题的TDD,它有助于你知道一些常见的情况,并从头开始用手工作。

W / R / T第4点,将非确定性代码移出GA,我认为这可能是值得考虑的方法。如果您可以分解算法并分离非确定性问题,那么它应该直接测试确定性部分。只要你小心你如何命名,我就不认为你在这里牺牲很多。除非我误解你,否则GA仍将委托给这个代码,但它会存在于其他地方。

关于(开发者)测试我的最爱的非常好的书的链接是:

答案 3 :(得分:2)

我对GA算法的非确定性函数进行单元测试的一种方法是将随机数选择在使用该随机数的逻辑1的不同函数中。

例如,如果你有一个函数,它接受一个基因(某种东西的载体),并取基因的两个随机点来对它们做一些事情(突变或其他),你可以把随机数的生成放在一个函数,然后将它们与基因一起传递给另一个函数,该函数包含给定数字的逻辑。

通过这种方式,您可以使用逻辑功能进行TDD并将其传递给某些基因和某些数字,确切地知道在给定数字的基础上逻辑应该做什么以及能够在修饰基因上写断言。

另一种方法是,使用随机数生成进行测试是将该生成外部化到另一个类,可以通过上下文访问或从配置值加载,并使用不同的类进行测试执行。该类将有两个实现,一个用于生成实际随机数的生产,另一个用于测试,它们可以接受稍后生成的数字。然后在测试中,您可以提供该类将提供给测试代码的某些数字。

答案 4 :(得分:1)

您可以编写冗余神经网络来分析算法的结果,并根据预期结果对输出进行排序。 :)

尽可能多地打破你的方法。然后,您还可以围绕随机部分进行单元测试,以检查值的范围。甚至让测试运行几次以查看结果是否发生变化。

答案 5 :(得分:1)

您的所有功能都应完全确定。这意味着您正在测试的所有函数都不应在函数本身内生成随机数。您将希望将其作为参数传递。这样,当您的程序根据您的随机数做出决策时,您可以传递代表性数字来测试该数字的预期输出。唯一不应该是确定性的是你的实际随机数生成器,你真的不需要太担心,因为你不应该自己写这个。你应该能够假设它只是一个既定的库。

这是你的单元测试。对于集成测试,如果您这样做,您可能会考虑模拟随机数生成,将其替换为将为您生成的每个随机数返回0..n中已知数字的算法。

答案 6 :(得分:1)

我写了一个C#TDD遗传算法教学应用: http://code.google.com/p/evo-lisa-clone/

让我们在应用程序中采用最简单的随机结果方法:PointGenetics.Create,它根据边界创建一个随机点。对于这种方法,我使用了5个测试,但它们都不依赖于特定的种子:

http://code.google.com/p/evo-lisa-clone/source/browse/trunk/EvoLisaClone/EvoLisaCloneTest/PointGeneticsTest.cs

随机性测试很简单:对于大边界(多种可能性),两个连续生成的点不应该相等。其余测试检查其他约束。

答案 7 :(得分:1)

最可测试的部分是健身功能 - 你所有的逻辑都在哪里。在某些情况下,这可能非常复杂(您可能会根据输入参数运行各种模拟),因此您需要确保所有这些内容适用于大量单元测试,并且此工作可以遵循任何方法。

关于测试GA参数(突变率,交叉策略等),如果你自己实现这些东西,你当然可以测试它(你可以再次对变异逻辑进行单元测试等)但是你赢了无法测试GA的'微调'。

换句话说,你将无法测试GA是否实际上执行的除了找到的解决方案的优点之外。

答案 8 :(得分:0)

算法为同一输入提供相同结果的测试可以帮助您,但有时您会进行更改以更改算法的结果拾取行为。

我会尽最大努力进行测试,确保算法为您提供正确的结果。如果算法为您提供了许多静态种子和随机值的正确结果,则算法可以正常工作,或者不会通过所做的更改来解决。

TDD的另一个机会是评估算法的可能性。如果您可以自动检查结果有多好,则可以添加测试,表明更改未降低结果质量或增加计算时间不合理。

如果你想用许多基础种子测试你的算法,你可能想要测试一套西装,在每次保存后运行一个快速测试,以确保你没有破坏任何东西和一个运行的西装更长时间的后续评估

答案 9 :(得分:0)

我强烈建议在单元测试用例(http://en.wikipedia.org/wiki/Mock_object)中使用模拟对象。您可以使用它们来模拟随机猜测的对象,以便使您获得预期的结果。