6

I'm making a Genetic Program, but I'm hitting a limitation with C# where I want to present new functions to the algorithm but I can't do it without recompiling the program. In essence I want the user of the program to provide the allowed functions and the GP will automatically use them. It would be great if the user is required to know as little about programming as possible.

I want to plug in the new functions without compiling them into the program. In Python this is easy, since it's all interpreted, but I have no clue how to do it with C#. Does anybody know how to achieve this in C#? Are there any libraries, techniques, etc?

4

6 に答える 6

13

プログラムのユーザーに「許可された機能を提供する」方法に依存します。

  • ユーザーが既に実装した関数を選択している場合は、これらをデリゲートまたは式ツリーとして渡すことができます。
  • ユーザーが C# または別の .NET 言語で独自のメソッドを記述し、それらをアセンブリにコンパイルする場合は、Reflection を使用してそれらを読み込むことができます。
  • ユーザーが C# ソース コードをプログラムに入力できるようにする場合は、CodeDom を使用してコンパイルし、Reflection を使用して結果のアセンブリを呼び出すことができます。
  • 単純な数学言語などのカスタム式言語をユーザーに提供したい場合は、(言語を解析できると仮定して) Reflection.Emit を使用して動的アセンブリを生成し、次を使用してそれを呼び出すことができます -- ご想像のとおり --反射。または、ユーザー コードから式ツリーを構築し、それを LINQ を使用してコンパイルすることもできますが、必要な柔軟性によって異なります。(そして、待つ余裕があれば、.NET 4.0 の式ツリーは 3.5 にあった制限の多くを取り除くので、Reflection.Emit を完全に回避できるかもしれません。)
  • ユーザーが Python、Ruby、またはその他の DLR 言語を使用して式を入力することに満足している場合は、ユーザーのコードを解釈する動的言語ランタイムをホストできます。

ここでは、DLR (および IronPython または IronRuby) をホストすることをお勧めします。これは、十分にテストされた環境と、DLR が提供するすべての最適化を取得できるためです。 IronPython の使用方法は次のとおりです。

パフォーマンスに関する質問への回答として追加: DLR は最適化に関してかなりスマートです。毎回やみくもにソース コードを再解釈するわけではありません。ソース コード (具体的には、特定の関数またはクラス) を MSIL に変換すると、ソース コードが変更されるまで、そのコンパイルされた表現を再利用し続けます (たとえば、関数が再定義されます)。したがって、ユーザーが同じ関数を使用し続けているが、異なるデータ セットに対して使用している場合、同じ ScriptScope を維持できる限り、適切なパフォーマンスが得られるはずです。あなたの懸念が、遺伝的アルゴリズム中に同じ関数を何十億回も実行することだけである場合も同様です。DLR のホスティングは非常に簡単なので、概念実証を行い、それがニーズに合っているかどうかを確認することは難しくありません。

于 2010-03-16T23:27:15.180 に答える
7

式ツリーの作成と操作を試みることができます。Linqを使用して式ツリーを評価します。

于 2010-03-16T23:23:09.650 に答える
2

CodeDom を使用して、関数をコンパイルして実行することもできます。グーグルで検索して、ニーズに合った例を確認してください。この記事「C#コードを動的にコンパイルする方法」この記事「.Netでコードを動的に実行する」が役立つようです。

于 2010-03-16T23:34:42.350 に答える
1

System.Reflection.Emit を見て、IL レベルでコードを生成できます。

または、C# を生成し、ライブラリにコンパイルして動的にロードします。それほど柔軟ではありません。

于 2010-03-16T23:25:53.210 に答える
1

コード内からコンパイラにアクセスできます。その後、コンパイルされたコードのインスタンスを作成し、アプリケーションを再起動せずにそれらを使用できます。その例は周りにあります

ここ

ここ

2 つ目は JavaScript エバリュエーターですが、簡単に適応させることができます。

于 2010-03-16T23:25:17.297 に答える
1

実際、IL を生成するのは非常に簡単です。このチュートリアルを参照してください: http://www.meta-alternative.net/calc.pdf

于 2010-03-16T23:46:34.300 に答える