/* * createTree * Function: Uses a CharCounts list to create a min-heap Huffman binary tree * Parameters: The CharCounts list to use * Return: The min-heap Huffman binary tree */ EncodingTree * createTree(CharCounts * counts) { EncodingTree * root; TreeQueue * queue; TreeQueue * toAdd; EncodingTree * temp1; EncodingTree * temp2; int nodeCount; CharCounts * tempCount; root = NULL; queue = NULL; toAdd = NULL; temp1 = NULL; temp2 = NULL; nodeCount = 0; tempCount = NULL; /* Insert all CharCounts into the TreeQueue (sorted least to greatest) */ tempCount = counts; while(tempCount != NULL) { toAdd = createBranch(tempCount); tempCount = tempCount->next; queue = insertInQueue(queue, toAdd); } /*printQueue(queue);*/ toAdd = NULL; /* * Remove from the TreeQueue, TWO AT A TIME, to create a singular binary tree, * and insert back into sorted queue accordingly * Continue until there is nothing left in the queue */ while(isEmpty(queue) == 0) { /*printf("boom\n");*/ if(toAdd != NULL) { queue = insertInQueue(queue, toAdd); } /* Remove two from queue */ temp1 = queue->root; /*printf("%c%d\n\nQueue1\n", temp1->letter, temp1->count);*/ /*printQueue(queue);*/ queue = queue->next; /*printf("Queue2\n");*/ /*printQueue(queue);*/ temp2 = queue->root; /*printf("%c%d\n\n", temp2->letter, temp2->count);*/ queue = queue->next; /*printQueue(queue);*/ temp2 = insertInTree(temp2, temp1); toAdd = createBranchFromTree(temp2); } root = toAdd->root; return(root); }
int BranchBound(Problem<type,type2>& P,Solution<type,type2>& s,ptrVar<type,type2> choiceVar, ptrTest<type,type2> TotalTest, type epsilon,double param){ struct timeval tim; gettimeofday(&tim,NULL); double t1=tim.tv_sec+(tim.tv_usec/1000000.0); double t2=0.0; double timeMIP=0.0; int cptMIP=0; int cptConsistency=0; int cptAdjust=0; int nbNode=0; int x=0; int test=0; Problem<type,type2> P1(P); std::stack<Problem<type,type2>> explore; explore.push(P); while (!explore.empty() && t2-t1<=7200.0) { ++nbNode; P1=explore.top(); explore.pop(); if (P1.dataConsistency()) { test=TotalTest(P1); if (0 != test) { cptAdjust+=test-1; x=choiceVar(P1,epsilon); if (x!=-1) createBranch(P1,x,explore,param); else { ++cptMIP; P1.updateHorizon(); if (!LPsolveConvex(P) && !SolveConvex(P1,s)){ gettimeofday(&tim,NULL); t2=tim.tv_sec+(tim.tv_usec/1000000.0); std::cout << "Instance résolue" << std::endl; //std::cout << "Total time : " <<t2-t1 << "\n"; std::cout << "Tree time : " <<t2-t1-timeMIP << "\n"; /* std::cout << "MIP time : " <<timeMIP << "\n"; std::cout << "le nombre de noeud : " << nbNode<<std::endl; std::cout << "le nombre de MIP : " << cptMIP <<std::endl; std::cout << "le nombre de consistensy fail : " << cptConsistency<<std::endl; */ std::cout << "le nombre de adjust : " << cptAdjust<<std::endl; return 1; } } } else ++cptConsistency; } gettimeofday(&tim,NULL); t2=tim.tv_sec+(tim.tv_usec/1000000.0); } std::cout << "Instance non résolue" << std::endl; /* std::cout << "le nombre de noeud : " << nbNode<<std::endl; std::cout << "le nombre de MIP : " << cptMIP <<std::endl; std::cout << "le nombre de consistensy fail : " << cptConsistency<<std::endl; */std::cout << "le nombre de adjust : " << cptAdjust<<std::endl; return 0; }
/** * Explores the grid * @param startNd */ void explore(int startNd) { // Create starting branch int branch = createBranch(-1); if (getPath(startNd, branch) == -1) { printf("An error occurred: starting node not included in any path.\n"); } else { // printf("Starting exploration\n"); pathReturned = explorePath(startNd, NULL, 0, 0); // printf("Exploration finished!\n"); } }
// creates recursively the tree, uses subset of features void Tree::train(DataFrame &dataframe, const vector<int> &featList, const int nrFeat, const bool verbose) { //select features randomly if (verbose) cout<<"Training tree with random seed:"<<rng.seed<<endl; vector<int> featsubset = LUtils::sample(rng, nrFeat, dataframe.nrcols - 1, false); DataFrame::FeatureResult featResult = dataframe.findBestFeature(featsubset, entropy_loss); //Create a new root node root->feature = featResult.opt_feat; root->splitvalue = featResult.opt_split; root->impurity = featResult.loss; root->nameFeature = dataframe.header.at(featResult.opt_feat); root->nrsamples = dataframe.nrrows; createBranch(root, dataframe, nrFeat, verbose); }
//recursively insert nodes void Tree::createBranch(boost::shared_ptr<Node> parentNode, DataFrame &dfsplit, const int nrFeat, bool verbose) { vector<int> featsubset = LUtils::sample(rng, nrFeat, dfsplit.nrcols - 1, false); if (verbose) { cout << "Feature subset: "; for (unsigned i = 0; i < featsubset.size(); ++i) { cout << " " << dfsplit.header[featsubset[i]]; } cout << endl; } DataFrame leftDF; DataFrame rightDF; dfsplit.splitFrame(parentNode->splitvalue, parentNode->feature, leftDF, rightDF); tree_size++; //LEFT BRANCH if (verbose && leftDF.nrrows > 0) { cout << "...Creating left branch: Feature: " << dfsplit.header[parentNode->feature] << " Value:" << parentNode->splitvalue << " n:" << leftDF.nrrows << " with prediction:" << leftDF.cm << endl; //leftDF.printSummary(); } if (leftDF.nrrows == 0) { //happens if one of the nodes is "practically" pure if (verbose) { cout << "No data in left node, right node:" << rightDF.nrrows << endl; cout << "Left node: Parent node is terminal." << endl; } parentNode->isTerminal = true; tnodecount++; return; } else if (leftDF.nrrows <= min_node || parentNode->depth + 1 > max_depth || leftDF.distinct[leftDF.classCol] < 2) { if (verbose) cout << "Terminal node, cm: " << leftDF.cm << endl; boost::shared_ptr<Node> left = boost::make_shared<Node>( parentNode->depth + 1, leftDF.cm); left->isTerminal = true; left->nrsamples = leftDF.nrrows; parentNode->left = left; tnodecount++; } else { DataFrame::FeatureResult featResulta = leftDF.findBestFeature( featsubset, entropy_loss); boost::shared_ptr<Node> left = boost::make_shared<Node>( featResulta.opt_feat, featResulta.opt_split, featResulta.loss, parentNode->depth + 1, leftDF.header[featResulta.opt_feat], leftDF.nrrows, leftDF.cm); parentNode->left = left; createBranch(left, leftDF, nrFeat, verbose); } //RIGHT BRANCH if (verbose && rightDF.nrrows > 0) { cout << "...Creating right branch: Feature: " << dfsplit.header[parentNode->feature] << " Value:" << parentNode->splitvalue << " n:" << rightDF.nrrows << " with prediction:" << rightDF.cm << endl; //rightDF.printSummary(); } if (rightDF.nrrows == 0) { //happens if one of the nodes is "practically" pure if (verbose) { cout << "No data in right node, left node:" << leftDF.nrrows << endl; cout << "Right node: Parent node is terminal." << endl; } parentNode->isTerminal = true; tnodecount++; return; } else if (rightDF.nrrows <= min_node || parentNode->depth + 1 > max_depth || rightDF.distinct[rightDF.classCol] < 2) { if (verbose) cout << "Terminal node, cm: " << rightDF.cm << endl; boost::shared_ptr<Node> right = boost::make_shared<Node>( parentNode->depth + 1, rightDF.cm); right->isTerminal = true; right->nrsamples = rightDF.nrrows; parentNode->right = right; tnodecount++; } else { DataFrame::FeatureResult featResultb = rightDF.findBestFeature( featsubset, entropy_loss); if (verbose) cout << "Terminal node, cm: " << rightDF.cm << endl; boost::shared_ptr<Node> right = boost::make_shared<Node>( featResultb.opt_feat, featResultb.opt_split, featResultb.loss, parentNode->depth + 1, rightDF.header[featResultb.opt_feat], rightDF.nrrows, rightDF.cm); parentNode->right = right; createBranch(right, rightDF, nrFeat, verbose); } //if we reach this point, we should return return; }
/** * Explores a path * @param node * @param currPath * @param currPathSize * @param node * @param currPath * @param currPathSize * @param branch * @return */ int* explorePath(int node, int* currPath, int currPathSize, int branch) { // printf("Call at node %d [branch: %d]\n", node, branch); // First get the path int startPath = getPath(node, branch); int startEven = getPathEven; // Get the position in the path int pos = -1, i, x; if (startEven) { for (i = 0; i < evenPathsSizes[startPath]; i++) { if (evenPaths[startPath][i] == node) { pos = i; // printf("Encountered even path %d [cue at %d]\n", startPath, pos); } } } else { for (i = 0; i < oddPathsSizes[startPath]; i++) { if (oddPaths[startPath][i] == node) { pos = i; // printf("Encountered odd path %d [cue at %d]\n", startPath, pos); } } } if (pos == -1) { printf("An error occurred: no cue found (starPath: %d, startEven: %d).\n", startPath, startEven); return NULL; } // Now create the left and right path // First determine the complete path to walk int *pathLeft = malloc(sizeof (int) *MAX_PATH_LENGTH); int pathLeftSize = 0; // Now process both even and odd paths differently if (startEven) { // For l: add from pos to end + from 1 to (including) pos for (i = pos; i < evenPathsSizes[startPath]; i++) pathLeft[pathLeftSize++] = evenPaths[startPath][i]; for (i = 1; i <= pos; i++) pathLeft[pathLeftSize++] = evenPaths[startPath][i]; } else { // For l: add from pos to 0 + from 0 to end + from end to pos for (i = pos; i >= 0; i--) pathLeft[pathLeftSize++] = oddPaths[startPath][i]; for (i = 1; i < oddPathsSizes[startPath]; i++) pathLeft[pathLeftSize++] = oddPaths[startPath][i]; for (i = oddPathsSizes[startPath] - 2; i >= pos; i--) pathLeft[pathLeftSize++] = oddPaths[startPath][i]; } // getchar(); // Initialize the paths possibly taken int **currPaths = malloc(sizeof (int) *MAX_PATH_LENGTH * MAX_BRANCHES); int *currPathsSizes = malloc(sizeof (int) *MAX_BRANCHES); int currPathsSize = 0; // Mark current path to walked if (startEven) walkedEvenPaths[branch][walkedEvenPathsSizes[branch]++] = startPath; else walkedOddPaths[branch][walkedOddPathsSizes[branch]++] = startPath; // branches contains the branch IDs, branchesPID contains the id in currPath[id] of the path associated with the branch int masterBranch = branch; // int branchLeft, branchRight; int *branches = malloc(sizeof (int) *MAX_BRANCHES); int *branchesPID = malloc(sizeof (int) *MAX_BRANCHES); int branchesSize = 0; int PID, BID; // printf("Processing standard path\n"); PID = branchesPID[branchesSize] = createNewCurrPath(currPaths, currPathsSizes, &currPathsSize, currPath, currPathSize); BID = branches[branchesSize] = createBranch(masterBranch); for (i = 0; i < pathLeftSize; i++) { if (getPath(pathLeft[i], BID) == -1) { // Just a normal step currPaths[PID][currPathsSizes[PID]++] = pathLeft[i]; } else { // Another path found -> recursion! currPaths[PID] = explorePath(pathLeft[i], currPaths[PID], currPathsSizes[PID], BID); // Find size for (x = 0; currPaths[PID][x] != -1; x++); currPathsSizes[PID] = x; } // ALTERNATIVE FOR LOOP_PATH_NOT // Check if path is complete, if so: i = pathLeftSize. :D #if LOOP_PATH == 1 if (pathIsComplete(currPaths[PID], currPathsSizes[PID])) { // printf("Branch %d finished\n", BID); i = pathLeftSize; } #endif } branchesSize++; // Find best branch and return that one // branchBest id local branch id, branches[branchBest] is global branch id int branchBest = -1, branchBestRating = 0; for (i = 0; i < branchesSize; i++) { // Get rating int rating = currPathsSizes[branchesPID[i]]; // Compare and select if (branchBest == -1 || branchBestRating > rating) { branchBest = i; branchBestRating = rating; } } if (branchBest == -1) { printf("An error occurred: no branches were created!\n"); return NULL; } // printf("Merge branch %d (master branch) and %d (local branch: %d) into %d\n", masterBranch, branches[branchBest], branchBest, masterBranch); overrideBranch(masterBranch, branches[branchBest]); // Pack size and return best branch currPaths[branchesPID[branchBest]][currPathsSizes[branchesPID[branchBest]]++] = -1; return currPaths[branchesPID[branchBest]]; }