[Lemon-commits] Balazs Dezso: Faster add row operation (#203)
Lemon HG
hg at lemon.cs.elte.hu
Sun Oct 4 08:46:26 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/e4554cd6b2bf
changeset: 801:e4554cd6b2bf
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Sun Oct 04 00:28:42 2009 +0200
description:
Faster add row operation (#203)
One virtual function call instead of more
diffstat:
lemon/cbc.cc | 12 ++++++++++++
lemon/cbc.h | 1 +
lemon/clp.cc | 13 +++++++++++++
lemon/clp.h | 1 +
lemon/cplex.cc | 33 +++++++++++++++++++++++++++++++++
lemon/cplex.h | 1 +
lemon/glpk.cc | 36 ++++++++++++++++++++++++++++++++++++
lemon/glpk.h | 1 +
lemon/lp_base.h | 22 ++++++++++++++++++----
lemon/lp_skeleton.cc | 5 +++++
lemon/lp_skeleton.h | 2 ++
lemon/soplex.cc | 13 +++++++++++++
lemon/soplex.h | 1 +
13 files changed, 137 insertions(+), 4 deletions(-)
diffs (285 lines):
diff --git a/lemon/cbc.cc b/lemon/cbc.cc
--- a/lemon/cbc.cc
+++ b/lemon/cbc.cc
@@ -94,6 +94,18 @@
return _prob->numberRows() - 1;
}
+ int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+ std::vector<int> indexes;
+ std::vector<Value> values;
+
+ for(ExprIterator it = b; it != e; ++it) {
+ indexes.push_back(it->first);
+ values.push_back(it->second);
+ }
+
+ _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
+ return _prob->numberRows() - 1;
+ }
void CbcMip::_eraseCol(int i) {
_prob->deleteColumn(i);
diff --git a/lemon/cbc.h b/lemon/cbc.h
--- a/lemon/cbc.h
+++ b/lemon/cbc.h
@@ -62,6 +62,7 @@
virtual int _addCol();
virtual int _addRow();
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
virtual void _eraseCol(int i);
virtual void _eraseRow(int i);
diff --git a/lemon/clp.cc b/lemon/clp.cc
--- a/lemon/clp.cc
+++ b/lemon/clp.cc
@@ -78,6 +78,19 @@
return _prob->numberRows() - 1;
}
+ int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+ std::vector<int> indexes;
+ std::vector<Value> values;
+
+ for(ExprIterator it = b; it != e; ++it) {
+ indexes.push_back(it->first);
+ values.push_back(it->second);
+ }
+
+ _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
+ return _prob->numberRows() - 1;
+ }
+
void ClpLp::_eraseCol(int c) {
_col_names_ref.erase(_prob->getColumnName(c));
diff --git a/lemon/clp.h b/lemon/clp.h
--- a/lemon/clp.h
+++ b/lemon/clp.h
@@ -75,6 +75,7 @@
virtual int _addCol();
virtual int _addRow();
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
virtual void _eraseCol(int i);
virtual void _eraseRow(int i);
diff --git a/lemon/cplex.cc b/lemon/cplex.cc
--- a/lemon/cplex.cc
+++ b/lemon/cplex.cc
@@ -111,6 +111,39 @@
return i;
}
+ int CplexBase::_addRow(Value lb, ExprIterator b,
+ ExprIterator e, Value ub) {
+ int i = CPXgetnumrows(cplexEnv(), _prob);
+ if (lb == -INF) {
+ const char s = 'L';
+ CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+ } else if (ub == INF) {
+ const char s = 'G';
+ CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+ } else if (lb == ub){
+ const char s = 'E';
+ CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+ } else {
+ const char s = 'R';
+ double len = ub - lb;
+ CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
+ }
+
+ std::vector<int> indices;
+ std::vector<int> rowlist;
+ std::vector<Value> values;
+
+ for(ExprIterator it=b; it!=e; ++it) {
+ indices.push_back(it->first);
+ values.push_back(it->second);
+ rowlist.push_back(i);
+ }
+
+ CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+ &rowlist.front(), &indices.front(), &values.front());
+
+ return i;
+ }
void CplexBase::_eraseCol(int i) {
CPXdelcols(cplexEnv(), _prob, i, i);
diff --git a/lemon/cplex.h b/lemon/cplex.h
--- a/lemon/cplex.h
+++ b/lemon/cplex.h
@@ -93,6 +93,7 @@
virtual int _addCol();
virtual int _addRow();
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
virtual void _eraseCol(int i);
virtual void _eraseRow(int i);
diff --git a/lemon/glpk.cc b/lemon/glpk.cc
--- a/lemon/glpk.cc
+++ b/lemon/glpk.cc
@@ -59,6 +59,42 @@
return i;
}
+ int GlpkBase::_addRow(Value lo, ExprIterator b,
+ ExprIterator e, Value up) {
+ int i = glp_add_rows(lp, 1);
+
+ if (lo == -INF) {
+ if (up == INF) {
+ glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+ } else {
+ glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+ }
+ } else {
+ if (up == INF) {
+ glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+ } else if (lo != up) {
+ glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+ } else {
+ glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+ }
+ }
+
+ std::vector<int> indexes;
+ std::vector<Value> values;
+
+ indexes.push_back(0);
+ values.push_back(0);
+
+ for(ExprIterator it = b; it != e; ++it) {
+ indexes.push_back(it->first);
+ values.push_back(it->second);
+ }
+
+ glp_set_mat_row(lp, i, values.size() - 1,
+ &indexes.front(), &values.front());
+ return i;
+ }
+
void GlpkBase::_eraseCol(int i) {
int ca[2];
ca[1] = i;
diff --git a/lemon/glpk.h b/lemon/glpk.h
--- a/lemon/glpk.h
+++ b/lemon/glpk.h
@@ -54,6 +54,7 @@
virtual int _addCol();
virtual int _addRow();
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
virtual void _eraseCol(int i);
virtual void _eraseRow(int i);
diff --git a/lemon/lp_base.h b/lemon/lp_base.h
--- a/lemon/lp_base.h
+++ b/lemon/lp_base.h
@@ -943,6 +943,14 @@
virtual int _addCol() = 0;
virtual int _addRow() = 0;
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+ int row = _addRow();
+ _setRowCoeffs(row, b, e);
+ _setRowLowerBound(row, l);
+ _setRowUpperBound(row, u);
+ return row;
+ }
+
virtual void _eraseCol(int col) = 0;
virtual void _eraseRow(int row) = 0;
@@ -1207,8 +1215,10 @@
///\param u is the upper bound (\ref INF means no bound)
///\return The created row.
Row addRow(Value l,const Expr &e, Value u) {
- Row r=addRow();
- row(r,l,e,u);
+ Row r;
+ e.simplify();
+ r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
+ ExprIterator(e.comps.end(), cols), u - *e));
return r;
}
@@ -1217,8 +1227,12 @@
///\param c is a linear expression (see \ref Constr)
///\return The created row.
Row addRow(const Constr &c) {
- Row r=addRow();
- row(r,c);
+ Row r;
+ c.expr().simplify();
+ r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF,
+ ExprIterator(c.expr().comps.begin(), cols),
+ ExprIterator(c.expr().comps.end(), cols),
+ c.upperBounded()?c.upperBound():INF));
return r;
}
///Erase a column (i.e a variable) from the LP
diff --git a/lemon/lp_skeleton.cc b/lemon/lp_skeleton.cc
--- a/lemon/lp_skeleton.cc
+++ b/lemon/lp_skeleton.cc
@@ -32,6 +32,11 @@
return ++row_num;
}
+ int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
+ {
+ return ++row_num;
+ }
+
void SkeletonSolverBase::_eraseCol(int) {}
void SkeletonSolverBase::_eraseRow(int) {}
diff --git a/lemon/lp_skeleton.h b/lemon/lp_skeleton.h
--- a/lemon/lp_skeleton.h
+++ b/lemon/lp_skeleton.h
@@ -45,6 +45,8 @@
/// \e
virtual int _addRow();
/// \e
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+ /// \e
virtual void _eraseCol(int i);
/// \e
virtual void _eraseRow(int i);
diff --git a/lemon/soplex.cc b/lemon/soplex.cc
--- a/lemon/soplex.cc
+++ b/lemon/soplex.cc
@@ -91,6 +91,19 @@
return soplex->nRows() - 1;
}
+ int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+ soplex::DSVector v;
+ for (ExprIterator it = b; it != e; ++it) {
+ v.add(it->first, it->second);
+ }
+ soplex::LPRow r(l, v, u);
+ soplex->addRow(r);
+
+ _row_names.push_back(std::string());
+
+ return soplex->nRows() - 1;
+ }
+
void SoplexLp::_eraseCol(int i) {
soplex->removeCol(i);
diff --git a/lemon/soplex.h b/lemon/soplex.h
--- a/lemon/soplex.h
+++ b/lemon/soplex.h
@@ -84,6 +84,7 @@
virtual int _addCol();
virtual int _addRow();
+ virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
virtual void _eraseCol(int i);
virtual void _eraseRow(int i);
More information about the Lemon-commits
mailing list