// --------------------------------------------------------------------- // //THINK: this is specific to PC and DC?? void DecompVarPool::reExpand(const DecompConstraintSet& modelCore, const double tolZero) { //THIS IS WRONG... //in masterSI, we have //A'', convexity, cuts //in modelCore.M we have A'', cuts //the sparseCol that you come out with the end here has things in the wrong //order: //A'', cuts, convexity double* denseCol = new double[modelCore.getNumRows() + 1]; vector<DecompWaitingCol>::iterator vi; for (vi = begin(); vi != end(); vi++) { // --- // --- get dense column = A''s, append convexity constraint on end // --- modelCore.M->times((*vi).getVarPtr()->m_s, denseCol); denseCol[modelCore.getNumRows()] = 1.0; // --- // --- create a sparse column from the dense column // --- CoinPackedVector* sparseCol = UtilPackedVectorFromDense(modelCore.getNumRows() + 1, denseCol, tolZero); (*vi).deleteCol(); (*vi).setCol(sparseCol); } setColsAreValid(true); UTIL_DELARR(denseCol); }
//===========================================================================// DecompConstraintSet * ATM_DecompApp::createModelCoreCount(){ UtilPrintFuncBegin(m_osLog, m_classTag, "createModelCoreCount()", m_appParam.LogLevel, 2); int a, nRows; const int nAtms = m_instance.getNAtms(); const int nAtmsSteps = getNAtmsSteps(); const int nCols = numCoreCols(); if(m_appParam.UseTightModel) nRows = 3*nAtms + nAtmsSteps; else nRows = 2*nAtms + 3*nAtmsSteps; int rowCnt = 0; //--- //--- A'' (core): //--- for a in A: //--- sum{d in D} v[a,d] <= K[a] //--- DecompConstraintSet * model = new DecompConstraintSet(); CoinAssertHint(model, "Error: Out of Memory"); //--- //--- create new matrix //--- model->M = new CoinPackedMatrix(false, 0.0, 0.0); CoinAssertHint(model->M, "Error: Out of Memory"); model->M->setDimensions(0, nCols); model->reserve(nRows, nCols); //--- //--- create model constraints //--- for(a = 0; a < nAtms; a++){ rowCnt += createConCount (model, a); rowCnt += createConZtoX (model, a);//OPT rowCnt += createConPickOne(model, a);//OPT } //THINK - add conZtoX to core and remove from relax? printf("nRows = %d, rowCnt = %d\n", nRows, rowCnt); assert(rowCnt == nRows); //--- //--- create model variables/columns //--- createModelColumns(model); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelCoreCount()", m_appParam.LogLevel, 2); return model; }
//===========================================================================// DecompConstraintSet * ATM_DecompApp::createModelCore2(){ UtilPrintFuncBegin(m_osLog, m_classTag, "createModelCore2()", m_appParam.LogLevel, 2); int a; const int nAtms = m_instance.getNAtms(); const int nCols = numCoreCols(); const int nRows = (2*nAtms); int rowCnt = 0; //--- //--- A'' (core): //--- for a in A: //--- sum{t in T} x1[a,t] <= 1 //--- sum{d in D} v[a,d] <= K[a] //--- for a in A, t in T: //--- z[a,t] <= x1[a,t], //--- z[a,t] <= x2[a], //--- z[a,t] >= x1[a,t] + x2[a] - 1. //--- DecompConstraintSet * model = new DecompConstraintSet(); CoinAssertHint(model, "Error: Out of Memory"); //--- //--- create new matrix //--- model->M = new CoinPackedMatrix(false, 0.0, 0.0); CoinAssertHint(model->M, "Error: Out of Memory"); model->M->setDimensions(0, nCols); model->reserve(nRows, nCols); //--- //--- create model constraints //--- for(a = 0; a < nAtms; a++){ rowCnt += createConPickOne(model, a); rowCnt += createConCount (model, a); } printf("nRows = %d, rowCnt = %d\n", nRows, rowCnt); assert(rowCnt == nRows); //--- //--- create model variables/columns //--- createModelColumns(model); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelCore2()", m_appParam.LogLevel, 2); return model; }
//===========================================================================// DecompConstraintSet * ATM_DecompApp::createModelRelaxCount(){ UtilPrintFuncBegin(m_osLog, m_classTag, "createModelRelaxCount()", m_appParam.LogLevel, 2); int a, d, t, nRows, pairIndex, nRowsMax; double rhs, coefA, coefC; pair<int,int> adP; vector<int>::const_iterator vi; const int nSteps = m_appParam.NumSteps; const int nAtms = m_instance.getNAtms(); const int nDates = m_instance.getNDates(); const int nPairs = m_instance.getNPairs(); const int nAtmsSteps = getNAtmsSteps(); const vector<int> & pairsAD = m_instance.getPairsAD(); const double * a_ad = m_instance.get_a_ad(); //dense storage const double * b_ad = m_instance.get_b_ad(); //dense storage const double * c_ad = m_instance.get_c_ad(); //dense storage const double * d_ad = m_instance.get_d_ad(); //dense storage const double * e_ad = m_instance.get_e_ad(); //dense storage const double * w_ad = m_instance.get_w_ad(); //dense storage const double * B_d = m_instance.get_B_d(); const int nCols = numCoreCols(); if(m_appParam.UseTightModel) nRowsMax = nDates + 2*nAtms + nAtmsSteps + 2*nPairs; else nRowsMax = nDates + nAtms + 3*nAtmsSteps + 2*nPairs; //TODO: // try the nested idea - so master has ConZtoX and we price without that // but we solve with gap the harder oracle with those constraints //--- //--- A' (relax): //--- for d in D: //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d] <---- makes it hard //OPT //--- for a in A: //--- sum{t in T} x1[a,t] <= 1 //OPT //--- for a in A, t in T: //--- z[a,t] <= x1[a,t], //--- z[a,t] <= x2[a], //--- z[a,t] >= x1[a,t] + x2[a] - 1. //--- for a in A, d in D: //--- f+[a,d] - f-[a,d] = //--- a[a,d] sum{t in T} (t/n) x1[a,t] + //--- b[a,d] x2[a] + //--- c[a,d] sum{t in T} (t/n) z[a,t] + //--- d[a,d] x3[a] + //--- e[a,d] //--- f-[a,d] <= w[a,d] * v[a,d] //--- DecompConstraintSet * model = new DecompConstraintSet(); CoinAssertHint(model, "Error: Out of Memory"); model->M = new CoinPackedMatrix(false, 0.0, 0.0); CoinAssertHint(model->M, "Error: Out of Memory"); model->M->setDimensions(0, nCols); model->reserve(nRowsMax, nCols); //--- //--- create nDates empty rowBudget packed vectors //--- vector<CoinPackedVector> rowBudget; for(d = 0; d < nDates; d++){ CoinPackedVector row; rowBudget.push_back(row); } nRows = 0; pairIndex = 0; for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){ adP = m_instance.getIndexADInv(*vi); a = adP.first; d = adP.second; //--- //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d] //--- rowBudget[d].insert(getColOffset_fp() + pairIndex, 1.0); rowBudget[d].insert(getColOffset_fm() + pairIndex, -1.0); //--- //--- f+[a,d] - f-[a,d] = //--- a[a,d] sum{t in T} (t/n) x1[a,t] + //--- b[a,d] x2[a] + //--- c[a,d] sum{t in T} (t/n) z[a,t] + //--- d[a,d] x3[a] + //--- e[a,d] //--- CoinPackedVector row; string rowName = "demand_def(a_" + m_instance.getAtmName(a) + ",d_" + m_instance.getDateName(d) + ")"; row.insert(colIndex_fp(pairIndex), 1.0); row.insert(colIndex_fm(pairIndex), -1.0); coefA = -a_ad[*vi] / nSteps; coefC = -c_ad[*vi] / nSteps; if(m_appParam.UseTightModel){ for(t = 0; t <= nSteps; t++){ row.insert(colIndex_x1(a,t), t * coefA); row.insert(colIndex_z (a,t), t * coefC); } } else{ for(t = 0; t < nSteps; t++){ row.insert(colIndex_x1(a,t), (t+1) * coefA); row.insert(colIndex_z (a,t), (t+1) * coefC); } } row.insert(colIndex_x2(a), -b_ad[*vi]); row.insert(colIndex_x3(a), -d_ad[*vi]); rhs = e_ad[*vi]; model->appendRow(row, rhs, rhs, rowName); nRows++; //--- //--- f-[a,d] <= w[a,d] * v[a,d] //--- CoinPackedVector rowLink; string rowNameLink = "linkv(a_" + m_instance.getAtmName(a) + ",d_" + m_instance.getDateName(d) + ")"; rowLink.insert(colIndex_fm(pairIndex), 1.0); rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]); model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink); nRows++; pairIndex++; } for(d = 0; d < nDates; d++){ string rowNameBudget = "budget(d_" + m_instance.getDateName(d) + ")"; model->appendRow(rowBudget[d], -DecompInf, B_d[d], rowNameBudget); nRows++; } //--- //--- for a in A: //--- sum{t in T} x1[a,t] <= 1 //--- for a in A, t in T: //--- z[a,t] <= x1[a,t], //--- z[a,t] <= x2[a], //--- z[a,t] >= x1[a,t] + x2[a] - 1. //--- //THINK: if you use this, shouldn't we postprocess z=x1*x2? // putting those constaints in master are unneccessary... // in fact, why not just do that in block version too... //for(a = 0; a < nAtms; a++){ //nRows += createConZtoX(model, a); //nRows += createConPickOne(model, a); //} assert(nRows <= nRowsMax); //--- //--- create model columns //--- createModelColumns(model); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelRelaxCount()", m_appParam.LogLevel, 2); return model; }
//===========================================================================// DecompConstraintSet * ATM_DecompApp::createModelRelax2(const int d){ UtilPrintFuncBegin(m_osLog, m_classTag, "createModelRelax2()", m_appParam.LogLevel, 2); int a, t, nRows, pairIndex, nRowsMax; double rhs, coefA, coefC; pair<int,int> adP; vector<int>::const_iterator vi; const int nSteps = m_appParam.NumSteps; const int nAtms = m_instance.getNAtms(); const vector<int> & pairsAD = m_instance.getPairsAD(); const double * a_ad = m_instance.get_a_ad(); //dense storage const double * b_ad = m_instance.get_b_ad(); //dense storage const double * c_ad = m_instance.get_c_ad(); //dense storage const double * d_ad = m_instance.get_d_ad(); //dense storage const double * e_ad = m_instance.get_e_ad(); //dense storage const double * w_ad = m_instance.get_w_ad(); //dense storage const double * B_d = m_instance.get_B_d(); const int nCols = numCoreCols(); if(m_appParam.UseTightModel) nRowsMax = 3*nAtms + 1 + getNAtmsSteps(); else nRowsMax = 2*nAtms + 1 + (3*getNAtmsSteps()); //--- //--- A'[d] for d in D (independent blocks) //--- for a in A //--- f+[a,d] - f-[a,d] = //--- a[a,d] sum{t in T} (t/n) x1[a,t] + //--- b[a,d] x2[a] + //--- c[a,d] sum{t in T} (t/n) z[a,t] + //--- d[a,d] x3[a] + //--- e[a,d] //--- f-[a,d] <= w[a,d] * v[a,d] //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d] //--- for a in A, t in T: //--- z[a,t] <= x1[a,t], //--- z[a,t] <= x2[a], //--- z[a,t] >= x1[a,t] + x2[a] - 1. //--- DecompConstraintSet * model = new DecompConstraintSet(); CoinAssertHint(model, "Error: Out of Memory"); model->M = new CoinPackedMatrix(false, 0.0, 0.0); CoinAssertHint(model->M, "Error: Out of Memory"); model->M->setDimensions(0, nCols); model->reserve(nRowsMax, nCols); CoinPackedVector rowBudget; nRows = 0; pairIndex = 0; for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){ adP = m_instance.getIndexADInv(*vi); if(d != adP.second){ pairIndex++; continue; } a = adP.first; //--- //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d] //--- rowBudget.insert(getColOffset_fp() + pairIndex, 1.0); rowBudget.insert(getColOffset_fm() + pairIndex, -1.0); //--- //--- f+[a,d] - f-[a,d] = //--- a[a,d] sum{t in T} (t/n) x1[a,t] + //--- b[a,d] x2[a] + //--- c[a,d] sum{t in T} (t/n) z[a,t] + //--- d[a,d] x3[a] + //--- e[a,d] //--- CoinPackedVector row; string rowName = "demand_def(a_" + m_instance.getAtmName(a) + ",d_" + m_instance.getDateName(d) + ")"; row.insert(colIndex_fp(pairIndex), 1.0); row.insert(colIndex_fm(pairIndex), -1.0); coefA = -a_ad[*vi] / nSteps; coefC = -c_ad[*vi] / nSteps; if(m_appParam.UseTightModel){ for(t = 0; t <= nSteps; t++){ row.insert(colIndex_x1(a,t), t * coefA); row.insert(colIndex_z (a,t), t * coefC); } } else{ for(t = 0; t < nSteps; t++){ row.insert(colIndex_x1(a,t), (t+1) * coefA); row.insert(colIndex_z (a,t), (t+1) * coefC); } } row.insert(colIndex_x2(a), -b_ad[*vi]); row.insert(colIndex_x3(a), -d_ad[*vi]); rhs = e_ad[*vi]; model->appendRow(row, rhs, rhs, rowName); nRows++; //--- //--- f-[a,d] <= w[a,d] * v[a,d] //--- CoinPackedVector rowLink; string rowNameLink = "linkv(a_" + m_instance.getAtmName(a) + ",d_" + m_instance.getDateName(d) + ")"; rowLink.insert(colIndex_fm(pairIndex), 1.0); rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]); model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink); nRows++; pairIndex++; } string rowNameBudget = "budget(d_" + m_instance.getDateName(d) + ")"; model->appendRow(rowBudget, -DecompInf, B_d[d], rowNameBudget); nRows++; for(a = 0; a < nAtms; a++) nRows += createConZtoX(model, a); assert(nRows <= nRowsMax); //--- //--- create model columns //--- createModelColumns(model, -1, d); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelRelax2()", m_appParam.LogLevel, 2); return model; }
//===========================================================================// DecompConstraintSet * ATM_DecompApp::createModelCore1(bool includeCount){ UtilPrintFuncBegin(m_osLog, m_classTag, "createModelCore1()", m_appParam.LogLevel, 2); int a, d, pairIndex; pair<int,int> adP; vector<int>::const_iterator vi; const int nAtms = m_instance.getNAtms(); const int nDates = m_instance.getNDates(); const vector<int> & pairsAD = m_instance.getPairsAD(); const double * B_d = m_instance.get_B_d(); const int nCols = numCoreCols(); int nRows = nDates; if(includeCount) nRows += nAtms; DecompConstraintSet * model = new DecompConstraintSet(); CoinAssertHint(model, "Error: Out of Memory"); model->M = new CoinPackedMatrix(false, 0.0, 0.0); CoinAssertHint(model->M, "Error: Out of Memory"); model->M->setDimensions(0, nCols); model->reserve(nRows, nCols); //--- //--- for d in D: //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d] //--- CoinPackedVector * rowsD = new CoinPackedVector[nDates]; pairIndex = 0; for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){ adP = m_instance.getIndexADInv(*vi); a = adP.first; d = adP.second; rowsD[d].insert(getColOffset_fp() + pairIndex, 1.0); rowsD[d].insert(getColOffset_fm() + pairIndex, -1.0); pairIndex++; } for(d = 0; d < nDates; d++){ string rowName = "budget(d_" + m_instance.getDateName(d) + ")"; model->appendRow(rowsD[d], -DecompInf, B_d[d], rowName); } UTIL_DELARR(rowsD); if(includeCount){ //--- for a in A: //--- sum{d in D} v[a,d] <= K[a] //--- for(a = 0; a < nAtms; a++){ createConCount(model, a); } } //--- //--- create model columns //--- createModelColumns(model); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelCore1()", m_appParam.LogLevel, 2); return model; }
//===========================================================================// void DecompAlgoRC::phaseDone() { //take the current set of variables and solve DW master to get primal //TODO: right now, creating from scratch each time -- really need // to append and warm start - esp if doing alot of branching //delete m_masterSI; //m_masterSI = NULL; //m_masterSI = new OsiLpSolverInterface(); //CoinAssertHint(m_masterSI, "Error: Out of Memory"); //m_masterSI->messageHandler()->setLogLevel(m_param.LogLpLevel); DecompConstraintSet* modelCore = m_modelCore.getModel(); #if 0 //--- //--- Initialize the solver interface for the master problem. //--- PC: min c(s lam) //--- A''s lam >= b'', //--- sum{s} lam_s = 1 , //--- lam_s >= 0 , s in F'[0] //--- modelCore contains [A'', b''], from the original model in //--- terms of x. In this function we create the DW-LP in terms of //--- lambda, [[A''s, 1], [b'', 1]] and load that into the OSI //--- interface m_masterSI. //--- //--- NOTE: if 0 is feasible to subproblem, we can relax convexity to <= 1 //--- UtilPrintFuncBegin(m_osLog, m_classTag, "phaseDone()", m_param.LogDebugLevel, 2); CoinAssert(m_vars.size() > 0); int nColsCore = modelCore->getNumCols(); int nRowsCore = modelCore->getNumRows(); modelCore->nBaseRowsOrig = modelCore->nBaseRows; modelCore->nBaseRows = nRowsCore; //THINK? should initVars be in pool and do addVarsFromPool here? CoinPackedMatrix* M = new CoinPackedMatrix(true, 0, 0); M->setDimensions(nRowsCore + 1, 0); const int n_cols = static_cast<int>(m_vars.size()); double* colLB = new double[n_cols]; double* colUB = new double[n_cols]; double* obj = new double[n_cols]; double* denseCol = new double[nRowsCore + 1]; CoinAssertHint(colLB && colUB && obj && denseCol, "Error: Out of Memory"); int col_index = 0; DecompVarList::iterator li; for (li = m_vars.begin(); li != m_vars.end(); li++) { UTIL_DEBUG(m_param.LogDebugLevel, 5, (*li)->print(m_osLog, m_app); ); //--- //--- get dense column = A''s, append convexity constraint on end //--- modelCore->M->times((*li)->m_s, denseCol); denseCol[nRowsCore] = 1.0; //--- //--- create a sparse column from the dense column //--- // THINK: do i need a DecompCol? // THINK: does this allocate memory for coinpackedvec twice? CoinPackedVector* sparseCol = UtilPackedVectorFromDense(nRowsCore + 1, denseCol, m_param.TolZero); UTIL_DEBUG(m_param.LogDebugLevel, 5, (*m_osLog) << "\nSparse Col: \n"; UtilPrintPackedVector(*sparseCol, m_osLog); );
//===========================================================================// bool DecompAlgoModel::isPointFeasible(const double* x, const bool isXSparse, const int logLevel, const double feasVarTol, const double feasConTol) { DecompConstraintSet* model = getModel(); if (!model) { return true; } const CoinPackedMatrix* M = model->getMatrix(); if (!M) { return true; } const vector<string>& colNames = model->getColNames(); const vector<string>& rowNames = model->getRowNames(); int c, r, i; bool isFeas = true; bool hasColNames = false; bool hasRowNames = false; double xj = 0.0; double ax = 0.0; double clb = 0.0; double cub = 0.0; double rlb = 0.0; double rub = 0.0; double actViol = 0.0; double relViol = 0.0; if (colNames.size()) { hasColNames = true; } if (rowNames.size()) { hasRowNames = true; } double feasVarTol10 = 10 * feasVarTol; double feasConTol10 = 10 * feasConTol; //--- //--- do we satisfy all (active) column bounds //--- vector<int> ::const_iterator it; map<int, int>::const_iterator mcit; const vector<int>& activeColumns = model->getActiveColumns(); bool isSparse = model->isSparse(); const map<int, int>& origToSparse = model->getMapOrigToSparse(); const map<int, int>& sparseToOrig = model->getMapSparseToOrig(); for (it = activeColumns.begin(); it != activeColumns.end(); it++) { if (isSparse) { mcit = origToSparse.find(*it); c = mcit->second; xj = isXSparse ? x[c] : x[*it]; } else { c = *it; xj = x[c]; assert(!isXSparse); } clb = model->colLB[c]; cub = model->colUB[c]; UTIL_DEBUG(logLevel, 5, int precision = 7; if (!UtilIsZero(xj)) { cout << "Point " << c; if (hasColNames) { cout << " -> " << colNames[c]; } cout << " LB= " << UtilDblToStr(clb, precision) << " x= " << UtilDblToStr(xj, precision) << " UB= " << UtilDblToStr(cub, precision) << endl; } ); actViol = std::max<double>(clb - xj, xj - cub); actViol = std::max<double>(actViol, 0.0); if (UtilIsZero(xj, feasVarTol) || (xj < 0 && UtilIsZero(clb)) || (xj > 0 && UtilIsZero(cub))) { relViol = actViol; } else { relViol = actViol / std::fabs(xj); } if (relViol > feasVarTol) { //Notify, but don't mark in feasible unless 10x worse. UTIL_DEBUG(logLevel, 4, int precision = 7; cout << "Point violates column " << c; if (hasColNames) cout << " -> " << colNames[c]; cout << " LB= " << UtilDblToStr(clb, precision) << " x= " << UtilDblToStr(xj, precision) << " UB= " << UtilDblToStr(cub, precision) << " RelViol= " << UtilDblToStr(relViol, precision) << endl; );