void TreeNode::Tree::copyNode(const AbstractTreeIterator& nodePath, const AbstractTreeIterator& newParentPath) { if (canCopyNodes() == true) { TreeNode* treeNode = getTreeNodeFromIterator(nodePath); TreeNode* newParentNode = getTreeNodeFromIterator(newParentPath); if (treeNode != NULL && newParentNode != NULL) { TreeCloner treeCloner(treeNode, *createNodeFunctor); TreeNode* clonedTreeNode = treeCloner.buildTree(); if (clonedTreeNode != NULL) { newParentNode->addChild(clonedTreeNode); clonedTreeNode->setParent(newParentNode); } else { resultError("Can't clone the tree-node to copy!" ERROR_AT); } } else { argumentError("Need a TreeNode::Iterator to copy a node!" ERROR_AT); } } else { stateError("Tree can't remove nodes!" ERROR_AT); } }
TreeNode<int>* takeInputLWise() { int rootData; cout << "Enter root data" << endl; cin >> rootData; TreeNode<int>* root = new TreeNode<int>(rootData); queue<TreeNode<int>*> queue; queue.push(root); while (!queue.empty()) { TreeNode<int>* first = queue.front(); queue.pop(); cout << "Enter num children for " << first->getData() << endl; int numChild; cin >> numChild; for (int i = 0; i < numChild; i++) { cout << "Enter " << i << "th child of " << first->getData() << endl; int childData; cin >> childData; TreeNode<int>* child = new TreeNode<int>(childData); queue.push(child); first->addChild(child); } } return root; }
/*---------------------------------------------------------------------*//** ノード配列から作成 単純な Function 集合メニューを作成する ○ルートノード ┣●親ノード ┃┗●子ノード(Fuction) ┣●親ノード ┃┗●子ノード(Fuction) ・ ・ ・ ┗●親ノード ┗●子ノード(Fuction) ↑このような形 また、 mtnodeParentArrayEntr = NULL, mtnodeChildArrayEntr = NULL, numArray = 0 でこの create 実行した後、 getMenuTreeRootNode でルートノードを得て、 addMenuTreeNode で要素となるノードを追加する方法もある @param name 名前 @param mtnodeParentArrayEntr 親ノード配列(メモリの解放処理は Menu クラス内で行う) @param mtnodeChildArrayEntr 子ノード配列(メモリの解放処理は Menu クラス内で行う) # 親ノード配列と同配列数である必要がある # 全ての子は Function ノードである必要がある @param numArray 配列長 @param functblRef ファンクションテーブルデータ @param objParam パラメータオブジェクト @retval true 成功 @retval false 失敗 **//*---------------------------------------------------------------------*/ bool Menu::create(const CStringBase* name, MenuTreeNode** mtnodeParentArrayEntr, MenuTreeNode** mtnodeChildArrayEntr, int numArray, MenuFuncTable* functblRef, MenuPanelFactory* pnlfctryRef, void* objCreateParam) { // ツリーを作成する _tree = new Tree<MenuTreeNode>(true); // 表示対象においての根ノードを作る MenuTreeNode* mtnodeRoot = new MenuTreeNode(); if(!mtnodeRoot->create(name, false, false, false, 0, 0)) { return false; } // ノードを作成する TreeNode<MenuTreeNode>* tnode = _tree->addRootNode(); tnode = tnode->addChild(mtnodeRoot); for(int i = 0; i < numArray; i++) { // 表示される親ノードの追加 if(i == 0) { tnode = tnode->addChild(mtnodeParentArrayEntr[i]); } else { tnode = tnode->addSibling(mtnodeParentArrayEntr[i]); } // Fuction を提供する子ノードを追加 tnode->addChild(mtnodeChildArrayEntr[i]); } // ファンクションテーブルを保存する _functblRef = functblRef; // パネルファクトリを保存する _pnlfctryRef = pnlfctryRef; // パラメータオブジェクトを保存する _objCreateParamRef = objCreateParam; // メモリ管理を委譲された配列を削除 delete[] mtnodeParentArrayEntr; delete[] mtnodeChildArrayEntr; return true; }
int main() { cout << "Initializing Tree with " << 1 << "\n"; TreeNode *root = new TreeNode(1); root->printTree(); TreeNode *a = root->addChild(2); root->printTree(); TreeNode *b = root->addChild(3); root->printTree(); a->addChild(4); root->printTree(); TreeNode *c = a->addChild(5); root->printTree(); c->addChild(6); root->printTree(); b->addChild(7); root->printTree(); root->breadthSearch(); root->depthSearch(); return 0; }
TreeNode<int>* takeTreeInput() { int rootData; cout << "Enter root data" << endl; cin >> rootData; TreeNode<int>* root = new TreeNode<int>(rootData); int numChildren; cout << "Enter number of children " << endl; cin >> numChildren; for (int i = 0; i < numChildren; i++) { root->addChild(takeTreeInput()); } return root; }
/*---------------------------------------------------------------------*//** ノード追加 **//*---------------------------------------------------------------------*/ bool Menu::addMenuTreeNode(MenuTreeNode* mtnodePos, MenuTreeNode* mtnodeAdd, bool isChild) { TreeNode<MenuTreeNode>* tnodePos = findTreeNodeFromMenuTreeNode(mtnodePos, _tree->getRoot()); if(tnodePos == 0L) { return false; } if(isChild) { tnodePos->addChild(mtnodeAdd); } else { tnodePos->addSibling(mtnodeAdd); } return true; }
void TreeNode::Tree::createNode(const AbstractTreeIterator& parentPath, const String& name, bool leaf) { if (canCreateNodes() == true) { TreeNode* parentNode = getTreeNodeFromIterator(parentPath); if (parentNode != NULL) { TreeNode* newNode = (*createNodeFunctor)(name); parentNode->addChild(newNode); newNode->setParent(parentNode); } else { argumentError("Need a TreeNode::Iterator to create a node!" ERROR_AT); } } else { stateError("Tree can't create nodes!" ERROR_AT); } }
void TreeNode::Tree::moveNode(const AbstractTreeIterator& nodePath, const AbstractTreeIterator& newParentPath) { if (canMoveNodes() == true) { TreeNode* treeNode = getTreeNodeFromIterator(nodePath); TreeNode* newParentNode = getTreeNodeFromIterator(newParentPath); if (treeNode != NULL && newParentNode != NULL) { TreeNode* oldParentNode = treeNode->getParent(); treeNode->setParent(NULL); oldParentNode->removeChild(treeNode->getChildIndexAtParent()); newParentNode->addChild(treeNode); treeNode->setParent(newParentNode); } else { argumentError("Need a TreeNode::Iterator to move a node!" ERROR_AT); } } else { stateError("Tree can't move nodes!" ERROR_AT); } }
TreeNode < T1 > _build(const vector < vector <T1> > & feature_set, const vector < T2 > & label_set, vector < bool > & selected) { TreeNode < T1 > temp; #ifdef DEBUG for(auto d: feature_set) { for(auto f: d) { cerr << f << ", "; } cerr << endl; } #endif // label->size: data size // select->size: feature size // related instance number temp.setNumInstances(label_set.size()); // check input bool feature_the_same = true; for(size_t fdx = 0; fdx < selected.size(); fdx++) { if(selected[fdx] == false) { set < T1 > cur_values; for(size_t ddx = 0; ddx < label_set.size(); ddx++) { cur_values.insert(feature_set[ddx][fdx]); } if(cur_values.size() != 1) { feature_the_same = false; } } } // all features have the same value if(feature_the_same) { temp.setNodeType(AIS); return temp; } // check output set < T2 > output_set; for(size_t ddx = 0; ddx < label_set.size(); ddx++) { // maybe wrong output_set.insert(label_set[ddx]); } // labels are the same if(output_set.size() == 1) { temp.setNodeType(AOS); return temp; } // find maximum information gain temp.setNodeType(MIG); map < T1, int > count_label; for(auto l: label_set) { count_label[l]++; } // H(Y) = - sigma(p(y) * log(p(y)) double h_y = 0; for(auto c: count_label) { double p = c.second * 1. / label_set.size(); h_y += p * log(p); } h_y = - h_y; #ifdef DEBUG cerr << "H(Y): " << h_y << endl; #endif int best_feature = -1; double best_ig = -1.; for(size_t fdx = 0; fdx < selected.size(); fdx++) { if(selected[fdx] == false) { // TODO // IG(Xi) = H(Y) - H(Y|Xi) // H(Y) = - sigma(p(y) * log(p(y)) // H(Y|Xi) = sigma(p(xij) * H(Y|xij)) // = sigma(p(xij) * [- sigma(p(y|xij) * log(p(y|xij)))] // = -sigma"y, xij"(p(xij, y) * log(p(y|xij))) // = -sigma"y, xij"(p(xij, y) * log(p(xij, y)/p(xij))) map < T1, map < T2, int > > count_value_with_label; for(size_t ddx = 0; ddx < label_set.size(); ddx++) { count_value_with_label[feature_set[fdx][ddx]][label_set[ddx]]++; } double h_y_x = 0.; for(auto x: count_value_with_label) { double p_x_with_no_fraction = x.second.size() * 1.; for(auto x_y: x.second) { double p_x_y_w_n_f = x_y.second * 1. / label_set.size(); h_y_x += p_x_y_w_n_f * log(p_x_y_w_n_f / p_x_with_no_fraction); } } h_y_x = - h_y_x; double ig = h_y - h_y_x; #ifdef DEBUG cerr << "IG: " << h_y << endl; #endif if(best_ig < ig) { best_ig = ig; best_feature = fdx; } } } assert(best_feature != -1); // split temp.setFeatureId(best_feature); // choose branches (discrete) set < T1 > values_of_feature; for(size_t ddx = 0; ddx < label_set.size(); ddx++) { values_of_feature.insert(feature_set[ddx][best_feature]); } selected[best_feature] = true; for(auto v: values_of_feature) { vector < vector <T1> > children_feature_set; vector < T2 > children_label_set; for(size_t ddx = 0; ddx < label_set.size(); ddx++) { if(feature_set[ddx][best_feature] == v) { children_feature_set.push_back(feature_set[ddx]); children_label_set.push_back(label_set[ddx]); } } temp.addChild(_build(children_feature_set, children_label_set, selected), v); } return temp; }