在开发了我自己的遗传编程教学应用程序之后,我发现了一个完整的遗传编程框架,名为AForge.NET Genetics。它是Aforge.NET库的一部分,采用LGPL许可证。
我建议您不要生成程序集,除非您确实需要,特别是如果您刚开始实现遗传算法。
当目标语言是函数式和动态类型时,遗传算法的实现最容易。这通常是为什么大多数遗传算法研究都是用LISP编写的原因。因此,如果您要在C#中实现它,最好定义自己的迷你“树语言”,让算法生成树,在运行每次算法迭代时只需解释树。
我在大学时做过这样的一个项目(在C#中实现遗传算法),那就是我采取的方法。
采用这种方式将使您具有仅有1个表示法(AST表示法),该表示法最适合执行和遗传算法“繁殖”步骤的优点。
另外,如果尝试生成程序集,您可能会向应用程序添加大量不必要的复杂性。目前,CLR不允许卸载App域中的程序集,除非销毁整个App域。这意味着您需要为每个生成的程序在每次算法迭代中启动单独的App域,以避免将巨大内存泄漏引入到应用程序中。总的来说,这样做只会增加许多额外的麻烦。
另一方面,解释的AST与任何其他对象一样可以进行垃圾回收,因此您不需要在多个应用程序域中操作。如果出于性能原因,您想要代码生成最终结果,可以稍后添加支持。但是,我建议您使用DynamicMethod类来完成这项工作。它将允许您在运行时动态将AST转换为已编译的委托。这将使您能够部署单个DLL,同时尽可能简化代码生成内容。此外,DynamicMethod实例也可以进行垃圾回收,因此您可以在遗传算法的一部分使用它们以加速运算。
你可能能够使用LINQ表达式树来实现遗传编程 -- 它比随机生成IL更有可能生成可用的东西。
我们还写了一本关于这个主题的书:遗传算法和遗传编程。
你是指实际的遗传编程,而不是一般的遗传算法吗?
如果是这样,C#/.net并不是最适合它的语言。例如,LISP一直是GP的主要支柱。
然而,如果你必须使用C#/.net,你可能需要动态生成CIL / MSIL。你可以使用System.Reflection.Emit来实现,但我建议使用Mono.Cecil。虽然它缺乏良好的文档(就像反射发射一样),但它提供了更好的程序集发射和反射。
另一个问题是,在.NET框架中加载代码并稍后处理它不是那么容易。至少,你不能卸载程序集。你可以卸载应用程序域,但将代码加载到单独的应用程序域中,并在外部调用它的整个过程可能会变得非常混乱。.NET 3.5的System.Addin功能应该会使这个过程更加容易。
var selection = new EliteSelection();
var crossover = new OrderedCrossover();
var mutation = new ReverseSequenceMutation();
var fitness = new YourFitnessFunction();
var chromosome = new YourChromosome();
var population = new Population (50, 70, chromosome);
var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation);
ga.Start();
如果您对一个功能齐全的进化计算框架感兴趣,我已经将ECJ转换成了C# .NET 4.0。该软件包包括了原始ECJ Java项目的所有内容,包括所有工作样本。
此外,我编写了500个单元测试以验证转换的许多方面。但是还需要更多的测试。特别是分布式计算方面尚未全面测试。这是因为我计划从ECJ的简单套接字使用转换为更强大的WCF和WF策略。我还将重新设计该框架以利用TPL(任务并行库)。
无论如何,您可以在此处下载初始转换:
http://branecloud.codeplex.com
我还在将其他几个与“合成智能”研究相关的Java框架转换为.NET(只要我有时间)。
Ben