2011-04-13 13 views
9

में सोचें मैं कुछ सालों से कोडिंग कर रहा हूं लेकिन मुझे अभी भी छद्म कोडिंग का लटका नहीं मिला है या वास्तव में कोड में चीजों को अभी तक नहीं सोच रहा है। इस समस्या के कारण, मुझे एक निर्णय निर्णय वृक्ष बनाने में क्या करना है, यह समझने में परेशानी हो रही है।सी ++ निर्णय वृक्ष कार्यान्वयन प्रश्न: कोड

यहाँ कुछ साइटों है कि मैं पर ध्यान दिया है कर रहे हैं और मुझ पर भरोसा वहाँ बहुत सारे थे अधिक

Decision Tree Tutorials

DMS Tutorials

साथ इस तरह के खेल जिसमें शामिल है के लिए इयान Millington के ऐ के रूप में कई पुस्तकों के साथ निर्णय कार्यक्रमों में प्रयोग किए जाने वाले विभिन्न सीखने वाले एल्गोरिदम का एक सभ्य रन-डाउन और गेम प्रोग्रामिंग के लिए व्यवहारिक गणित जो मूल रूप से निर्णय पेड़ और सिद्धांत के बारे में है। मैं एंट्रॉपी, आईडी 3 के साथ एक निर्णय पेड़ की अवधारणाओं को समझता हूं और आनुवंशिक एल्गोरिदम को कैसे जोड़ता हूं और निर्णय लेने वाला पेड़ जीए के लिए नोड्स का निर्णय लेता है। वे अच्छी अंतर्दृष्टि देते हैं, लेकिन वास्तव में मैं जो खोज रहा हूं वह नहीं।

मेरे पास कुछ बुनियादी कोड है जो निर्णय पेड़ के लिए नोड बनाता है, और मेरा मानना ​​है कि मुझे पता है कि वास्तविक तर्क को कैसे कार्यान्वित किया जाए, लेकिन इसका कोई उपयोग नहीं है यदि मेरे पास प्रोग्राम का कोई उद्देश्य नहीं है या एंट्रॉपी या सीखना है एल्गोरिदम शामिल है।

मैं जो पूछ रहा हूं वह है, क्या कोई मुझे यह जानने में मदद कर सकता है कि मुझे यह सीखने का निर्णय पेड़ बनाने के लिए क्या करना है। मेरे पेड़ बनाने के लिए कार्यों के माध्यम से अपने स्वयं के एक वर्ग में मेरे नोड्स हैं, लेकिन मैं इसमें प्रवेश कैसे लगाऊंगा और इसमें एक वर्ग होना चाहिए, एक संरचना है, मुझे यकीन नहीं है कि इसे एक साथ कैसे रखा जाए। छद्म कोड और एक विचार जहां मैं इस सिद्धांत और संख्याओं के साथ जा रहा हूं। मैं कोड को एक साथ रख सकता हूं अगर केवल मुझे पता था कि मुझे कोड के लिए क्या चाहिए। किसी भी मार्गदर्शन की सराहना की जाएगी।

मैं इसके बारे में मूल रूप से कैसे जाऊंगा।

आईडी 3 और एंट्रॉपी जैसे सीखने वाले एल्गोरिदम जोड़ना। इसे कैसे स्थापित किया जाना चाहिए?

एक बार जब मुझे यह पता चला कि इस सब के बारे में कैसे जाना है, तो मैं इसे एक राज्य मशीन में लागू करने की योजना बना रहा हूं जो गेम/सिमुलेशन प्रारूप में विभिन्न राज्यों के माध्यम से जाता है। यह सब पहले से ही स्थापित है, मुझे लगता है कि यह अकेला हो सकता है और एक बार जब मैं इसे समझता हूं तो मैं इसे अन्य परियोजना में ले जा सकता हूं।

यहां मेरे लिए स्रोत कोड है।

अग्रिम धन्यवाद!

main.cpp:

