SPxBasis::Desc::Desc(const SPxSolver& base) { rowstat.reSize(base.nRows()); colstat.reSize(base.nCols()); if (base.rep() == SPxSolver::ROW) { stat = &rowstat; costat = &colstat; } else { assert(base.rep() == SPxSolver::COLUMN); stat = &colstat; costat = &rowstat; } assert(Desc::isConsistent()); }
void SPxSumST::setupWeights(SPxSolver& base) { int count; int i; Real x; DVector work, delta, rowLen; rowLen.reDim( base.nRows() ); work.reDim (base.nCols()); delta.reDim (base.nCols()); Real* wrk = work.get_ptr(); const Real* lhs = base.lhs().get_const_ptr(); const Real* rhs = base.rhs().get_const_ptr(); const Real* up = base.upper().get_const_ptr(); const Real* low = base.lower().get_const_ptr(); for (i = base.nRows(); --i >= 0;) { rowLen[i] = base.rowVector(i).length2(); if (lhs[i] > 0) delta.multAdd(lhs[i] / rowLen[i], base.rowVector(i)); else if (rhs[i] < 0) delta.multAdd(rhs[i] / rowLen[i], base.rowVector(i)); } for (count = 0;; count++) { work += delta; for (i = base.nCols(); --i >= 0;) { if (wrk[i] > up[i]) wrk[i] = up[i]; if (wrk[i] < low[i]) wrk[i] = low[i]; } // std::cout << -(work * base.maxObj()) << std::endl; if (count >= 12) break; delta.clear(); for (i = base.nRows(); --i >= 0;) { x = base.rowVector(i) * work; if (lhs[i] > x) delta.multAdd((lhs[i] - x) / rowLen[i], base.rowVector(i)); else if (rhs[i] < x) delta.multAdd((rhs[i] - x) / rowLen[i], base.rowVector(i)); } } primal(work); SPxVectorST::setupWeights(base); }
// ---------------------------------------------------------------- void SPxWeightST::generate(SPxSolver& base) { SPxId tmpId; forbidden.reSize(base.dim()); rowWeight.reSize(base.nRows()); colWeight.reSize(base.nCols()); rowRight.reSize (base.nRows()); colUp.reSize (base.nCols()); if (base.rep() == SPxSolver::COLUMN) { weight = &colWeight; coWeight = &rowWeight; } else { weight = &rowWeight; coWeight = &colWeight; } assert(weight->size() == base.coDim()); assert(coWeight->size() == base.dim()); setupWeights(base); SPxBasis::Desc desc(base); // desc.reSize(base.nRows(), base.nCols()); DataArray < SPxId > pref(base.nRows() + base.nCols()); initPrefs(pref, base, rowWeight, colWeight); int i; int deltai; int j; int sel; for(i = 0; i < forbidden.size(); ++i) forbidden[i] = 0; if (base.rep() == SPxSolver::COLUMN) { i = 0; deltai = 1; } else { i = pref.size() - 1; deltai = -1; } { int dim = base.dim(); Real max = 0; for (; i >= 0 && i < pref.size(); i += deltai) { tmpId = pref[i]; const SVector& bVec = base.vector(tmpId); sel = -1; // column or row singleton ? if (bVec.size() == 1) { int idx = bVec.index(0); if (forbidden[idx] < 2) { sel = idx; dim += (forbidden[idx] > 0) ? 1 : 0; } } else { max = bVec.maxAbs(); int best = base.nRows(); for (j = bVec.size(); --j >= 0;) { Real x = bVec.value(j); int k = bVec.index(j); int l = base.coVector(k).size(); if (!forbidden[k] && (fabs(x) > STABLE * max) && (l < best)) { best = l; sel = k; } } } if (sel >= 0) { MSG_DEBUG( if (pref[i].type() == SPxId::ROW_ID) spxout << "DWEIST01 r" << base.number(pref[i]); else spxout << "DWEIST02 c" << base.number(pref[i]); ) forbidden[sel] = 2; if (base.rep() == SPxSolver::COLUMN) setDualStatus(desc, base, pref[i]); else setPrimalStatus(desc, base, pref[i]); for (j = bVec.size(); --j >= 0;) { Real x = bVec.value(j); int k = bVec.index(j); if (!forbidden[k] && (x > EPS * max || -x > EPS * max)) { forbidden[k] = 1; --dim; } } if (--dim == 0) { //@ for(++i; i < pref.size(); ++i) if (base.rep() == SPxSolver::COLUMN) { for (i += deltai; i >= 0 && i < pref.size(); i += deltai) setPrimalStatus(desc, base, pref[i]); for (i = forbidden.size(); --i >= 0;) { if (forbidden[i] < 2) setDualStatus(desc, base, base.coId(i)); } } else { for (i += deltai; i >= 0 && i < pref.size(); i += deltai) setDualStatus(desc, base, pref[i]); for (i = forbidden.size(); --i >= 0;) { if (forbidden[i] < 2) setPrimalStatus(desc, base, base.coId(i)); } } break; } } else if (base.rep() == SPxSolver::COLUMN)
// ---------------------------------------------------------------- void SPxWeightST::generate(SPxSolver& base) { SPxId tmpId; forbidden.reSize(base.dim()); rowWeight.reSize(base.nRows()); colWeight.reSize(base.nCols()); rowRight.reSize (base.nRows()); colUp.reSize (base.nCols()); if (base.rep() == SPxSolver::COLUMN) { weight = &colWeight; coWeight = &rowWeight; } else { weight = &rowWeight; coWeight = &colWeight; } assert(weight->size() == base.coDim()); assert(coWeight->size() == base.dim()); setupWeights(base); SPxBasis::Desc desc(base); // desc.reSize(base.nRows(), base.nCols()); DataArray < SPxId > pref(base.nRows() + base.nCols()); initPrefs(pref, base, rowWeight, colWeight); int i; int stepi; int j; int sel; for(i = 0; i < base.dim(); ++i) forbidden[i] = 0; if (base.rep() == SPxSolver::COLUMN) { // in COLUMN rep we scan from beginning to end i = 0; stepi = 1; } else { // in ROW rep we scan from end to beginning i = pref.size() - 1; stepi = -1; } int dim = base.dim(); Real maxEntry = 0; for (; i >= 0 && i < pref.size(); i += stepi) { tmpId = pref[i]; const SVector& vec = base.vector(tmpId); sel = -1; // column or row singleton ? if (vec.size() == 1) { int idx = vec.index(0); if (forbidden[idx] < 2) { sel = idx; dim += (forbidden[idx] > 0) ? 1 : 0; } } else { maxEntry = vec.maxAbs(); // initialize the nonzero counter int minRowEntries = base.nRows(); // find a stable index with a sparse row/column for (j = vec.size(); --j >= 0;) { Real x = vec.value(j); int k = vec.index(j); int nRowEntries = base.coVector(k).size(); if (!forbidden[k] && (spxAbs(x) > STABLE * maxEntry) && (nRowEntries < minRowEntries)) { minRowEntries = nRowEntries; sel = k; } } } // we found a valid index if (sel >= 0) { MSG_DEBUG( if (pref[i].type() == SPxId::ROW_ID) std::cout << "DWEIST01 r" << base.number(pref[i]); else std::cout << "DWEIST02 c" << base.number(pref[i]); ) forbidden[sel] = 2; // put current column/row into basis if (base.rep() == SPxSolver::COLUMN) setDualStatus(desc, base, pref[i]); else setPrimalStatus(desc, base, pref[i]); for (j = vec.size(); --j >= 0;) { Real x = vec.value(j); int k = vec.index(j); if (!forbidden[k] && (x > EPS * maxEntry || -x > EPS * maxEntry)) { forbidden[k] = 1; --dim; } } if (--dim == 0) { //@ for(++i; i < pref.size(); ++i) if (base.rep() == SPxSolver::COLUMN) { // set all remaining indeces to nonbasic status for (i += stepi; i >= 0 && i < pref.size(); i += stepi) setPrimalStatus(desc, base, pref[i]); // fill up the basis wherever linear independence is assured for (i = forbidden.size(); --i >= 0;) { if (forbidden[i] < 2) setDualStatus(desc, base, base.coId(i)); } } else { for (i += stepi; i >= 0 && i < pref.size(); i += stepi) setDualStatus(desc, base, pref[i]); for (i = forbidden.size(); --i >= 0;) { if (forbidden[i] < 2) setPrimalStatus(desc, base, base.coId(i)); } } break; } }