【问题标题】:Poor randomization in the Genetic Algorithm Framework遗传算法框架中的随机性差
【发布时间】:2016-04-04 10:59:06
【问题描述】:

有没有人从 .Net Genetic Algorithm Framework 看到令人信服的结果?

我在遗传算法框架提供的旅行推销员问题演示中看到随机性很差。以下调用在 x 100 个种子染色体群体中生成相同的基因洗牌顺序:

chromosome.Genes.ShuffleFast();

如果我单步执行代码,基因顺序看起来是随机的,因此我怀疑 ShuffleFast() 中存在 time/Rdn() 错误,否则我忽略了设置步骤。

我试图通过预洗染色体基因序列来解决这个问题,这对 TSP 结果产生了微小的变化。然而,运行的控制台日志仍然显示 GAF 在 400 代人口中仅发现了 4 个潜在的解决方案。这与 GA YouTube 视频不一致,该视频显示遗传算法实现归巢于具有大量抖动的建议解决方案。我引用这进一步表明 GAF 在随机数生成方面存在系统性内部问题。

作者的博客对遗传算法框架进行了很好的记录,因此我试图保持开放的心态。

重现步骤 = 从 nuget 下载 GAF,在创建染色体 for 循环后使用断点编译和调试默认项目,检查 population.Solutions。 Windows 7、VS2015、.Net 4.5 和 4.61。调试或发布。

【问题讨论】:

  • 您能否发布更多代码以显示此调用的上下文。如果未正确初始化,随机数生成器可能会出现问题。
  • @ChrisF ShuffleFast() 例程的内部工作在我认为是封闭源代码的 GAF 库中。图书馆的作者需要回应,他在 SO 上很活跃。在那之前,我会寻找另一个 GA 库。 ShuffleFast() 调用在 16 个整数列表的紧密循环中进行了 100 次,如果我在该循环中手动中断并按 F10,则 Shuffle 结果看起来是随机的。
  • “ShuffleFast() 调用在 16 个整数列表上的紧密循环中进行了 100 次,” - 这可能是问题的原因。看起来随机数生成器正在循环的每次迭代中进行初始化。进入调试器会减慢它的速度,从而给你随机的结果。您需要在循环外初始化生成器。
  • 请注意,基本 GA:s 并不是真正解决 TSP 的最佳方法。一个简单的蚂蚁系统 (AS) 实现通常优于 TSP:s 的 GA,即使在后者中包括针对特定问题测试的突变率/高级交叉方案以保持排列编码完整。可能,对于您看过的 youtube 视频,染色体已经用良好的启发式解决方案进行了初始化,并显示了针对特定问题的参数调整后的最终结果。

标签: c# genetic-algorithm genetic-programming


【解决方案1】:

查看反汇编程序中的代码,有两个版本的ShuffleFast 定义为扩展方法:一个将Random 对象作为参数,另一个使用default constructor 创建一个新对象并使用它。它们在其他方面是相同的,都是标准的 Fisher-Yates 洗牌。

所以你需要自己构造Random,然后传入:

Random r = new Random();
...
chromosome.Genes.ShuffleFast(r);
otherChromosome.Genes.ShuffleFast(r);
...

这样,您只有一个随机数流,并且每当您运行程序时,该流都会根据当前时间播种。

【讨论】:

  • 我按照您的建议使用了 ShuffleFast(Random r) 重载,并在染色体种群循环之外声明了 r。现在种子种群具有随机基因序列。在 400 代中,只有几个城市游览距离变化,测试输出看起来仍然很奇怪。我的下一步是将 GAF 测试数据移植到另一个 GA .Net 框架,以查看该算法是否逐步找到最佳答案。如果 GAF 的作者没有对运行时测试结果提供更深入的描述,我会将您的回复标记为已接受的答案。
【解决方案2】:

抱歉,问题回复晚了。问题确实出在 GAF 上。 Shuffle 方法使用 System.Random 数字生成器,并在每次调用该方法时创建一个新数字生成器。这会由于播种而导致问题。我已经在 GAF 中修复了这个(今晚),这将在下一个版本中。我建议使用以下代码作为解决方法。

var rnd = GAF.Threading.RandomProvider.GetThreadRandom ();
myList.ShuffleFast (rnd);

使用上述代码创建的每个随机数生成器都会创建一个随机数生成器,每个线程都有一个种子。然后可以按照 Matthew 的描述将其传递给 Shuffle() 方法。

【讨论】:

    猜你喜欢
    • 2015-07-03
    • 2012-07-07
    • 2019-08-07
    • 2018-04-10
    • 2016-09-11
    • 2011-04-16
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多