int main() 
{ 
    //create the new decision tree object 
    DecisionTree* NewTree = new DecisionTree(); 

    //add root node the very first 'Question' or decision to be made 
    //is monster health greater than player health? 
    NewTree->CreateRootNode(1); 

    //add nodes depending on decisions 
    //2nd decision to be made 
    //is monster strength greater than player strength? 
    NewTree->AddNode1(1, 2); 

    //3rd decision 
    //is the monster closer than home base? 
    NewTree->AddNode2(1, 3); 

    //depending on the weights of all three decisions, will return certain node result 
    //results! 
    //Run, Attack, 
    NewTree->AddNode1(2, 4); 
    NewTree->AddNode2(2, 5); 
    NewTree->AddNode1(3, 6); 
    NewTree->AddNode2(3, 7); 

    //Others: Run to Base ++ Strength, Surrender Monster/Player, 
    //needs to be made recursive, that way when strength++ it affects decisions second time around DT 

    //display information after creating all the nodes 
    //display the entire tree, i want to make it look like the actual diagram! 
    NewTree->Output(); 

    //ask/answer question decision making process 
    NewTree->Query(); 

    cout << "Decision Made. Press Any Key To Quit." << endl; 

    //pause quit, oh wait how did you do that again...look it up and put here 

    //release memory! 
    delete NewTree; 

    //return random value 
    //return 1; 
} 

निर्णय Tree.h:

//the decision tree class 
class DecisionTree 
{ 
public: 
    //functions 
    void RemoveNode(TreeNodes* node); 
    void DisplayTree(TreeNodes* CurrentNode); 
    void Output(); 
    void Query(); 
    void QueryTree(TreeNodes* rootNode); 
    void AddNode1(int ExistingNodeID, int NewNodeID); 
    void AddNode2(int ExistingNodeID, int NewNodeID); 
    void CreateRootNode(int NodeID); 
    void MakeDecision(TreeNodes* node); 

    bool SearchAddNode1(TreeNodes* CurrentNode, int ExistingNodeID, int NewNodeID); 
    bool SearchAddNode2(TreeNodes* CurrentNode, int ExistingNodeID, int NewNodeID); 

    TreeNodes* m_RootNode; 

    DecisionTree(); 

    virtual ~DecisionTree(); 
}; 

Decisions.cpp:

+०१२३५१६४१०
int random(int upperLimit); 

//for random variables that will effect decisions/node values/weights 
int random(int upperLimit) 
{ 
    int randNum = rand() % upperLimit; 
    return randNum; 
} 

//constructor 
//Step 1! 
DecisionTree::DecisionTree() 
{ 
    //set root node to null on tree creation 
    //beginning of tree creation 
    m_RootNode = NULL; 
} 

//destructor 
//Final Step in a sense 
DecisionTree::~DecisionTree() 
{ 
    RemoveNode(m_RootNode); 
} 

//Step 2! 
void DecisionTree::CreateRootNode(int NodeID) 
{ 
    //create root node with specific ID 
    // In MO, you may want to use thestatic creation of IDs like with entities. depends on how many nodes you plan to have 
    //or have instantaneously created nodes/changing nodes 
    m_RootNode = new TreeNodes(NodeID); 
} 

//Step 5.1!~ 
void DecisionTree::AddNode1(int ExistingNodeID, int NewNodeID) 
{ 
    //check to make sure you have a root node. can't add another node without a root node 
    if(m_RootNode == NULL) 
    { 
     cout << "ERROR - No Root Node"; 
     return; 
    } 

    if(SearchAddNode1(m_RootNode, ExistingNodeID, NewNodeID)) 
    { 
     cout << "Added Node Type1 With ID " << NewNodeID << " onto Branch Level " << ExistingNodeID << endl; 
    } 
    else 
    { 
     //check 
     cout << "Node: " << ExistingNodeID << " Not Found."; 
    } 
} 

