2011-12-03 15 views
7

Tôi đang tìm cách tốt hơn để triển khai cây quyết định trong javascript. Là rất mới để lập trình tôi có một số lượng rất hạn chế các công cụ trong hộp công cụ của tôi. Cách duy nhất tôi biết để làm điều này là: . Với một khó khăn rất lớn xấu để duy trì và làm theo nếu người khác nếu tuyên bố . Tôi có thể sử dụng một chuyển đổi/trường hợp tuyên bố và làm một điều loại máy nhà nước.Cách triển khai cây quyết định trong javascript. Tìm kiếm một giải pháp tốt hơn so với những người xấu xí của tôi

Đề xuất và lý thuyết được đánh giá cao. Ngoài ra, các ví dụ mã nhỏ sẽ rất hữu ích. Cảm ơn đã dành một cái nhìn.

Dale

+0

Là một cây quyết định chỉ là một sơ đồ cấu trúc đặc biệt? – Dale

Trả lời

10

Nếu nó là một cây thực sự lớn, và đặc biệt nếu nó được tạo ra từ dữ liệu, bạn có thể xử lý các chức năng quyết định như dữ liệu, sử dụng một phương pháp chức năng. Ví dụ:

var decisionTree = 
    new Case(true, Array(
        new Case (function(n){ return n < 0; }, Math.sin), 
        new Case (function(n){ return n < 2; }, "0<= n < 2"), 
        new Case (true, "Greater than two "))); 

decisionTree.evaluate(1); // evaluates to string "0<= n < 2" 
decisionTree.evaluate(-Math.PI/2); // evaluates to -1 
decisionTree.evaluate(5); // evaluates to string "Greater than two" 

dùng thực hiện điều này, bạn có thể tùy tiện tổ cây của bạn:

// Represents a predicate and corresponding action to take if predicate is a 
// match. 
// 
// predicate : true or Function(object) returning a boolean. 
// 
// action : One of Function, Case, Array of Cases or other value (see 
//   Case.evaluate as to how each is applied) 
// 
// 
Case = function (predicate, action) { 
    this.predicate = predicate; 
    this.action = action; 
}; 


Case.prototype = { 
    nomatch : { match : false }, 
    match : function (v) { return { match : true, result :v }; }, 


    // Recursively test Cases and applies corresponding action on 
    // `object`. 
    // 
    // The action applied depends on the datatype of `action`: 
    // 
    // - Function : evaluates to `action(object)` 
    // 
    // - Case : A subsequent test is performed. Evaluates to whatever 
    //   the Cases action evaluates to. 
    //   
    // - Array of Cases : Subsequent tests are performed. Evaluates to whatever 
    //   the action of the first matching Case evaluates to. 
    // 
    // - Any other Value : Evaluates to itself 
    // 
    // returns object containing fields: 
    // 
    //  match: boolean, indicates if Case was a match 
    // 
    //  result: result of action applied 
    // 
    evaluate : function(object) { 
     var match = this.predicate; 

     if (match instanceof Function) 
      match = match(object); 

     if (match) { 

      if (this.action instanceof Function) 
       return this.match(this.action(object)); 

      if (this.action instanceof Case) 
       return this.action.evaluate(object); 

      if (this.action instanceof Array) { 
       var decision; 
       var result; 
       for (var c = 0; c < this.action.length; c++) { 
        decision = this.action[c]; 
        if (decision instanceof Case) { 
         result = decision.evaluate(object); 
         if (result.match) 
          return result; 
        } else throw("Array of Case expected"); 
       } 

       return this.nomatch; 
      } 

      return this.match(this.action); 
     } 
     return this.nomatch; 
    } 
}; 
+0

Điều này thật tuyệt vời! Cảm ơn. Bạn có bất kỳ ý kiến ​​về điều này từ một quan điểm hiệu suất? – Dale

+0

Tuyệt vời :) Tôi cũng tò mò làm thế nào và mức độ này sẽ được tối ưu hóa bởi thông dịch viên. – Andrei

0

Các thực hành tốt nhất cho các loại điều này là để tổ if-then báo cáo trong một cách có ý nghĩa, và sau đó đặt chúng trong các cơ quan chức năng của chính họ. Một hàm không bao giờ nên có nhiều hơn 2 lồng nhau nếu; sau đó, có thể chấp nhận đặt lồng nhau nếu trong các hàm được đặt tên và triển khai tốt, do đó trừu tượng hóa sự phức tạp của chương trình trong khi giữ lại ý nghĩa của nó đối với lập trình viên sẽ đọc mã của bạn sau khi bạn đi. :)

+0

Tôi thích câu trả lời đó. Vấn đề của tôi không phải là câu lệnh if-then. Tôi không có bất kỳ ifs lồng nhau nào. Tôi có một tuyên bố nếu (nếu khác) cho mỗi lá của cây làm điều gì đó. Vì vậy, tôi đã đặt tất cả sự phức tạp của tôi vào việc tính toán điều kiện. Có cần thiết để lồng ghép chúng và trừu tượng các hàm bên trong lồng nhau như bạn đã đề xuất không? Cảm ơn. – Dale

+1

Nó thường được mong muốn để làm tổ trừu tượng hoặc dài nếu-sau đó chuỗi khi nó không rõ ràng những gì nó làm hoặc nếu nó khó đọc. Điều này cho phép dễ đọc hơn đối với chương trình của bạn (bằng bất kỳ ngôn ngữ nào) khi các hàm nhỏ được sử dụng để trừu tượng hóa những thứ khó hiểu như các chuỗi dài nếu sau đó. Theo quy tắc chung, nếu bạn phải viết nhận xét về câu lệnh if-then cụ thể hoặc tại sao nó ở đó, tốt hơn là đặt nó vào hàm riêng của nó chứ không phải là bình luận. Đồng nghiệp của bạn sẽ cảm ơn bạn. – djhaskin987

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