【问题标题】:How should I Test a Genetic Algorithm我应该如何测试遗传算法
【发布时间】:2010-11-05 13:29:17
【问题描述】:

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

为了更笼统地提出这个问题,您如何测试非确定性方法/功能。这是我的想法:

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

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

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

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

非常好的测试书籍的链接也将不胜感激。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    编辑我发现了这个strategies for testing nondeterministic systems,它可能会提供一些见解。一旦 TDD/开发过程证明逻辑是合理的,它可能有助于实时结果的统计分析。

    【讨论】:

    • 感谢您的回答。我曾希望有一些灵丹妙药,但我想这并不是一件容易测试的事情。如果我仔细挑选随机数,我可以测试每个执行路径。我还将使用已知的健身环境进行测试,以便了解它的表现。
    • @James,请记住,对于非确定性算法,“测试逻辑”和测试“预期结果”之间存在显着差异。做一个,然后另一个。如果第一个坏了,第二个就没有意义了。
    【解决方案2】:

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

    【讨论】:

    • 这不仅会评估值在法线附近的分布,而不是评估算法以正确方式围绕法线分布的适合度吗?如果您运行两次,损坏的算法仍然会被破坏。如果它有搜索结果,就像检查结果中包含关键字一样作为搜索顺序的验证。
    • 我说的不是正态分布,我是说分布要满足统计预期,即如果你需要一个随机函数来返回,比如一个boltzmann分布对应的随机值,你应该检查是否有足够多的测试运行形成这样的分布。
    • 我明白了。我认为这对 TDD 来说可能有点容易出错。我什至认为我链接到的论文中基于图形的统计分析不应该是逻辑单元/功能测试的第一个端口,而不是实时数据的结果。
    【解决方案3】:

    如果您谈论的是 TDD,我会说肯定从选择一个常数开始并从那里扩展您的测试套件。我已经对一些高度数学的问题进行了 TDD,它有助于拥有一些你知道并从一开始就手工解决的恒定案例。

    W/R/T 您的第四点,将不确定性代码移出 GA,我认为这可能是一种值得考虑的方法。如果您可以分解算法并分离非确定性关注点,它应该使测试确定性部分变得简单。只要您注意命名事物的方式,我认为您不会在这里牺牲太多。除非我误解了你,否则 GA 仍将委托给此代码,但它存在于其他地方。

    关于(开发人员)测试的非常好的书籍的链接,我最喜欢的是:

    【讨论】:

      【解决方案4】:

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

      例如,如果您有一个函数,该函数接受一个基因(某物的向量)并利用该基因的两个随机点对它们做某事(突变或其他),您可以将随机数的生成放在一个函数,然后将它们与基因一起传递给另一个包含给定数字的逻辑的函数。

      通过这种方式,您可以使用逻辑函数进行 TDD,并将某些基因和某些数字传递给它,确切地知道在给定数字的情况下逻辑应该对基因做什么,并能够在修改后的基因上编写断言。

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            我编写了一个 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

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

            【讨论】:

            • 感谢您的回复,我稍后会检查代码。我现在已经完成了测试,并使用了一种与你类似的方法,我想。当我为我的“随机”数字赋予特定值时,我测试了我知道应该发生的各种事情。然后我检查了分布大约是我预期的超过 10,000 次试验。不完美,但可以。
            【解决方案8】:

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

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

            换句话说,除了通过找到的解决方案的优点之外,您将无法测试 GA 是否真的执行。

            【讨论】:

              【解决方案9】:

              算法在相同输入下为您提供相同结果的测试可能会对您有所帮助,但有时您会进行更改,从而改变算法的结果选择行为。

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

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

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

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                  猜你喜欢
                  • 2017-05-13
                  • 2023-03-28
                  • 2015-08-03
                  • 2012-06-17
                  • 2021-08-04
                  • 2010-12-01
                  • 2018-05-10
                  • 2011-01-11
                  • 2019-06-22
                  相关资源
                  最近更新 更多