//############################################################################# void MibSHeuristic::lowerObjHeuristic() { /* optimize wrt to lower-level objective over current feasible lp feasible region */ MibSModel * model = MibSModel_; OsiSolverInterface * oSolver = model->getSolver(); //OsiSolverInterface * hSolver = new OsiCbcSolverInterface(); OsiSolverInterface* hSolver = new OsiSymSolverInterface(); double objSense(model->getLowerObjSense()); int lCols(model->getLowerDim()); int uCols(model->getUpperDim()); int * lColIndices = model->getLowerColInd(); int * uColIndices = model->getUpperColInd(); double * lObjCoeffs = model->getLowerObjCoeffs(); //int tCols(lCols + uCols); int tCols(oSolver->getNumCols()); //assert(tCols == oSolver->getNumCols()); hSolver->loadProblem(*oSolver->getMatrixByCol(), oSolver->getColLower(), oSolver->getColUpper(), oSolver->getObjCoefficients(), oSolver->getRowLower(), oSolver->getRowUpper()); int j(0); for(j = 0; j < tCols; j++){ if(oSolver->isInteger(j)) hSolver->setInteger(j); } double * nObjCoeffs = new double[tCols]; int i(0), index(0); CoinZeroN(nObjCoeffs, tCols); for(i = 0; i < lCols; i++){ index = lColIndices[i]; nObjCoeffs[index] = lObjCoeffs[i]; } //MibS objective sense is the opposite of OSI's! hSolver->setObjSense(objSense); hSolver->setObjective(nObjCoeffs); //double cutoff(model->getCutoff()); double cutoff(model->getKnowledgeBroker()->getIncumbentValue()); if(model->getNumSolutions()){ CoinPackedVector objCon; //double rhs(cutoff * objSense); //double smlTol(1.0); double rhs(cutoff); for(i = 0; i < tCols; i++){ objCon.insert(i, oSolver->getObjCoefficients()[i] * oSolver->getObjSense()); } hSolver->addRow(objCon, - hSolver->getInfinity(), rhs); } if(0) hSolver->writeLp("lobjheurstic"); if(0){ dynamic_cast<OsiCbcSolverInterface *> (hSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("max_active_nodes", 1); } hSolver->branchAndBound(); if(hSolver->isProvenOptimal()){ double upperObjVal(0.0); /*****************NEW ******************/ MibSSolution *mibSol = NULL; OsiSolverInterface * lSolver = model->bS_->setUpModel(hSolver, true); if(0){ lSolver->writeLp("tmp"); } if(0){ dynamic_cast<OsiCbcSolverInterface *> (lSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("max_active_nodes", 1); } lSolver->branchAndBound(); if (lSolver->isProvenOptimal()){ const double * sol = hSolver->getColSolution(); double objVal(lSolver->getObjValue() * objSense); double etol(etol_); double lowerObj = getLowerObj(sol, objSense); double * optUpperSolutionOrd = new double[uCols]; double * optLowerSolutionOrd = new double[lCols]; CoinZeroN(optUpperSolutionOrd, uCols); CoinZeroN(optLowerSolutionOrd, lCols); if(fabs(objVal - lowerObj) < etol){ /** Current solution is bilevel feasible **/ for(i = 0; i < tCols; i++) upperObjVal += hSolver->getColSolution()[i] * oSolver->getObjCoefficients()[i]; mibSol = new MibSSolution(hSolver->getNumCols(), hSolver->getColSolution(), upperObjVal, model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); mibSol = NULL; } else{ /* solution is not bilevel feasible, create one that is */ const double * uSol = hSolver->getColSolution(); const double * lSol = lSolver->getColSolution(); int numElements(hSolver->getNumCols()); int i(0), pos(0), index(0); double * lpSolution = new double[numElements]; double upperObj(0.0); //FIXME: problem is still here. indices may be wrong. //also is all this necessary, or can we just paste together uSol and lSol? //this may be an old comment for(i = 0; i < numElements; i++){ pos = model->bS_->binarySearch(0, lCols - 1, i, lColIndices); if(pos < 0){ pos = model->bS_->binarySearch(0, uCols - 1, i, uColIndices); if (pos >= 0){ optUpperSolutionOrd[pos] = uSol[i]; } } else{ optLowerSolutionOrd[pos] = lSol[pos]; } } for(i = 0; i < uCols; i++){ index = uColIndices[i]; lpSolution[index] = optUpperSolutionOrd[i]; upperObj += optUpperSolutionOrd[i] * oSolver->getObjCoefficients()[index]; } for(i = 0; i < lCols; i++){ index = lColIndices[i]; lpSolution[index] = optLowerSolutionOrd[i]; upperObj += optLowerSolutionOrd[i] * oSolver->getObjCoefficients()[index]; } if(model->checkUpperFeasibility(lpSolution)){ mibSol = new MibSSolution(hSolver->getNumCols(), lpSolution, upperObj * oSolver->getObjSense(), model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); mibSol = NULL; } delete [] lpSolution; } } delete lSolver; } delete hSolver; }
//############################################################################# void MibSHeuristic::greedyHeuristic() { MibSModel * model = MibSModel_; //OsiSolverInterface * oSolver = model->getSolver(); OsiSolverInterface * oSolver = model->solver(); double uObjSense(oSolver->getObjSense()); double lObjSense(model->getLowerObjSense()); int lCols(model->getLowerDim()); int uCols(model->getUpperDim()); int * uColIndices = model->getUpperColInd(); int * lColIndices = model->getLowerColInd(); double * lObjCoeffs = model->getLowerObjCoeffs(); double * intCost = model->getInterdictCost(); double intBudget = model->getInterdictBudget(); int tCols(uCols + lCols); assert(tCols == oSolver->getNumCols()); int i(0), ind_min_wt(0); double usedBudget(0.0); double * fixedVars = new double[lCols]; double * testsol = new double[tCols]; CoinZeroN(fixedVars, lCols); CoinZeroN(testsol, tCols); std::multimap<double, int> lObjCoeffsOrd; for(i = 0; i < lCols; i++) lObjCoeffsOrd.insert(std::pair<double, int>(lObjCoeffs[i] * lObjSense, i)); if(!bestSol_) bestSol_ = new double[tCols]; //initialize the best solution information //bestObjVal_ = model->getSolver()->getInfinity() * uObjSense; //CoinZeroN(bestSol_, tCols); std::multimap<double, int>::iterator iter; //std::multimap<double, int>::iterator first; //std::multimap<double, int>::iterator last; //int dist = std::distance(first, last); srandom((unsigned) time(NULL)); int randchoice(0); if(0) std::cout << "randchoice " << randchoice << std::endl; double cost(0.0); //starting from the largest, fix corr upper-level variables //then, with these fixed, solve the lower-level problem //this yields a feasible solution iter = lObjCoeffsOrd.begin(); while((usedBudget < intBudget) && (iter != lObjCoeffsOrd.end())){ ind_min_wt = iter->second; cost = intCost[ind_min_wt]; testsol[uColIndices[ind_min_wt]] = 1.0; double min_wt = iter->first; if(0){ std::cout << "upper: " << ind_min_wt << " " << uColIndices[ind_min_wt] << " " << oSolver->getColUpper()[uColIndices[ind_min_wt]] << " " << oSolver->getColLower()[uColIndices[ind_min_wt]] << std::endl; std::cout << "lower: " << ind_min_wt << " " << lColIndices[ind_min_wt] << " " << oSolver->getColUpper()[lColIndices[ind_min_wt]] << std::endl; } //if((oSolver->getColUpper()[uColIndices[ind_min_wt]] == 1.0) //&& (oSolver->getColUpper()[lColIndices[ind_min_wt]] > 0)){ if(oSolver->getColUpper()[uColIndices[ind_min_wt]] > etol_){ //if(((usedBudget + cost) <= intBudget) // && checkLowerFeasibility(oSolver, testsol)){ if((usedBudget + cost) <= intBudget){ //FIXME: SHOULD BE CHECKING FOR CURRENT BOUNDS HERE //fix the corresponding upper-level variable to 1 randchoice = random() % 2; if(0) std::cout << "randchoice " << random << std::endl; if(randchoice){ fixedVars[ind_min_wt] = 1.0; usedBudget += intCost[ind_min_wt]; } } } else{ testsol[uColIndices[ind_min_wt]] = 0; //break; } iter++; } /* now we find a feasible solution by fixing upper-level vars and solving the lower-level problem */ double * incumbentSol = new double[tCols]; double * colsol = new double[tCols]; CoinZeroN(colsol, tCols); for(i = 0; i < uCols; i++){ colsol[uColIndices[i]] = fixedVars[i]; if(fixedVars[i] == 1.0) if(0) std::cout << "fixed " << i << std::endl; } bfSol * sol = getBilevelSolution(colsol, lObjSense * oSolver->getInfinity()); if(sol){ double incumbentObjVal = sol->getObjVal(); CoinCopyN(sol->getColumnSol(), tCols, incumbentSol); MibSSolution * mibSol = new MibSSolution(tCols, incumbentSol, incumbentObjVal, model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); } //bestObjVal_ = incumbentObjVal; //CoinCopyN(incumbentSol, tCols, bestSol_); delete [] incumbentSol; delete [] testsol; //delete [] colsol; //delete [] fixedVars; //delete sol; }
//############################################################################# void MibSHeuristic::createBilevelSolutions(std::map<double, mcSol> mcSolutions) { MibSModel * model = MibSModel_; double uObjSense(model->getSolver()->getObjSense()); int lCols(model->getLowerDim()); int uCols(model->getUpperDim()); int tCols(uCols + lCols); double incumbentObjVal(model->getSolver()->getInfinity() * uObjSense); double * incumbentSol = new double[tCols]; int i(0); if(!bestSol_) bestSol_ = new double[tCols]; //initialize the best solution information //bestObjVal_ = model->getSolver()->getInfinity() * uObjSense; //CoinZeroN(bestSol_, tCols); std::map<double, mcSol >::iterator iter = mcSolutions.begin(); for(iter = mcSolutions.begin(); iter != mcSolutions.end(); iter++){ mcSol tmpsol = iter->second; const double * colsol = tmpsol.getColumnSol(); double origLower = tmpsol.getObjPair().second; if(0){ std::cout << "Candidate solution value: " << origLower << std::endl; for(i = 0; i < tCols; i++){ std::cout << "colsol[" << i << "] :" << colsol[i] << std::endl; } } bfSol * sol = getBilevelSolution(colsol, origLower); if(sol){ if(0){ std::cout << "Returned solution: " << std::endl; for(i = 0; i < tCols; i++){ std::cout << "sol->getColumnSol[" << i << "]" << sol->getColumnSol()[i] << std::endl; } std::cout << "sol->getObjVal: " << sol->getObjVal() << std::endl; } if(sol->getObjVal() < incumbentObjVal){ incumbentObjVal = sol->getObjVal(); CoinCopyN(sol->getColumnSol(), tCols, incumbentSol); if(0){ std::cout << "New incumbent found." << std::endl; for(i = 0; i < tCols; i++){ std::cout << "incumbentSol[" << i << "]: " << incumbentSol[i] << std::endl; } std::cout << "incumbentObjVal: " << incumbentObjVal << std::endl; } } } } if(0){ std::cout << "This solution comes from MibSHeuristic.cpp:742" << std::endl; } MibSSolution * mibSol = new MibSSolution(tCols, incumbentSol, incumbentObjVal, model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); //need to add this solution to mibssolutions instead //bestObjVal_ = incumbentObjVal; //CoinCopyN(incumbentSol, tCols, bestSol_); //delete bfSol; delete [] incumbentSol; }
//############################################################################# void MibSHeuristic::objCutHeuristic() { /* Solve the LP relaxation with the new constraint d^2 y <= d^y* */ MibSModel * model = MibSModel_; //OsiSolverInterface * oSolver = model->origLpSolver_; OsiSolverInterface * oSolver = model->getSolver(); //OsiSolverInterface * hSolver = new OsiCbcSolverInterface(); OsiSolverInterface * hSolver = new OsiSymSolverInterface(); double objSense(model->getLowerObjSense()); int lCols(model->getLowerDim()); int uCols(model->getUpperDim()); int tCols(lCols + uCols); int * lColIndices = model->getLowerColInd(); int * uColIndices = model->getUpperColInd(); double * lObjCoeffs = model->getLowerObjCoeffs(); hSolver->loadProblem(*oSolver->getMatrixByCol(), oSolver->getColLower(), oSolver->getColUpper(), oSolver->getObjCoefficients(), oSolver->getRowLower(), oSolver->getRowUpper()); int j(0); for(j = 0; j < tCols; j++){ if(oSolver->isInteger(j)) hSolver->setInteger(j); } double * optLowerSolutionOrd = model->bS_->optLowerSolutionOrd_; CoinPackedVector objCon; int i(0), index(0); double rhs(0.0); for(i = 0; i < lCols; i++){ index = lColIndices[i]; objCon.insert(index, lObjCoeffs[i] * objSense); //should this be ordered? and should lObjCoeffs by at index? //rhs += optLowerSolutionOrd_[i] * lObjCoeffs[i] * objSense; rhs += optLowerSolutionOrd[i] * lObjCoeffs[i] * objSense; } //Hmm, I think this was wrong before...? // hSolver->addRow(objCon, - hSolver->getInfinity(), rhs); hSolver->addRow(objCon, rhs, hSolver->getInfinity()); /* optimize w.r.t. to the UL objective with the new row */ if(0){ dynamic_cast<OsiCbcSolverInterface *> (hSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (hSolver)->setSymParam("max_active_nodes", 1); } hSolver->branchAndBound(); if(0) hSolver->writeLp("objcutheuristic"); if(hSolver->isProvenOptimal()){ MibSSolution *mibSol = NULL; OsiSolverInterface * lSolver = model->bS_->setUpModel(hSolver, true); if(0){ dynamic_cast<OsiCbcSolverInterface *> (lSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (lSolver)->setSymParam("max_active_nodes", 1); } lSolver->branchAndBound(); const double * sol = hSolver->getColSolution(); double objVal(lSolver->getObjValue() * objSense); double etol(etol_); double lowerObj = getLowerObj(sol, objSense); double * optUpperSolutionOrd = new double[uCols]; double * optLowerSolutionOrd = new double[lCols]; CoinZeroN(optUpperSolutionOrd, uCols); CoinZeroN(optLowerSolutionOrd, lCols); if(fabs(objVal - lowerObj) < etol){ /** Current solution is bilevel feasible **/ mibSol = new MibSSolution(hSolver->getNumCols(), hSolver->getColSolution(), hSolver->getObjValue(), model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); mibSol = NULL; } else{ /* solution is not bilevel feasible, create one that is */ const double * uSol = hSolver->getColSolution(); const double * lSol = lSolver->getColSolution(); //int numElements(lSolver->getNumCols()); int numElements(hSolver->getNumCols()); int i(0), pos(0), index(0); double * lpSolution = new double[numElements]; double upperObj(0.0); //FIXME: problem is still here. indices may be wrong. //also is all this necessary, or can we just paste together uSol and lSol? for(i = 0; i < numElements; i++){ //index = indices[i]; pos = model->bS_->binarySearch(0, lCols - 1, i, lColIndices); if(pos < 0){ pos = model->bS_->binarySearch(0, uCols - 1, i, uColIndices); //optUpperSolutionOrd[pos] = values[i]; //optUpperSolutionOrd[pos] = uSol[pos]; if (pos >= 0){ optUpperSolutionOrd[pos] = uSol[i]; } } else{ //optLowerSolutionOrd[pos] = lSol[i]; optLowerSolutionOrd[pos] = lSol[pos]; } } for(i = 0; i < uCols; i++){ index = uColIndices[i]; lpSolution[index] = optUpperSolutionOrd[i]; upperObj += optUpperSolutionOrd[i] * hSolver->getObjCoefficients()[index]; } for(i = 0; i < lCols; i++){ index = lColIndices[i]; lpSolution[index] = optLowerSolutionOrd[i]; upperObj += optLowerSolutionOrd[i] * hSolver->getObjCoefficients()[index]; } if(model->checkUpperFeasibility(lpSolution)){ mibSol = new MibSSolution(hSolver->getNumCols(), lpSolution, upperObj * hSolver->getObjSense(), model); model->storeSolution(BlisSolutionTypeHeuristic, mibSol); mibSol = NULL; } delete [] lpSolution; } delete lSolver; } delete hSolver; }