//Step 6.1!~ search and add new node to current node 
bool DecisionTree::SearchAddNode1(TreeNodes *CurrentNode, int ExistingNodeID, int NewNodeID) 
{ 
    //if there is a node 
    if(CurrentNode->m_NodeID == ExistingNodeID) 
    { 
     //create the node 
     if(CurrentNode->NewBranch1 == NULL) 
     { 
      CurrentNode->NewBranch1 = new TreeNodes(NewNodeID); 
     } 
     else 
     { 
      CurrentNode->NewBranch1 = new TreeNodes(NewNodeID); 
     } 
     return true; 
    } 
    else 
    { 
     //try branch if it exists 
     //for a third, add another one of these too! 
     if(CurrentNode->NewBranch1 != NULL) 
     { 
      if(SearchAddNode1(CurrentNode->NewBranch1, ExistingNodeID, NewNodeID)) 
      { 
       return true; 
      } 
      else 
      { 
       //try second branch if it exists 
       if(CurrentNode->NewBranch2 != NULL) 
       { 
        return(SearchAddNode2(CurrentNode->NewBranch2, ExistingNodeID, NewNodeID)); 
       } 
       else 
       { 
        return false; 
       } 
      } 
     } 
     return false; 
    } 
} 

//Step 5.2!~ does same thing as node 1. if you wanted to have more decisions, 
//create a node 3 which would be the same as this maybe with small differences 
void DecisionTree::AddNode2(int ExistingNodeID, int NewNodeID) 
{ 
    if(m_RootNode == NULL) 
    { 
     cout << "ERROR - No Root Node"; 
    } 

    if(SearchAddNode2(m_RootNode, ExistingNodeID, NewNodeID)) 
    { 
     cout << "Added Node Type2 With ID " << NewNodeID << " onto Branch Level " << ExistingNodeID << endl; 
    } 
    else 
    { 
     cout << "Node: " << ExistingNodeID << " Not Found."; 
    } 
} 

//Step 6.2!~ search and add new node to current node 
//as stated earlier, make one for 3rd node if there was meant to be one 
bool DecisionTree::SearchAddNode2(TreeNodes *CurrentNode, int ExistingNodeID, int NewNodeID) 
{ 
    if(CurrentNode->m_NodeID == ExistingNodeID) 
    { 
     //create the node 
     if(CurrentNode->NewBranch2 == NULL) 
     { 
      CurrentNode->NewBranch2 = new TreeNodes(NewNodeID); 
     } 
     else 
     { 
      CurrentNode->NewBranch2 = new TreeNodes(NewNodeID); 
     } 
     return true; 
    } 
    else 
    { 
     //try branch if it exists 
     if(CurrentNode->NewBranch1 != NULL) 
     { 
      if(SearchAddNode2(CurrentNode->NewBranch1, ExistingNodeID, NewNodeID)) 
      { 
       return true; 
      } 
      else 
      { 
       //try second branch if it exists 
       if(CurrentNode->NewBranch2 != NULL) 
       { 
        return(SearchAddNode2(CurrentNode->NewBranch2, ExistingNodeID, NewNodeID)); 
       } 
       else 
       { 
        return false; 
       } 
      } 
     } 
     return false; 
    } 
} 

//Step 11 
void DecisionTree::QueryTree(TreeNodes* CurrentNode) 
{ 
    if(CurrentNode->NewBranch1 == NULL) 
    { 
     //if both branches are null, tree is at a decision outcome state 
     if(CurrentNode->NewBranch2 == NULL) 
     { 
      //output decision 'question' 
      /////////////////////////////////////////////////////////////////////////////////////// 
     } 
     else 
     { 
      cout << "Missing Branch 1"; 
     } 
     return; 
    } 
    if(CurrentNode->NewBranch2 == NULL) 
    { 
     cout << "Missing Branch 2"; 
     return; 
    } 

    //otherwise test decisions at current node 
    MakeDecision(CurrentNode); 
} 

//Step 10 
void DecisionTree::Query() 
{ 
    QueryTree(m_RootNode); 
} 

//////////////////////////////////////////////////////////// 
//debate decisions create new function for decision logic 

// cout << node->stringforquestion; 

