int Variable::genColumn( Active<Constraint, Variable> *actCon, Column &col) const { double eps = master_->machineEps(); double minusEps = -eps; int n = actCon->number(); expand(); for (int i = 0; i < n; i++) { double co = (*actCon)[i]->coeff(this); if (co > eps || co < minusEps) col.insert(i,co); } col.obj(obj()); col.lBound(lBound()); col.uBound(uBound()); compress(); return col.nnz(); }
void LpSub::addVars( ArrayBuffer<Variable*> &vars, ArrayBuffer<FSVarStat*> &fsVarStat, ArrayBuffer<double> &lb, ArrayBuffer<double> &ub) { // LpSub::addVars(): local variables ArrayBuffer<int> delVar(vars.size(),false); //!< the eliminated variables Array<double> rhsDelta(0,sub_->nCon()-1, 0.0); //!< the correction of the rhs double vValue; double coeff; bool modifyRhs = false; //!< if \a true the modification of rhs required int oldNCol = trueNCol(); int n = trueNCol(); Variable *v; // divide the added variables in eliminable and non-eliminable ones int nVariables = vars.size(); for (int i = 0; i < nVariables; i++) { v = vars[i]; if(fsVarStat[i]->fixedOrSet()) { if (eliminable(i)) { //! the new variable is eliminated delVar.push(i); vValue = elimVal(fsVarStat[i], lb[i], ub[i]); valueAdd_ += v->obj() * vValue; orig2lp_[nOrigVar_++] = -1; const int nCon = sub_->nCon(); for (int c = 0; c < nCon; c++) { coeff = sub_->constraint(c)->coeff(v); if (fabs(coeff) > master_->eps()) { rhsDelta[c] += vValue * coeff; modifyRhs = true; } } } else { // the new variable is fixed in the LP orig2lp_[nOrigVar_++] = n; lp2orig_[n] = oldNCol + i; ++n; lb[i] = ub[i] = elimVal(fsVarStat[i], lb[i], ub[i]); } } else { // the new variable will be added to the LP explicitly orig2lp_[nOrigVar_++] = n; lp2orig_[n] = oldNCol + i; ++n; } } // remove the fixed and set added variables if (delVar.size()) { vars.leftShift(delVar); fsVarStat.leftShift(delVar); lb.leftShift(delVar); ub.leftShift(delVar); } // generate the column of the added variable and add them to the LP ArrayBuffer<Column*> newCols(vars.size(),false); //!< new columns added to the constraint matrix Column colBuf(master_, nRow()); //!< buffer for generated columns Column *col; nVariables = vars.size(); for(int i = 0; i < nVariables; i++) { vars[i]->genColumn(sub_->actCon(), colBuf); col = new Column(master_, colBuf.nnz()); col->copy(colBuf); col->obj(colBuf.obj()); col->uBound(colBuf.uBound()); col->lBound(colBuf.lBound()); newCols.push(col); colBuf.clear(); } LP::addCols(newCols); // modify the right hand side if fixed or set variables are added if (modifyRhs) { const int nCon = sub_->nCon(); Array<double> newRhs(nCon); for(int c = 0; c < nCon; c++) newRhs[c] = rhs(c) - rhsDelta[c]; changeRhs(newRhs); } // LpSub::addVars(): clean up for(int i = 0; i < nVariables; i++) delete newCols[i]; }