如何在 JavaScript 中实现决策树。寻找比我丑陋的解决方案更好的解决方案[关闭]

Posted

技术标签:

【中文标题】如何在 JavaScript 中实现决策树。寻找比我丑陋的解决方案更好的解决方案[关闭]【英文标题】:How to implement a decision tree in javascript. Looking for a better solution than my ugly ones [closed] 【发布时间】:2012-01-12 05:06:08 【问题描述】:

我正在寻找一种在 javascript 中实现决策树的更好方法。作为编程新手,我的工具箱中的工具数量非常有限。我知道的唯一方法是: .if else if 语句很难维护和遵循一个巨大的丑陋 .我可以使用 switch/case 语句并做状态机类型的事情。

建议和理论表示赞赏。此外,小的代码示例将非常有帮助。感谢您的观看。

戴尔

【问题讨论】:

【参考方案1】:

如果它是一棵非常大的树,特别是如果它是从数据生成的,您可以使用函数方法将决策函数视为数据。例如:

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"

使用这个实现,你可以任意嵌套你的树:

// 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;
    
;

【讨论】:

【参考方案2】:

这类事情的最佳实践是以有意义的方式嵌套 if-then 语句,然后将它们放入自己的函数体中。一个函数不应该有超过 2 个嵌套的 if;之后,可以在命名和实现良好的函数中进一步嵌套 if ,从而抽象程序的复杂性,同时保留它对程序员的意义,让程序员在你离开后阅读你的代码。 :)

【讨论】:

我喜欢这个答案。我的问题不是嵌套的 if-then 语句。我没有任何嵌套的 if。对于树的每一片叶子,我都有一个 if(else if) 语句。所以我把我所有的复杂性都放在了计算条件上。嵌套它们并按照您的建议抽象函数内部的嵌套是否更可取?谢谢。 当不清楚它的作用或难以阅读时,通常需要抽象嵌套或长 if-then 链。当使用小函数来抽象难以理解的事物(例如长 if-then 链)时,这为您的程序(在任何语言中)提供了更多的可读性。根据经验,如果你必须写一个关于特定 if-then 语句的作用或它为什么存在的评论,最好将它放在它自己的命名函数中而不是评论它。你的同事会感谢你的。

以上是关于如何在 JavaScript 中实现决策树。寻找比我丑陋的解决方案更好的解决方案[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中实现交互式决策树

如何在c#中实现决策矩阵

无法使用 Accord.Net 框架实现基本决策树

如何在 RDB 中实现常规索引和复合索引?

如何使用 php 获取所有可能的决策树

如何使用 express.js 在 Ajax 调用中实现 CSRF 保护(寻找完整示例)?