Пример #1
0
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.
  }
}
Пример #2
0
//#############################################################################
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);

}
Пример #3
0
//#############################################################################
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();
  }
}