我应该如何testing一个遗传algorithm

我做了很less的遗传algorithm; 他们工作(他们迅速find合理的解决scheme)。 但是我现在已经发现了TDD 。 有没有办法用TDD的方式编写一个遗传algorithm (这个algorithm严重依赖于随机数)?

为了更一般地提出这个问题,你如何testing一个非确定性的方法/函数。 这是我想到的:

  1. 使用特定的种子。 如果我首先在代码中犯了一个错误,那么这将无法帮助,但是在重构时将有助于查找错误。

  2. 使用已知的数字列表。 与上面类似,但我可以通过手动跟踪代码(这将是非常乏味的)。

  3. 使用一个常数。 至less我知道该期待什么。 当RandomFloat(0,1)总是返回1时,确保骰子总是读取6是很好的。

  4. 尽量将尽可能多的非确定性代码移出GA。 这看起来很愚蠢,因为这是它的目的的核心。

链接到非常好的书籍testing也将不胜感激。

对我来说,testing其一致性逻辑的唯一方法是应用一致的input ,或者将每次迭代看作是在迭代之前和之后testing其状态的单个自动机,将整个非确定性系统转化为基于确定性的可testing组件迭代值。

对于迭代中的变异/繁殖/属性inheritance,在每次迭代的边界上testing这些值,并基于来自成功的迭代子testing的已知input/输出来testing所有迭代的全局输出。

因为algorithm是迭代的,所以可以在testing中使用归纳法 ,以确保它在1次迭代中工作,n + 1次迭代certificate对于给定的input范围/域将产生正确的结果(不pipe数据的确定性)以及对可能值的约束在input。

编辑我发现这个策略来testing可能提供一些洞察力的非确定性系统 。 一旦TDD /开发过程certificate逻辑是正确的,对活结果的统计分析可能会有所帮助。

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

如果你正在谈论TDD,我会说从一开始就select一个固定的数字,并从那里增加你的testing套件。 我已经完成了几个高度math问题的TDD,它可以帮助你掌握一些你知道的并且从头开始用手工计算的常量情况。

W / R / T你的第四点,把不确定的代码移出GA,我想这可能是一个值得考虑的方法。 如果可以分解algorithm并分离非确定性问题,则应该直接testing确定性部分。 只要你小心你的名字,我不认为你在这里牺牲太多。 除非我误解了你,否则GA仍然会委托给这个代码,但是它还是在别的地方。

至于(开发人员)testing我的collections的非常好的书的链接是:

  • 由Lasse Kosela 驾驶的testing
  • 通过Michael Feathers的遗留代码有效地工作
  • XUnittesting模式 Gerard Meszaros
  • 下一代Java™testing: CédricBeust和Hani Suleiman撰写的TestNG和Advanced Concepts

我为单位testingGAalgorithm的非确定性函数所做的一种方法是将随机数的select置于使用该随机数的逻辑函数的不同函数中。

例如,如果你有一个函数需要一个基因(某物的向量),并且需要基因的两个随机点来处理它们(变异或其他),你可以把随机数的生成放在一个函数中,然后将它们与基因一起传递给包含给定数字的逻辑的另一个函数。

通过这种方式,你可以用逻辑function做TDD,并传递给它一定的基因和一定的数字,准确地知道逻辑在给定数字的基因上应该做些什么,并且能够在修改后的基因上写出断言。

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

您可以编写一个冗余neural network来分析algorithm的结果,并根据预期的结果对输出进行sorting。 🙂

尽可能地打破你的方法。 然后你也可以围绕随机部分进行unit testing来检查值的范围。 即使有testing运行几次,看看结果是否改变。

你所有的function应该是完全确定的。 这意味着你正在testing的function都不应该在函数内部产生随机数。 你会想要把它作为参数传入。 这样当你的程序根据你的随机数做出决定的时候,你可以通过代表性的数字来testing该数字的预期输出。 唯一不应该确定的是你的实际随机数字生成器,你不需要太担心,因为你不应该自己写这个。 你应该能够假设它只要build立一个图书馆就可以工作。

这是你的unit testing。 对于你的集成testing,如果你这样做,你可能会考虑嘲笑你的随机数生成,用一个algorithm来替代它,这个algorithm将返回0..n的已知数,对于你需要生成的每个随机数。

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

让我们在应用程序中采用最简单的随机结果方法:PointGenetics.Create,给定边界,创build一个随机点。 对于这个方法,我使用了5个testing,而且没有一个依赖于特定的种子:

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

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

那么最可testing的部分是健身function – 你所有的逻辑将在哪里。 这可能在某些情况下非常复杂(您可能正在运行基于input参数的各种模拟),所以您要确保所有这些东西都可以与大量unit testing一起工作,而且这项工作可以遵循任何方法。

关于testing遗传algorithm的参数(变异率,交叉策略,不pipe),如果你自己实现的东西,你当然可以testing它(你可以再次有突变逻辑等unit testing),但你不会能够testingGA的“微调”。

换句话说,你将无法testing遗传algorithm的实际效果,而不是find解决scheme的好处。

algorithm为相同input提供相同结果的testing可以帮助您,但是有时您会进行更改,改变algorithm的结果选取行为。

我会尽最大的努力做一个testing,确保algorithm给你一个正确的结果。 如果algorithm为多个静态种子和随机值提供了正确的结果,则该algorithm可以正常工作,或者不会因所做的更改而中断。

TDD的另一个机会是评估algorithm的可能性。 如果您可以自动检查结果有多好,您可以添加testing,以显示更改没有降低结果的质量或增加计算时间不合理。

如果你想testing你的algorithm与许多基础种子,你可能想要testing一套西装,每次保存后运行一个快速的testing启动,以确保你没有损坏任何东西和一个更长时间运行的西装稍后评估

我强烈build议寻找使用模拟对象为您的unit testing用例( http://en.wikipedia.org/wiki/Mock_object )。 您可以使用它们来模拟出随机猜测的对象,以便让您获得预期的结果。