2009-03-14 13 views
21

Vorrei implementare un nodale interfaccia, fondamentalmente un DAG cui ogni nodo esegue un'operazione sul suo connessioni di ingresso ed emette qualcosa (quale si può collegare ad un altro nodo)Implementazione di un'interfaccia grafica basata su nodo?

Alcuni esempi di applicazioni:


Come primo obiettivo, vorrei avere un'applicazione graficacon solo 2 nodi. Un "numero" che emette semplicemente un numero fisso e un nodo "Aggiungi", che prende due input e restituisce la somma dei due.

Dato che le persone hanno risposto so-far, ho una vaga idea di come rappresentare i dati in codice, ad esempio in Python'y cercando pseudo-codice:

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() 

Come avrei ottenuto circa wrapping una GUI personalizzata attorno a questo? Qualcosa come il seguente, ma leggermente meno disegnato a mano!

nodal UI mockup

Dove vorrei cominciare? Attualmente sto pianificando di scriverlo in Objective-C/Cocoa, anche se sono più che aperto a suggerimenti per altre lingue.

risposta

4

Vorrei iniziare modellando alcune interfacce di base (nel senso OOP, non nel senso della GUI). Mi sembra che avrai un Nodo che accetterà una collezione di input e un singolo output. Non hai dato alcuna indicazione su quanto siano ampi i tipi di dati, ma ti servirà un metodo adeguato per rappresentare i tuoi input/output. Per il tuo primo obiettivo, questo potrebbe essere un numero intero.

in qualche linguaggio OOP stile C generica (spero che abbia senso):

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(); 

Si potrebbe espandere su questo, sostituendo int con una certa classe astratta, generica, o interfaccia. L'effettiva implementazione varierà in base alla lingua effettiva, ovviamente.

1

Vorrei iniziare con la modellazione delle operazioni interessanti. Alla fine li collegherete a un'interfaccia utente, ma quello è il volante e il pedale del gas, non il motore.

Quello che stai tentando di costruire ha molto in comune con i linguaggi di programmazione: variabili, valori, tipi, espressioni, valutazione, ecc. Molte metafore sono applicabili e potrebbero fornire alcune indicazioni.

Se si utilizza .NET 3.5, è disponibile l'opzione Expression Trees, che consente di rappresentare e compilare le espressioni di codice in fase di esecuzione.

Ad esempio, per modellare il vostro primo obiettivo:

using System.Linq.Expressions; 

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

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

Per richiamare l'espressione, abbiamo bisogno di avvolgere add2And3 con un metodo. Ciò viene fatto con un'espressione lambda:

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

Func<int> rappresenta un metodo che non accetta parametri e restituisce un int. In C#, il codice rappresentato da add2And3Lambda sarebbe:

() => 2 + 3 

Quindi quello che abbiamo è un albero di espressione la cui radice è un metodo. Perché un metodo è callable, siamo in grado di compilare l'albero in un'istanza del tipo delegato sottostante:

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

Ora possiamo invocare il codice che abbiamo costruito:

int theNumber5 = add2And3Func(); 

Ogni espressione a disposizione. Le lingue NET sono supportate.

Immaginate che ogni nodo del vostro grafico abbia un Expression associato. Questo potrebbe darti un'idea del potere degli alberi di espressione e di come potrebbero aiutarti in questo compito.

1

Tutti i sistemi di nodi hanno in comune il fatto di descrivere un linguaggio di programmazione funzionale. Una funzione accetta più parametri e restituisce un singolo risultato, indipendentemente dal motivo per cui è stato progettato. Alcuni esempi:

  • Graphics: Blur (Immagine, Kernel, Raggio) -> Immagine

  • Math: Aggiungere (Number, numero) -> Numero

  • relazionale: Filtro (tabella, predicate) -> Tabella

sostanza che si riduce a una firma di funzione come Func<object[], object> (C#).

Affronterai la domanda su come rendere persistente il tuo sistema di nodi. Vuoi rendere il risultato di un nodo utilizzabile come parametro solo da un altro nodo (albero) o da più nodi (grafico)?

Esempio di un albero, hanno direttamente i parametri di un bambino nodi:

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

Esempio di un grafico, memorizzare tutti i nodi in un elenco e utilizzare solo i riferimenti:

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

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

F := Func(Add, D, E) 
0

Forse bwise ha qualcosa di interessante?

Nella metà inferiore di this page viene mostrato un esempio dell'utilizzo di bwise per creare un blocco di moltiplicazione che prende due numeri come input.

1

ho trovato alcune informazioni utili per l'attuazione di una tale interfaccia a Cocoa:

0

ho implementato un grafico di esecuzione, come si descrive in questo progetto: GRSFramework

Il codice sorgente può essere trovato here.

Attualmente sto lavorando per rilasciare una versione migliore e pulita di questo sistema nel progetto ExecutionGraph.
Potrebbe essere di interesse anche per te.

poi c'è anche la biblioteca tensorflow da Google che ha un sistema simile implementato TensorFlow

0

sono incappato in questa discussione, mentre la ricerca di una soluzione simile. Recentemente ho trovato un bel progetto su github https://github.com/nodebox/nodebox che sembra essere esattamente quello che stai cercando. Almeno uno poteva estrarre e adottare i componenti dell'editor dal progetto.

saluti, Stephan

+0

Benvenuti a StackOverflow, grazie per voler contribuire, ma risposte con collegamenti solo sono scoraggiati. Consulta le [linee guida per la risposta] (https://stackoverflow.com/help/how-to-answer). Una buona regola è quella di guardare la tua risposta senza il link e se fornisce poco o nessun valore, considera l'espansione. – JaredMcAteer

Problemi correlati