bool HyperheuristicQUBOCallback::Report(const QUBOSimpleSolution& solution, bool newBest, double runtime) { if (newBest) { // Need to convert from QUBO to Max-Cut and report MaxCutSimpleSolution mcSol(solution, mi_, mch_); return mch_->Report(mcSol); } else { return mch_->Report(); // Not new best solution, so just check term. crit. } }
//############################################################################# void MibSHeuristic::weightedSumsHeuristic() { std::queue< SolPair > probQueue; std::list< double > BETAS; std::map<double, mcSol> mcSolutions; mcSol sol0 = mcSol(); mcSol sol1 = mcSol(); mcSol sol = mcSol(); double beta(0.0); double slope(0.0); double etol(etol_); BETAS.push_back(1.0); BETAS.push_back(0.0); /** First solve the subproblem for beta = 1 and beta = 0 **/ sol1 = solveSubproblem(1.0); // beta = 1 numProblems_++; mcSolutions.insert(std::make_pair(1.0, sol1)); int i(0); int tCols(MibSModel_->getLowerDim() + MibSModel_->getUpperDim()); if(0){ std::cout << "supported solution added." << std::endl; std::cout << "support obj value: " << sol1.getObjPair().second << std::endl; std::cout << "upper obj value: " << sol1.getObjPair().first << std::endl; for(i = 0; i < tCols; i++){ std::cout << "sol1[" << i << "]: " << sol1.getColumnSol()[i] << std::endl; } } sol0 = solveSubproblem(0.0);// beta = 0 numProblems_++; mcSolutions.insert(std::make_pair(0.0, sol0)); if(0){ std::cout << "supported solution added." << std::endl; std::cout << "support obj value: " << sol0.getObjPair().second << std::endl; std::cout << "upper obj value: " << sol0.getObjPair().first << std::endl; for(i = 0; i < tCols; i++){ std::cout << "sol0[" << i << "]" << sol0.getColumnSol()[i] << std::endl; } } probQueue.push(SolPair(sol1.getObjPair(), sol0.getObjPair())); double delta_y(0.0); double delta_x(0.0); while(probQueue.size() > 0){ /** Get the first pair in the queue **/ SolPair sP = probQueue.front(); /** Remove the first pair **/ probQueue.pop(); delta_y = sP.getFirst().second - sP.getSecond().second; delta_x = sP.getSecond().first - sP.getFirst().first; if((fabs(delta_y) > etol) && (fabs(delta_x) > etol)){ slope = delta_y / delta_x; beta = slope/(1 + slope); /** should probably add a tolerance here **/ if(find(BETAS.begin(), BETAS.end(), beta) == BETAS.end()){ std::cout << "Solving with beta = " << beta << std::endl; BETAS.push_back(beta); sol = solveSubproblem(beta); numProblems_++; /*******************************************/ /* If the outcome does not already exist, */ /* add it to the solutions list and create */ /* two new solution pairs to be analyzed */ /*******************************************/ double pair1(sol.getObjPair().first - sP.getFirst().first); double pair2(sol.getObjPair().second - sP.getFirst().second); double pair3(sol.getObjPair().first - sP.getSecond().first); double pair4(sol.getObjPair().second - sP.getSecond().second); if(((fabs(pair1) > etol) && (fabs(pair2) > etol)) && ((fabs(pair3) > etol) && (fabs(pair4) > etol))){ mcSolutions.insert(std::make_pair(beta, sol)); if(0){ std::cout << "supported solution added." << std::endl; std::cout << "support obj value: " << sol.getObjPair().second << std::endl; std::cout << "upper obj value: " << sol.getObjPair().first << std::endl; for(i = 0; i < tCols; i++){ std::cout << "sol[" << i << "]: " << sol.getColumnSol()[i] << std::endl; } } probQueue.push(SolPair(sP.getFirst(), sol.getObjPair())); probQueue.push(SolPair(sol.getObjPair(), sP.getSecond())); } } else{ std::cout << "Repeated beta value. Skipping problem pair." <<std::endl; } } } createBilevelSolutions(mcSolutions); }
//############################################################################# mcSol MibSHeuristic::solveSubproblem(double beta) { /* optimize wrt to weighted upper-level objective over current feasible lp feasible region */ MibSModel * model = MibSModel_; OsiSolverInterface * oSolver = model->getSolver(); //OsiSolverInterface * sSolver = new OsiCbcSolverInterface(); OsiSolverInterface* sSolver = new OsiSymSolverInterface(); //sSolver = oSolver->clone(); //OsiSolverInterface * sSolver = tmpSolver; //OsiSolverInterface * tmpSolver = new OsiSolverInterface(oSolver); double uObjSense(oSolver->getObjSense()); double lObjSense(model->getLowerObjSense()); int lCols(model->getLowerDim()); int uCols(model->getUpperDim()); int * lColIndices = model->getLowerColInd(); int * uColIndices = model->getUpperColInd(); double * lObjCoeffs = model->getLowerObjCoeffs(); const double * uObjCoeffs = oSolver->getObjCoefficients(); double etol(etol_); int tCols(uCols + lCols); assert(tCols == oSolver->getNumCols()); sSolver->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)) sSolver->setInteger(j); } double * nObjCoeffs = new double[tCols]; int i(0), index(0); CoinZeroN(nObjCoeffs, tCols); /* Multiply the UL columns of the UL objective by beta */ for(i = 0; i < uCols; i++){ index = uColIndices[i]; if(fabs(uObjCoeffs[index]) > etol) nObjCoeffs[index] = beta * uObjCoeffs[index] * uObjSense; else nObjCoeffs[index] = 0.0; } /* Multiply the LL columns of the UL objective by beta */ for(i = 0; i < lCols; i++){ index = lColIndices[i]; if(fabs(uObjCoeffs[index]) > etol) nObjCoeffs[index] = beta* uObjCoeffs[index] * uObjSense; else nObjCoeffs[index] = 0.0; } /* Add the LL columns of the LL objective multiplied by (1 - beta) */ for(i = 0; i < lCols; i++){ index = lColIndices[i]; if(fabs(lObjCoeffs[i]) > etol) nObjCoeffs[index] += (1 - beta) * lObjCoeffs[i] * lObjSense; } sSolver->setObjective(nObjCoeffs); //int i(0); if(0){ for(i = 0; i < sSolver->getNumCols(); i++){ std::cout << "betaobj " << sSolver->getObjCoefficients()[i] << std::endl; } } if(0){ sSolver->writeLp("afterbeta"); //sSolver->writeMps("afterbeta"); } if(0){ for(i = 0; i < sSolver->getNumCols(); i++){ std::cout << "obj " << sSolver->getObjCoefficients()[i] << std::endl; std::cout << "upper " << sSolver->getColUpper()[i] << std::endl; std::cout << "lower " << sSolver->getColLower()[i] << std::endl; } } if(0){ dynamic_cast<OsiCbcSolverInterface *> (sSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (sSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (sSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (sSolver)->setSymParam("max_active_nodes", 1); } //dynamic_cast<OsiSymSolverInterface *> (sSolver)->branchAndBound(); sSolver->branchAndBound(); if(sSolver->isProvenOptimal()){ if(0){ std::cout << "writing lp file." << std::endl; sSolver->writeLp("afterbeta"); //sSolver->writeMps("afterbeta"); } double upperObjVal(0.0); double lowerObjVal(0.0); for(i = 0; i < tCols; i++){ upperObjVal += sSolver->getColSolution()[i] * oSolver->getObjCoefficients()[i]; if(0){ std::cout << "sSolver->getColSolution()[" << i << "] :" << sSolver->getColSolution()[i] << std::endl; } } lowerObjVal = getLowerObj(sSolver->getColSolution(), lObjSense); if(beta == 1.0){ /* fix upper-level objective to current value and reoptimize wrt to lower-level objective */ //OsiSolverInterface * nSolver = new OsiCbcSolverInterface(); OsiSolverInterface * nSolver = new OsiSymSolverInterface(); nSolver->loadProblem(*oSolver->getMatrixByCol(), oSolver->getColLower(), oSolver->getColUpper(), oSolver->getObjCoefficients(), oSolver->getRowLower(), oSolver->getRowUpper()); for(j = 0; j < tCols; j++){ if(oSolver->isInteger(j)) nSolver->setInteger(j); } CoinZeroN(nObjCoeffs, tCols); for(i = 0; i < lCols; i++){ index = lColIndices[i]; nObjCoeffs[index] = lObjCoeffs[i] * lObjSense; } nSolver->setObjective(nObjCoeffs); CoinPackedVector objCon; for(i = 0; i < tCols; i++){ objCon.insert(i, uObjCoeffs[i] * uObjSense); } nSolver->addRow(objCon, upperObjVal, upperObjVal); nSolver->writeLp("beta1"); if(0){ dynamic_cast<OsiCbcSolverInterface *> (nSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("max_active_nodes", 1); } nSolver->branchAndBound(); double * colsol = new double[tCols]; if(nSolver->isProvenOptimal()){ lowerObjVal = nSolver->getObjValue(); CoinCopyN(nSolver->getColSolution(), tCols, colsol); } else{ //just take the current solution lowerObjVal = sSolver->getObjValue(); CoinCopyN(sSolver->getColSolution(), tCols, colsol); } delete[] nObjCoeffs; nObjCoeffs = 0; delete sSolver; delete nSolver; return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol); } else if(beta == 0.0){ /* fix lower-level objective to current value and reoptimize wrt to upper-level objective */ //OsiSolverInterface * nSolver = new OsiCbcSolverInterface(); OsiSolverInterface * nSolver = new OsiSymSolverInterface(); nSolver->loadProblem(*oSolver->getMatrixByCol(), oSolver->getColLower(), oSolver->getColUpper(), oSolver->getObjCoefficients(), oSolver->getRowLower(), oSolver->getRowUpper()); for(j = 0; j < tCols; j++){ if(oSolver->isInteger(j)) nSolver->setInteger(j); } CoinZeroN(nObjCoeffs, tCols); for(i = 0; i < tCols; i++) nObjCoeffs[i] = uObjCoeffs[i] * uObjSense; nSolver->setObjective(nObjCoeffs); CoinPackedVector objCon; for(i = 0; i < lCols; i++){ index = lColIndices[i]; objCon.insert(index, lObjCoeffs[i] * lObjSense); } nSolver->addRow(objCon, lowerObjVal, lowerObjVal); if(0){ dynamic_cast<OsiCbcSolverInterface *> (nSolver)->getModelPtr()->messageHandler()->setLogLevel(0); } else{ dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("prep_level", -1); dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("verbosity", -2); dynamic_cast<OsiSymSolverInterface *> (nSolver)->setSymParam("max_active_nodes", 1); } if(0) nSolver->writeLp("nSolver"); nSolver->branchAndBound(); double * colsol = new double[tCols]; if(nSolver->isProvenOptimal()){ upperObjVal = nSolver->getObjValue(); CoinCopyN(nSolver->getColSolution(), tCols, colsol); } else{ upperObjVal = nSolver->getObjValue(); CoinCopyN(nSolver->getColSolution(), tCols, colsol); } delete[] nObjCoeffs; nObjCoeffs = 0; delete sSolver; delete nSolver; return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol); } else{ //no optimality cut needed here. all solutions are supported. double * colsol = new double[tCols]; CoinCopyN(sSolver->getColSolution(), tCols, colsol); delete[] nObjCoeffs; nObjCoeffs = 0; delete sSolver; return mcSol(std::make_pair(upperObjVal, lowerObjVal), colsol); } } else{ //FIXME:SHOULD JUST TAKE THIS OUT. DELETE sSolver and remove it from above nObjCoeffs = 0; delete[] nObjCoeffs; delete sSolver; std::cout << "Subproblem is not proven optimal." << std::endl; //return NULL; //abort(); } }