//Step 12 
void DecisionTree::MakeDecision(TreeNodes *node) 
{ 
    //should I declare variables here or inside of decisions.h 
    int PHealth; 
    int MHealth; 
    int PStrength; 
    int MStrength; 
    int DistanceFBase; 
    int DistanceFMonster; 

    ////sets random! 
    srand(time(NULL)); 

    //randomly create the numbers for health, strength and distance for each variable 
    PHealth = random(60); 
    MHealth = random(60); 
    PStrength = random(50); 
    MStrength = random(50); 
    DistanceFBase = random(75); 
    DistanceFMonster = random(75); 

    //the decision to be made string example: Player health: Monster Health: player health is lower/higher 
    cout << "Player Health: " << PHealth << endl; 
    cout << "Monster Health: " << MHealth << endl; 
    cout << "Player Strength: " << PStrength << endl; 
    cout << "Monster Strength: " << MStrength << endl; 
    cout << "Distance Player is From Base: " << DistanceFBase << endl; 
    cout << "Disntace Player is From Monster: " << DistanceFMonster << endl; 

    //MH > PH 
    //MH < PH 
    //PS > MS 
    //PS > MS 
    //DB > DM 
    //DB < DM 

    //good place to break off into different decision nodes, not just 'binary' 

    //if statement lower/higher query respective branch 
    if(PHealth > MHealth) 
    { 
    } 
    else 
    { 
    } 
    //re-do question for next branch. Player strength: Monster strength: Player strength is lower/higher 
    //if statement lower/higher query respective branch 
    if(PStrength > MStrength) 
    { 
    } 
    else 
    { 
    } 

    //recursive question for next branch. Player distance from base/monster. 
    if(DistanceFBase > DistanceFMonster) 
    { 
    } 
    else 
    { 
    } 
    //DECISION WOULD BE MADE 
    //if statement? 
    // inside query output decision? 
    //cout << << 

     //QueryTree(node->NewBranch2); 

     //MakeDecision(node); 
} 

//Step.....8ish? 
void DecisionTree::Output() 
{ 
    //take repsective node 
    DisplayTree(m_RootNode); 
} 

//Step 9 
void DecisionTree::DisplayTree(TreeNodes* CurrentNode) 
{ 
    //if it doesn't exist, don't display of course 
    if(CurrentNode == NULL) 
    { 
     return; 
    } 

    ////////////////////////////////////////////////////////////////////////////////////////////////// 
    //need to make a string to display for each branch 
    cout << "Node ID " << CurrentNode->m_NodeID << "Decision Display: " << endl; 

    //go down branch 1 
    DisplayTree(CurrentNode->NewBranch1); 

    //go down branch 2 
    DisplayTree(CurrentNode->NewBranch2); 
} 

//Final step at least in this case. A way to Delete node from tree. Can't think of a way to use it yet but i know it's needed 
void DecisionTree::RemoveNode(TreeNodes *node) 
{ 
    //could probably even make it to where you delete a specific node by using it's ID 
    if(node != NULL) 
    { 
     if(node->NewBranch1 != NULL) 
     { 
      RemoveNode(node->NewBranch1); 
     } 

     if(node->NewBranch2 != NULL) 
     { 
      RemoveNode(node->NewBranch2); 
     } 

     cout << "Deleting Node" << node->m_NodeID << endl; 

     //delete node from memory 
     delete node; 
     //reset node 
     node = NULL; 
    } 
} 

ट्री नोड्स।ज:

using namespace std; 
//tree node class 
class TreeNodes 
{ 
public: 
    //tree node functions 
    TreeNodes(int nodeID/*, string QA*/); 
    TreeNodes(); 

    virtual ~TreeNodes(); 

    int m_NodeID; 

    TreeNodes* NewBranch1; 
    TreeNodes* NewBranch2; 
}; 

TreeNodes.cpp:

//contrctor 
TreeNodes::TreeNodes() 
{ 
    NewBranch1 = NULL; 
    NewBranch2 = NULL; 

    m_NodeID = 0; 
} 

//deconstructor 
TreeNodes::~TreeNodes() 
{ } 

//Step 3! Also step 7 hah! 
TreeNodes::TreeNodes(int nodeID/*, string NQA*/) 
{ 
    //create tree node with a specific node ID 
    m_NodeID = nodeID; 

    //reset nodes/make sure! that they are null. I wont have any funny business #s -_- 
    NewBranch1 = NULL; 
    NewBranch2 = NULL; 
} 
+1

