setTreeNodes UnorderedTree::TreeComponents(TreeNodes *t,bool bCanonical=false){ //Returns the components ( subtree of next level) of a tree setTreeNodes setTreeComponents; //Insert into a set, the components TreeNodes::iterator itTreeNodes; Integer level=(*t)[0]; TreeNodes component; itTreeNodes=t->begin(); int i=0; bool blnend=false; while(i<t->size() &&itTreeNodes!=t->end()) { //The components start at level 0, the canonical form no if (*itTreeNodes!=level) component.push_back( (*itTreeNodes)-(bCanonical ? 0 :level)); ++itTreeNodes;i++; if (itTreeNodes==t->end()) blnend=true; else if((*itTreeNodes)<= level+1 ) blnend=true; if (blnend==true){ blnend=false; if(component.size()>0){ setTreeComponents.insert(bCanonical ? CanonicalForm(component): component ); component.clear(); } } } return setTreeComponents; }
void BppSolver::SeparateBranch(BranchNode& togetherNode, BranchNode& separateNode, TreeNodes& nodes) { togetherNode.id = nbGeneratedNodes++; nodes.push_back(togetherNode); separateNode.id = nbGeneratedNodes++; nodes.push_back(separateNode); }
void BppSolver::TogetherBranch(BranchNode& togetherNode, BranchNode& separateNode, TreeNodes& nodes) { separateNode.id = nbGeneratedNodes++; nodes.push_back(separateNode); togetherNode.id = nbGeneratedNodes++; // deepening on together branch; nodes.push_back(togetherNode); }
void Tree::print_l(TreeNodes tree){ //Prints Tree #if defined(LABELLED) for(TreeNodes::iterator it=tree.begin();it!=tree.end();it++) cout<<"("<<it->depth<<","<<it->label<<") "; #else for(TreeNodes::iterator it=tree.begin();it!=tree.end();it++) cout<<*it<<" "; #endif }
TreeNodes UnorderedTree::SubtreeAtNode(TreeNodes *supertree,Integer *iNode){ //Outputs the bigest bottom subtree rooted at iNode TreeNodes tn; int i=*iNode; int v=(*supertree)[i].depth; int init_depth=v; do { tn.push_back(Node(v-init_depth,(*supertree)[i].label)); i++; v=(*supertree)[i].depth; } while (v-init_depth>0 && i<supertree->size() ); return CanonicalForm(tn); }
TreeNodes UnorderedTree::CanonicalForm(TreeNodes t){ //Returns recursively the CanonicalForm of a tree if (t.size()<2) return t; setTreeNodes setTreeComponents = TreeComponents(&t,true); Integer level=t[0]; TreeNodes tn; tn.push_back(level); setTreeNodes::reverse_iterator itset; TreeNodes::iterator iteTreeNodes; for (itset=setTreeComponents.rbegin();itset!=setTreeComponents.rend();++itset){ TreeNodes t1=(*itset); for (iteTreeNodes=t1.begin();iteTreeNodes!=t1.end();++iteTreeNodes){ tn.push_back((*iteTreeNodes)); } } return tn; }
std::size_t BppSolver::branchAndPrice(BinPackingProblem& bpp) { TreeNodes nodes; nodes.emplace_back(); nbGeneratedNodes = 0; while (!nodes.empty()) { BranchNode& node = nodes.back(); if (node.toPrune) { for (auto i : *node.invalidColumns) BPmodel.setVarUB(i, 1.0); if (node.id >= 0) //pricerBranchConstraints[node.id].end(); pricerModel.removeConstraint(node.id); #ifdef EXPORT_MODEL BPSolver.exportModel("model.lp"); pricerSolver.exportModel("pricer.lp"); #endif // !EXPORT_MODEL nodes.pop_back(); // delete the node. } else if (std::ceil(node.incumbentLPValue) <= upperBound) { // modify the master and pricer to solve the specific node // desable ~current and incumbent invalide variables for (auto i : *node.invalidColumns) BPmodel.disableVar(i); // add the specific pricer branch constraint IloExpr expr(pricerModel.getEnv()); if (node.brType == TOGETHER) { expr += pricerModel.getVar(node.couple_ij.first) - pricerModel.getVar(node.couple_ij.second); pricerModel.addConstraint(expr, 0.0); } else if (node.brType == SEPARATE) { expr += pricerModel.getVar(node.couple_ij.first) + pricerModel.getVar(node.couple_ij.second); pricerModel.addConstraint(expr, 1.0); } expr.end(); #ifdef EXPORT_MODEL BPSolver.exportModel("model.lp"); pricerSolver.exportModel("pricer.lp"); #endif // !EXPORT_MODEL // generate columns real master_lp_value = columnGeneration(bpp); //std::cout << master_lp_value << "\n"; // is solution integral if (BPmodel.checkIntegrality()) { std::cout << "---------------- INTEGRAL -----------------\n"; // possible new upper bound if (std::ceil(master_lp_value - EPS) < upperBound) { // update upper bound upperBound = master_lp_value; // copy the current solution bestSolution = BPmodel.getPrimalValues(); } node.toPrune = true; //else if (master_lp_value == upperBound) // optimal // return upperBound; } else if (std::ceil(master_lp_value) < upperBound) // generate branchs { auto couple = ryanFosterCouple(node); node.toPrune = true; generateBranches(master_lp_value, couple, node, nodes); } else { // no node to generate, then this node must be pruned node.toPrune = true; } } else // to prune node.toPrune = true; } while (!nodes.empty()); return (std::size_t)upperBound; }