22

ノードインターフェイス、基本的には各ノードが入力接続で操作を実行し、何かを出力するDAGを実装したいと思います(別のノードに接続できます)

いくつかのサンプルアプリケーション:


最初の目標として、ノードが2つしかないグラフィカルアプリケーションが必要です。単純に固定数を出力する「数値」と、2つの入力を受け取り、2つの合計を出力する「追加」ノード。

これまでのところ人々が答えているように、私はデータをコードで表現する方法、たとえばPythonのように見える擬似コードでデータを表現する方法について大まかな考えを持っています。

class Number:
    def __init__(self, value):
        self.value = value

    def eval(self):
        return self.value

class Add:
    def __init__(self, input1, input2):
        self.input1 = input1
        self.input2 = input2

    def eval(self):
        return self.input1.eval() + self.input2.eval()


a = Number(20)
b = Number(72)

adder = Add(a, b)
print adder.eval()

これにカスタムGUIをラップするにはどうすればよいですか?次のようなものですが、手描きは少し少ないです!

ノードUIモックアップ

どこから始めますか?私は現在、Objective-C / Cocoaでそれを書くことを計画していますが、他の言語の提案を受け入れる以上のことをしています。

4

7 に答える 7

3

いくつかの基本的なインターフェイスをモデル化することから始めます (GUI の意味ではなく、OOP の意味で)。入力のコレクションと単一の出力を受け入れるノードがあるように思えます。データ型の広さについては何も示していませんが、入力/出力を表す適切な方法が必要になるでしょう。最初の目標の場合、これは整数になる可能性があります。

一般的な C スタイルの OOP 言語では (意味があるといいのですが):

class Node<T> {
    Node<T>[] inputs;
    T eval();
}

class AdderNode extends Node<int> {
    int eval() {
        int accum = 0;
        for (inputs : i)
            accum += i.eval();
        return i;
    }
}

class ConstNode<int I> extends Node<int> {
    int eval() { return I; }
}

AdderNode a;
a.inputs.add(ConstNode<2>());
a.inputs.add(ConstNode<3>());
a.eval();

int を抽象クラス、ジェネリック、またはインターフェイスに置き換えることで、これを拡張できます。もちろん、実際の実装は実際の言語によって異なります。

于 2009-03-14T05:38:55.460 に答える
2

興味深い操作をモデル化することから始めます。最終的にそれらを UI に接続しますが、それはハンドルとアクセルであり、エンジンではありません。

作成しようとしているものは、変数、値、型、式、評価など、プログラミング言語と多くの共通点があります。多くのメタファーは適用可能であり、何らかのガイダンスを提供する可能性があります。

.NET 3.5 を使用している場合は、実行時にコード式を表現およびコンパイルできる式ツリーのオプションがあります。

たとえば、最初の目標をモデル化するには:

using System.Linq.Expressions;

ConstantExpression theNumber2 = Expression.Constant(2);
ConstantExpression theNumber3 = Expression.Constant(3);

BinaryExpression add2And3 = Expression.Add(theNumber2, theNumber3);

式を呼び出すにはadd2And3、メソッドでラップする必要があります。これは、ラムダ式で行われます。

Expression<Func<int>> add2And3Lambda = Expression.Lambda<Func<int>>(add2And3);

Func<int>パラメータを取らず、 を返すメソッドを表しますint。C# では、 で表されるコードは次のadd2And3Lambdaようになります。

() => 2 + 3

つまり、ルートがメソッドである式ツリーです。メソッドはcallableであるため、ツリーを基になるデリゲート型のインスタンスにコンパイルできます。

Func<int> add2And3Func = add2And3Lambda.Compile();

これで、作成したコードを呼び出すことができます。

int theNumber5 = add2And3Func();

.NET 言語で使用できるすべての式がサポートされています。

グラフ内のすべてのノードに がExpression関連付けられていると想像してください。これにより、式ツリーの威力と、このタスクにどのように役立つかについてのアイデアが得られるかもしれません。

于 2009-03-14T06:32:34.660 に答える
1

これらすべてのノード システムには、関数型プログラミング言語を記述しているという共通点があります。関数は、その設計目的に関係なく、複数のパラメーターを取り、単一の結果を返します。いくつかの例:

  • グラフィック: ぼかし(画像、カーネル、半径) -> 画像

  • 数学: Add(Number, Number) -> Number

  • リレーショナル: フィルター (テーブル、述語) -> テーブル

Func<object[], object>基本的には、 (C#)のような関数シグネチャになります。

ノードシステムを永続化する方法の問題に直面します。ノードの結果を他の 1 つのノード (ツリー) または複数のノード (グラフ) でパラメータとして使用できるようにしますか?

ツリーの例では、パラメーターを子ノードに直接設定します。

Add(
  Multiply(
    Constant(5),
    Constant(4)
  ),
  Multiply(
    Constant(5),
    Constant(3)
  )
)

グラフの例。すべてのノードをリストに格納し、参照のみを使用します。

A := Constant(5)
B := Constant(4)
C := Constant(3)

D := Func(Multiply, A, B)
E := Func(Multiply, A, C)

F := Func(Add, D, E)
于 2009-03-14T09:45:37.753 に答える
1

Cocoa でこのようなインターフェースを実装する際に役立つ情報をいくつか見つけました。

于 2009-05-23T18:37:02.720 に答える
0

多分bwiseには何か興味がありますか?

このページの下半分には、bwise を使用して 2 つの数値を入力として受け取る乗算ブロックを作成する例が示されています。

于 2009-05-13T21:15:43.947 に答える