用于遗传编程的 C# 动态树
我有一些公共用户定义的类,其成员之间存在关系,还有一些具有特定和通用签名的方法。
我希望能够使用基本控制语句(如 if/then/else、foreach、do/while、变量赋值等)存储和操作这些类(加上 CLR 类)的自定义控制流。
自定义控制流应在以下位置创建:运行时然后存储以供以后使用和操作。 这个想法是拥有控制流的数据表示,可能以抽象语法树的形式,具有强类型语法,以便能够应用遗传操作。 生成的自定义代码必须作为另一个程序的一部分执行。
1) 操作遗传操作的首选代码表示是什么,然后执行包括我的类在内的代码,
2) 我应该使用哪些 C# 技术来解决上述问题? 我知道有相关技术,如反射、新的 c# 3.0 功能(lambda、表达式树)、CodeDom、DLR 库等,但哪种方法或组合是最有效的。
3)是否有这样的范例或实现可用?
编辑: 该平台提供了定义的 C# 自定义类型的数据,包括常量和时间变量。
每时每刻都将规则应用于数据(基本条件或更复杂的功能),并决定采取一些行动。
我希望能够:
在树或图上表示规则并执行该流程。
用户通过 UI 工具包创建自定义规则集
在树或图上进行重新排列并应用 GP 操作
I have some public user defined classes with relations between their members and also several methods with specific and generic signatures.
I would like to be able to store and manipulate custom control flow over these classes (plus CLR classes) using basic control statements like if/then/else, foreach, do/while, variable assignments etc.
The custom control flow should be created at runtime and then stored for later use and manipulation.
The idea is to have a data representation of the control flow, possibly in the form of a abstract syntax tree, with strongly typed syntax in order to be able to apply genetic operations.
The resulting custom code has to be executed as part of another program.
1) What is the preferred code representation for manipulating genetic operations and then execute the code including my classes,
2) Which c# technologies should I use for the above problem?
I know there are related technologies like reflection, the new c# 3.0 features (lambda, expression trees), CodeDom, DLR library, etc but which approach or combination is the most efficient.
3) Are there such paradigms or implementations available?
EDIT:
The platform is supplied with data of defined c# custom types, both constant and time variable.
Every moment rules are applied to the data (basic conditions or more complicated functions) and it is decided to take some actions.
I would like to be able to:
Represent the rules on a tree or a graph and execute tha flow.
Create custom rule sets by the user via a UI toolkit
Make rearrangement on the tree or graph and apply GP operations
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
反射是一种检查已经生成的类型、方法、字段等的技术,因此它目前可能对您没有多大帮助。
表达式树相当有趣,但据我所知,它们不允许您创建复杂的程序流,因为 lambda 表达式不能有主体,这将使创建任何适度复杂的东西变得相当困难。
DLR 正在酝酿之中。 您将获得一些零散的内容,但只有下一个 .NET 版本才会内置对 DLR 的支持。 通过动态创建程序并执行它们,这可能是一个有趣的选择。
您现在可以做的可能是在动态方法或动态生成的程序集中发出 IL。 所有可能的构造都应该可供您使用,但后续操作可能相当困难。
即便如此,有一个项目可以发挥相当多的 IL 魔力,甚至可能对您有用:林甫. 根据列表,您拥有动态对象的实现,并且可以执行诸如dynamicObject.CreateDuck()之类的操作。
另一个可能有点繁重但也很有趣的路线是WF(工作流基础)框架。 此类工作流程应该可以通过程序构建,并且由于其延续风格的工作方式,它们可能会很有趣:您可以随时保留正在运行的工作流程,并在您离开的地方重新开始。
所有传统的程序结构都应该在 WF 中可供您使用。
Reflection is the technology to inspect already generated types, methods, fields, etc., hence it'll probably not help you much for now.
Expression trees are rather interesting, but AFAIK they will not allow you to create complex program flow since a lambda expression cannot have a body, which would make it rather difficult to create anything moderately complex.
DLR is somewhat in the making. You will get the bits and pieces, but only the next .NET version will have baked-in support for the DLR. That could be an interesting alternative, by creating programs on the fly and executing them.
What you could do now is possibly emitting IL, either in a Dynamic Method or a dynamically generated assembly. All possible constructs should be available to you, but a subsequent manipulation is probably rather difficult.
Even so, there is one project that does quite a bit of IL magic and it may even be something that could be useful to you: LinFu. According to the list you have an implementation of Dynamic Object and can do stuff like dynamicObject.CreateDuck<InterfaceType>()
Another route which may be a bit heavy but also interesting is the WF (Workflow Foundation) Framework. Such workflows should be constructable by program and they may be interesting due to their continuation style working: You can persist a running workflow any time and pick it up just where you left it.
All traditional program structures should be available to you within WF.
培育用 C# 等语言表示的程序非常棘手 - 它们根本就不是可延展的 - 您会发现您所做的绝大多数更改只会导致程序失败。
我会推荐两种替代方法之一:
(1) 可以使用线性指令序列和某种形式的虚拟寄存器或堆栈机来表示。 (2) 可以使用树来表示,并使用某种形式的“归约”算法进行评估。
无论您使用哪种方法,您都需要在沙箱中执行程序 - 无限循环很常见,因此您需要能够在一定数量的循环后停止它们。
Breeding programs represented in languages such as C# is very tricky - they simply aren't designed to be malleable - you will find that the vast majority of changes you make simply cause the program to fail.
I would recommend one of two alternative approaches:
(1) is representable using a linear sequence of instructions and some form of virtual register or stack machine. (2) is representable using a tree, and evaluated using some form of "reduce" algorithm.
Whatever approach you use, you'll need to execute the programs in a sandbox - infinite loops will be common, so you'll need to be able to stop them after a set number of cycles.
动态表达式 [示例] API 涵盖了这个领域的基础......
the Dynamic Expression [example] API covers ground in this space...
只需输出 c#(任何其他支持此功能的 .net 语言,f# 也很好用)并使用 CodeDomProvider 即时编译它。 强制提供的代码成为一个源文件,以包含实现 IDynamicEntryPoint 的类型(使用静态方法或空构造函数,它是入口点,并将在构造后调用)
这应该是您首先调用的端口,因为可以快速尝试,同时长期获得最高性能的最佳机会(除非动态 IL 输出,但即使如此,您也可能无法击败编译器)
这显然有两个可能的缺陷,可能会破坏交易
除非您有兴趣编写自己的语言/解析器/编译器来娱乐,否则请使用已经存在的语言/解析器/编译器。
Just output c# (of any other .net language supporting this, f# works great too) and use the CodeDomProvider to compile it on the fly. Force the code supplied to be one source file, to include a type which implements IDynamicEntryPoint (with a static method or an empty constructor which is the entry point and will be invoked post construction)
This should be your first port of call to start with because it is quick to try out at the same time as long term having the best chance of the highest performance (barring dynamic IL output but even then you might not beat the compiler)
This obviously has two possible flaws which may be deal breakers:
Unless you are interested in writing your own language/parser/compiler for fun use one that's already there.