2009-03-14 40 views
21

Tôi muốn thực hiện một đầu mối giao diện, cơ bản là một DAG nơi mỗi nút thực hiện một thao tác trên đó là các kết nối đầu vào, và đầu ra một cái gì đó (mà bạn có thể kết nối tới nút khác)Thực hiện giao diện đồ họa dựa trên nút?

Một số ứng dụng ví dụ:


Là một mục tiêu đầu tiên, tôi muốn có một ứng dụng đồ họa chỉ với 2 nút. Một "số" chỉ đơn giản xuất ra một số cố định và nút "Thêm", có hai đầu vào và đầu ra là tổng của hai số.

Khi mọi người đã trả lời cái đến nay, tôi có một ý tưởng sơ bộ như thế nào để đại diện cho dữ liệu trong mã, ví dụ như trong Python'y tìm pseudo-code:

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

Làm thế nào tôi sẽ nhận được về gói một GUI tùy chỉnh xung quanh điều này? Một cái gì đó như sau, nhưng hơi ít vẽ tay!

nodal UI mockup

Tôi sẽ bắt đầu ở đâu? Tôi hiện đang có kế hoạch viết nó trong Objective-C/Cocoa, mặc dù tôi không chỉ đề xuất cho các ngôn ngữ khác.

Trả lời

4

Tôi sẽ bắt đầu bằng cách lập mô hình một số giao diện cơ bản (theo nghĩa OOP, không phải là ý nghĩa GUI). Dường như với tôi bạn sẽ có một Node mà sẽ chấp nhận một bộ sưu tập các đầu vào và một đầu ra duy nhất. Bạn đã không đưa ra bất kỳ dấu hiệu nào về mức độ rộng của các kiểu dữ liệu, nhưng bạn sẽ muốn một số phương thức phù hợp để trình bày các đầu vào/đầu ra của bạn. Đối với mục tiêu đầu tiên của bạn, điều này có thể là một số nguyên.

Trong một số ngôn ngữ OOP C phong cách chung chung (hy vọng nó làm cho tinh thần):

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

Bạn có thể mở rộng về vấn đề này bằng cách thay thế int với một số trừu tượng lớp, chung chung, hoặc giao diện. Thực tế thực tế sẽ khác nhau dựa trên ngôn ngữ thực tế, tất nhiên.

1

Tôi sẽ bắt đầu với mô hình hóa các hoạt động thú vị. Cuối cùng, bạn sẽ kết nối chúng với một giao diện người dùng, nhưng đó là vô-lăng và bàn đạp ga, chứ không phải động cơ.

Những gì bạn đang cố gắng xây dựng có nhiều điểm chung với ngôn ngữ lập trình: biến, giá trị, loại, biểu thức, đánh giá, v.v. Nhiều ẩn dụ có thể áp dụng và có thể cung cấp một số hướng dẫn.

Nếu bạn đang sử dụng .NET 3.5, bạn có tùy chọn Expression Trees, cho phép bạn trình bày và biên dịch các biểu thức mã khi chạy.

Ví dụ, để mô hình mục tiêu đầu tiên của bạn:

using System.Linq.Expressions; 

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

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

Để gọi biểu thức, chúng ta cần phải quấn add2And3 với một phương pháp. Này được thực hiện với một biểu thức lambda:

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

Func<int> đại diện cho một phương pháp mà mất không tham số và trả về một int. Trong C#, mã đại diện bởi add2And3Lambda sẽ là:

() => 2 + 3 

Vì vậy, những gì chúng ta có là một cây biểu thức có gốc là một phương pháp. Bởi vì một phương pháp là callable, chúng tôi có thể biên dịch các cây thành một thể hiện của loại đại biểu cơ bản:

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

Bây giờ chúng ta có thể gọi mã chúng tôi xây dựng:

int theNumber5 = add2And3Func(); 

Mỗi biểu hiện sẵn sàng. Ngôn ngữ NET được hỗ trợ.

Hãy tưởng tượng mọi nút trong biểu đồ của bạn có Expression được liên kết với nó. Điều đó có thể cung cấp cho bạn một ý tưởng về sức mạnh của cây biểu thức và cách họ có thể giúp bạn với nhiệm vụ này.

1

Tất cả các hệ thống nút đó có điểm chung là chúng mô tả ngôn ngữ lập trình hàm. Một hàm nhận nhiều tham số và trả về một kết quả duy nhất, bất kể mục đích gì được thiết kế. Một số ví dụ:

  • Graphics: Blur (Hình ảnh, Kernel, Radius) -> Hình ảnh

  • Math: Thêm (Number, Số) -> Số

  • Relational: Lọc (Bảng, Predicate) -> Bảng

Về cơ bản, có chữ ký chức năng như Func<object[], object> (C#).

Bạn sẽ phải đối mặt với câu hỏi về cách làm cho hệ thống nút của bạn liên tục. Bạn có muốn làm cho kết quả của một nút có thể sử dụng làm tham số chỉ bằng một nút khác (cây) hoặc bởi nhiều nút (biểu đồ) không?

Ví dụ về một cây, trực tiếp có các thông số một đứa trẻ nút:

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

Ví dụ về một đồ thị, lưu trữ tất cả các nút trong một danh sách và chỉ sử dụng tài liệu tham khảo:

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

lẽ bwise có một cái gì đó quan tâm?

Trên nửa dưới của this page hiển thị ví dụ về sử dụng bwise để tạo khối nhân có hai số làm đầu vào.

1

Tôi tìm thấy một số thông tin hữu ích về việc thực hiện một giao diện như vậy trong Cocoa:

0

Tôi thực hiện một Graph Thực hiện như bạn mô tả trong dự án này: GRSFramework

Các mã nguồn có thể được tìm thấy here.

Hiện tại tôi đang làm việc để phát hành một phiên bản tốt hơn, được làm sạch của hệ thống này trong dự án ExecutionGraph.
Bạn cũng có thể quan tâm đến bạn.

Sau đó, cũng là thư viện TensorFlow từ Google trong đó có một hệ thống tương tự được thực hiện TensorFlow

0

tôi stumbled khi chủ đề này trong khi nghiên cứu một giải pháp tương tự. Gần đây tôi tìm thấy một dự án tốt đẹp trên github https://github.com/nodebox/nodebox mà dường như chính xác những gì bạn đang tìm kiếm. Ít nhất một người có thể trích xuất và áp dụng các thành phần biên tập từ dự án.

Kính trọng, Stephan

+0

Chào mừng bạn đến StackOverflow, cảm ơn vì muốn đóng góp nhưng câu trả lời với các liên kết chỉ được khuyến khích. Vui lòng xem lại [nguyên tắc trả lời] (https://stackoverflow.com/help/how-to-answer). Nguyên tắc chung là xem xét câu trả lời của bạn mà không có liên kết và nếu nó cung cấp ít hoặc không có giá trị, hãy xem xét mở rộng. – JaredMcAteer

Các vấn đề liên quan