BdMaster::~BdMaster() { FREE_PTR(si_); FREE_ARRAY_PTR(obj_aux_); FREE_ARRAY_PTR(clbd_aux_); FREE_ARRAY_PTR(cubd_aux_); }
DspDriver::~DspDriver() { par_ = NULL; model_ = NULL; FREE_PTR(message_); FREE_ARRAY_PTR(primsol_); FREE_ARRAY_PTR(dualsol_); }
BdDriver::~BdDriver() { FREE_PTR(mw_); FREE_ARRAY_PTR(aux_obj_); FREE_ARRAY_PTR(aux_clbd_); FREE_ARRAY_PTR(aux_cubd_); FREE_ARRAY_PTR(priorities_); FREE_ARRAY_PTR(primsol_); }
TssBd::~TssBd() { FREE_PTR(si_); FREE_ARRAY_PTR(augs_); FREE_ARRAY_PTR(obj_aux_); FREE_ARRAY_PTR(clbd_aux_); FREE_ARRAY_PTR(cubd_aux_); naugs_ = 0; naux_ = 0; }
DSP_RTN_CODE BdDriver::setAuxVarData( int size, /**< size of arrays */ double * obj, /**< objective function coefficients */ double * clbd, /**< column lower bounds */ double * cubd /**< column upper bounds */) { if (size <= 0) return DSP_RTN_ERR; BGN_TRY_CATCH FREE_ARRAY_PTR(aux_obj_) FREE_ARRAY_PTR(aux_clbd_) FREE_ARRAY_PTR(aux_cubd_) aux_size_ = size; aux_obj_ = new double [size]; aux_clbd_ = new double [size]; aux_cubd_ = new double [size]; CoinCopyN(obj, size, aux_obj_); CoinCopyN(clbd, size, aux_clbd_); CoinCopyN(cubd, size, aux_cubd_); END_TRY_CATCH_RTN(;,DSP_RTN_ERR)
DetModel::~DetModel() { FREE_PTR(mat_); FREE_ARRAY_PTR(clbd_); FREE_ARRAY_PTR(cubd_); FREE_ARRAY_PTR(ctype_); FREE_ARRAY_PTR(obj_); FREE_ARRAY_PTR(rlbd_); FREE_ARRAY_PTR(rubd_); nints_ = 0; }
DSP_RTN_CODE BlkModel::updateBlocks() { #define FREE_MEMORY \ FREE_ARRAY_PTR(ncols_coupled); int* ncols_coupled = NULL; BGN_TRY_CATCH std::vector<int> blockids; for (Blocks::iterator it = blocks_.begin(); it != blocks_.end(); ++it) blockids.push_back(it->first); double stime = CoinGetTimeOfDay(); /** number of blocks */ if (blockids.size() > 0) { /** coupling columns and rows */ std::vector<int> master_coupling_cols; /** retrieve master information */ DetBlock* master = block(blockids[0]); if (master == NULL) return DSP_RTN_ERR; const CoinPackedMatrix* master_mat = master->getConstraintMatrix(); /** get number of columns, rows and integers */ ncols_full_ = master->getNumCols(); nrows_full_ = master->getNumRows(); nints_full_ = master->getNumIntegers(); /** to count how many subproblems are coupled with each column of the master. */ ncols_coupled = new int [master->getNumCols()]; CoinZeroN(ncols_coupled, master->getNumCols()); for (unsigned i = 1; i < blockids.size(); ++i) { /** coupling columns and rows */ std::vector<int> sub_coupling_cols; std::vector<int> sub_coupling_rows; /** retrieve subproblem */ int id = blockids[i]; DetBlock* sub = block(id); if (sub == NULL) return DSP_RTN_ERR; /** mark it is a dual block angular matrix */ if (sub->getNumCols() > master->getNumCols()) dual_block_angular_ = true; /** retrieve subproblem column indices */ const CoinPackedMatrix* sub_mat = sub->getConstraintMatrix(); int sub_num_col_indices = sub_mat->isColOrdered() ? sub_mat->getNumCols() : sub_mat->getNumElements(); int* sub_col_indices = new int [sub_num_col_indices]; if (sub_mat->isColOrdered()) CoinCopyN(sub_mat->getVectorStarts(), sub_num_col_indices, sub_col_indices); else CoinCopyN(sub_mat->getIndices(), sub_num_col_indices, sub_col_indices); /** add number of columns, rows and integers */ ncols_full_ += sub->getNumCols() - master->getNumCols(); nrows_full_ += sub->getNumRows() - master->getNumRows(); nints_full_ += sub->getNumIntegers() - master->getNumIntegers(); /** sort indices to speed up the search */ std::sort(sub_col_indices, sub_col_indices + sub_num_col_indices); /** find coupling columns and rows */ for (int j = 0; j < sub_num_col_indices; ++j) { if (j > 0 && sub_col_indices[j-1] == sub_col_indices[j]) continue; if (sub_col_indices[j] < master_mat->getNumCols()) { master_coupling_cols.push_back(sub_col_indices[j]); sub_coupling_cols.push_back(sub_col_indices[j]); /** find all the coupling rows */ for (int row = 0; row < master->getNumRows(); ++row) { if (fabs(master_mat->getCoefficient(row, sub_col_indices[j])) > 1.0e-8) sub_coupling_rows.push_back(row); } } } /** erase duplicates */ std::sort(sub_coupling_cols.begin(), sub_coupling_cols.end()); sub_coupling_cols.erase( std::unique(sub_coupling_cols.begin(), sub_coupling_cols.end()), sub_coupling_cols.end()); std::sort(sub_coupling_rows.begin(), sub_coupling_rows.end()); sub_coupling_rows.erase( std::unique(sub_coupling_rows.begin(), sub_coupling_rows.end()), sub_coupling_rows.end()); /** set coupling columns and rows */ sub->setCouplingCols(sub_coupling_cols.size(), &sub_coupling_cols[0]); sub->setCouplingRows(sub_coupling_rows.size(), &sub_coupling_rows[0]); DSPdebugMessage("Coupling columns of block %d:\n", id); DSPdebug(DspMessage::printArray(sub->getNumCouplingCols(), sub->getCouplingCols())); DSPdebugMessage("Coupling rows of block %d:\n", id); DSPdebug(DspMessage::printArray(sub->getNumCouplingRows(), sub->getCouplingRows())); /** count the master columns coupled */ for (unsigned j = 0; j < sub_coupling_cols.size(); ++j) ncols_coupled[sub_coupling_cols[j]]++; } /** erase duplicates */ std::sort(master_coupling_cols.begin(), master_coupling_cols.end()); master_coupling_cols.erase( std::unique(master_coupling_cols.begin(), master_coupling_cols.end()), master_coupling_cols.end()); /** set coupling columns */ master->setCouplingCols(master_coupling_cols.size(), &master_coupling_cols[0]); /** set coupling rows */ int* master_coupling_rows = new int [master->getNumRows()]; for (int i = 0; i < master->getNumRows(); ++i) master_coupling_rows[i] = i; master->setCouplingRows(master->getNumRows(), master_coupling_rows); FREE_ARRAY_PTR(master_coupling_rows); #if 0 /** check if the full matrix is of a primal block angular form. */ primal_block_angular_ = true; for (int j = 0; j < master->getNumCols(); ++j) if (ncols_coupled[j] > 1) primal_block_angular_ = false; if (primal_block_angular_ == true) printf("The constraint matrix is of a primal block angular.\n"); if (dual_block_angular_ == true) printf("The constraint matrix is of a dual block angular.\n"); #endif } DSPdebugMessage("Update block time: %.4f\n", CoinGetTimeOfDay() - stime); END_TRY_CATCH_RTN(FREE_MEMORY,DSP_RTN_ERR) FREE_MEMORY return DSP_RTN_OK; #undef FREE_MEMORY }
/** solve */ STO_RTN_CODE TssBd::solve() { #define FREE_MEMORY \ FREE_PTR(tssbdsub) assert(model_); /** subproblems */ const double * probability = NULL; /**< probability */ TssBdSub * tssbdsub = NULL; /**< cut generator */ double lowerbound = 0.0; BGN_TRY_CATCH /** solution time */ double swtime = CoinGetTimeOfDay(); /** time limit */ time_remains_ = par_->wtimeLimit_; /** get number of scenarios */ probability = model_->getProbability(); /** configure Benders cut generator */ /** This does NOT make deep copies. So, DO NOT RELEASE POINTERS. */ tssbdsub = new TssBdSub(par_); for (int s = 0; s < model_->getNumScenarios(); ++s) tssbdsub->scenarios_.push_back(s); STO_RTN_CHECK_THROW(tssbdsub->loadProblem(model_, naugs_, augs_, naux_), "loadProblem", "TssBdSub"); if (par_->logLevel_ > 0) printf("Phase 1:\n"); /** solution time */ double stime = clockType_ ? CoinGetTimeOfDay() : CoinCpuTime(); /** find lower bound */ /** TODO: replace this with TssDd */ STO_RTN_CHECK_THROW(findLowerBound(probability, lowerbound), "findLowerBound", "TssBd"); /** We should have a lower bound here. */ if (par_->logLevel_ > 0) printf(" -> Found lower bound %e\n", lowerbound); /** construct master problem */ STO_RTN_CHECK_THROW(constructMasterProblem(tssbdsub, lowerbound), "constructMasterProblem", "TssBd"); if (par_->logLevel_ > 0) printf("Phase 2:\n"); time_remains_ -= CoinGetTimeOfDay() - swtime; /** use L-shaped method to find lower bound */ if (model_->getNumCoreIntegers() == 0) { /** configure LP */ STO_RTN_CHECK_THROW(configureSLP(), "configureSLP", "TssBd"); /** solve LP */ STO_RTN_CHECK_THROW(solveSLP(tssbdsub), "solveSLP", "TssBd"); } else { /** configure MILP */ STO_RTN_CHECK_THROW(configureSMILP(tssbdsub), "configureSMILP", "TssBd"); /** solve MILP */ STO_RTN_CHECK_THROW(solveSMILP(), "solveSMILP", "TssBd"); } /** solution time */ solutionTime_ = (clockType_ ? CoinGetTimeOfDay() : CoinCpuTime()) - stime; /** collect solution */ switch (status_) { case STO_STAT_OPTIMAL: case STO_STAT_LIM_ITERorTIME: case STO_STAT_STOPPED_GAP: case STO_STAT_STOPPED_NODE: case STO_STAT_STOPPED_TIME: { const double * solution = si_->getSolution(); if (solution) { /** first-stage solution */ assert(solution_); CoinCopyN(solution, model_->getNumCols(0), solution_); /** second-stage solution */ double * objval_reco = new double [model_->getNumScenarios()]; double ** solution_reco = new double * [model_->getNumScenarios()]; for (int s = 0; s < model_->getNumScenarios(); ++s) solution_reco[s] = new double [model_->getNumCols(1)]; for (int s = 0; s < naugs_; ++s) CoinCopyN(solution + model_->getNumCols(0) + s * model_->getNumCols(1), model_->getNumCols(1), solution_reco[augs_[s]]); /** collect solution */ tssbdsub->solveRecourse(solution_, objval_reco, solution_reco, par_->numCores_); for (int s = 0; s < model_->getNumScenarios(); ++s) { if (tssbdsub->excludedScenarios_[s]) continue; CoinCopyN(solution_reco[s], model_->getNumCols(1), solution_ + model_->getNumCols(0) + model_->getNumCols(1) * s); } /** compute primal bound */ primalBound_ = 0.0; for (int j = 0; j < model_->getNumCols(0); ++j) primalBound_ += model_->getObjCore(0)[j] * solution_[j]; for (int s = 0; s < model_->getNumScenarios(); ++s) { primalBound_ += objval_reco[s] * model_->getProbability()[s]; } //printf("primalBound %e\n", primalBound_); /** free memory */ FREE_ARRAY_PTR(objval_reco); FREE_2D_ARRAY_PTR(model_->getNumScenarios(), solution_reco); } break; } break; default: printf("Solution status (%d).\n", status_); break; } END_TRY_CATCH_RTN(FREE_MEMORY,STO_RTN_ERR) /** free memory */ FREE_MEMORY return STO_RTN_OK; #undef FREE_MEMORY }