कुछ कोड के साथ हर स्तर पर नोड्स स्टोर करने के लिए होगा का अनुसरण करता है अच्छा सवाल है, तो मैं ऊपर उठाया। आप जिस लाइब्रेरी को लाइब्रेरी प्राप्त करने की कोशिश कर रहे हैं उसके आधार पर जो आपको सी ++ में कुछ तर्क प्रोग्रामिंग प्रतिमानों को लागू करने की अनुमति देता है, वह मूल रूप से ब्याज का हो सकता है। http://www.mpprogramming.com/cpp/ – shuttle87

+19

अच्छा भगवान है कि यादृच्छिक स्वयंसेवकों को पढ़ने के लिए बहुत सारे कोड हैं ... – ildjarn

+0

याहू, लेकिन यह दिखाता है कि मुझे पता है कि मैं एक अर्थ में क्या कर रहा हूं। मैंने जिन प्रश्नों को देखा उनमें से कई के पास जाने के लिए पर्याप्त नहीं था या उन्होंने यह नहीं दिखाया कि उन्होंने काम किया है। मैंने काम किया! haha। मुझे उम्मीद है कि कई लोग इस बात को समझने के लिए कि क्या हो रहा है, समझने के लिए। – CodingImagination

उत्तर

1

कृपया मुझे ठीक कर लें मैं गलत हूँ लेकिन http://dms.irb.hr/tutorial/tut_dtrees.php और http://www.decisiontrees.net/?q=node/21 पर छवियों से पहचानने वास्तविक निर्णय तर्क में जाना चाहिए पेड़ में नहीं, नोड्स। आप मॉडल कर सकते हैं कि पॉलिमॉर्फिक नोड्स होने के कारण, प्रत्येक निर्णय के लिए एक बनाया जाना है। पेड़ निर्माण में थोड़ा बदलाव और निर्णय प्रतिनिधिमंडल के लिए मामूली मामूली संशोधन के साथ आपका कोड ठीक होना चाहिए।

1

असल में आपको सब कुछ चरणों में तोड़ने की जरूरत है और फिर एल्गोरिदम के प्रत्येक भाग को मॉड्यूलर करने की आवश्यकता है जिसे आप कार्यान्वित करने का प्रयास कर रहे हैं।

आप इसे स्यूडो कोड में या कोड/स्क्वांस और स्टब्स का उपयोग करके स्वयं कोड में कर सकते हैं।

एल्गोरिदम के प्रत्येक भाग में आप कुछ फ़ंक्शन में कोड कर सकते हैं और इसे एक साथ जोड़ने से पहले उस फ़ंक्शन का परीक्षण भी कर सकते हैं। आप मूल रूप से एल्गोरिदम कार्यान्वयन में विशिष्ट उद्देश्यों के लिए उपयोग किए जाने वाले विभिन्न कार्यों या कक्षाओं के साथ समाप्त हो जाएंगे। तो पेड़ निर्माण के लिए आपके मामले में आपके पास एक ऐसा कार्य होगा जो एक नोड पर एन्ट्रॉपी की गणना करता है, दूसरा जो डेटा को प्रत्येक नोड पर सबसेट में विभाजित करता है, आदि

मैं सामान्य मामले में विशेष रूप से सम्मान के बजाय यहां बात कर रहा हूं निर्णय पेड़ निर्माण। मिशेल द्वारा मशीन लर्निंग पर पुस्तक देखें यदि आपको निर्णय पेड़ एल्गोरिदम और इसमें शामिल कदमों पर विशिष्ट जानकारी की आवश्यकता है।

0

स्यूडोकोड लागू करने के लिए एक निर्णय पेड़ के रूप में

createdecisiontree(data, attributes) 

Select the attribute a with the highest information gain 

for each value v of the attribute a 

    Create subset of data where data.a.val==v (call it data2) 

    Remove the attribute a from the attribute list resulting in attribute_list2 

    Call CreateDecisionTree(data2, attribute_list2) 

आप की तरह

decisiontree [attr] [वैल] = new_node

संबंधित मुद्दे