[PPL-devel] [GIT] ppl/ppl(pip): Implemented additional steps of the simplex algorithm.
François Galea
francois.galea at uvsq.fr
Wed Sep 16 15:31:40 CEST 2009
Module: ppl/ppl
Branch: pip
Commit: 5927b13d1aae63bca73f31b377ee437b28ce8618
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=5927b13d1aae63bca73f31b377ee437b28ce8618
Author: François Galea <francois.galea at uvsq.fr>
Date: Wed Sep 16 15:24:24 2009 +0200
Implemented additional steps of the simplex algorithm.
- handling of simplex rows with mixed parameter sign;
- handling of tautology expressions;
- handling of splitting a solution according to a test parametric expression.
---
src/PIP_Tree.cc | 112 ++++++++++++++++++++++++++++++++++++++++++++++++-
src/PIP_Tree.defs.hh | 3 +
2 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/src/PIP_Tree.cc b/src/PIP_Tree.cc
index edc073f..d528d37 100644
--- a/src/PIP_Tree.cc
+++ b/src/PIP_Tree.cc
@@ -74,7 +74,8 @@ PIP_Tree_Node::PIP_Tree_Node(const PIP_Tree_Node &x)
PIP_Decision_Node::~PIP_Decision_Node() {
delete true_child;
- delete false_child;
+ if (false_child)
+ delete false_child;
}
PIP_Solution_Node::~PIP_Solution_Node() {
@@ -196,6 +197,14 @@ PIP_Tree_Node::OK() const {
return true;
}
+void
+PIP_Tree_Node::add_constraint(const Row &row) {
+ Linear_Expression e;
+ for (dimension_type j=row.size(); j-- > 1; )
+ e += row[j] * Variable(j-1);
+ constraints_.insert(e + row[0] >= 0);
+}
+
bool
PIP_Solution_Node::OK() const {
/* FIXME: finish me! */
@@ -526,7 +535,7 @@ PIP_Solution_Node::solve(PIP_Tree_Node*& parent_ref,
// Main loop of the simplex algorithm
for(;;) {
- dimension_type i;
+ dimension_type i, j;
dimension_type i_ = n_a_d;
dimension_type i__ = n_a_d;
dimension_type num_rows = tableau.t.num_rows();
@@ -590,7 +599,7 @@ PIP_Solution_Node::solve(PIP_Tree_Node*& parent_ref,
std::cout << "Found row with negative parameters: " << i_
<< std::endl;
#endif
- dimension_type j, k;
+ dimension_type k;
Coefficient z(0);
Coefficient sij, cij, cij_;
Coefficient c;
@@ -738,6 +747,103 @@ PIP_Solution_Node::solve(PIP_Tree_Node*& parent_ref,
c /= sij;
}
}
+
+ /* Otherwise, we have found a row i__ with mixed parameter sign. */
+ else if (i__ != n_a_d) {
+ dimension_type neg = n_a_d;
+ Coefficient ns, score;
+
+ /* Look for a constraint with mixed parameter sign with no positive
+ * variable coefficients */
+ for (i=i__; i<num_rows; ++i) {
+ if (sign[i] != MIXED)
+ continue;
+ for (j=0; j<num_vars; ++j) {
+ if (tableau.s[i][j] > 0)
+ break;
+ }
+ /* Choose row with lowest score, potentially eliminating
+ * implicated tautologies if some exist */
+ if (j == num_vars) {
+ score = 0;
+ for (j=0; j<num_params; ++j)
+ score += tableau.t[i][j];
+ if (neg == n_a_d || score < ns) {
+ neg = i;
+ ns = score;
+ }
+ }
+ }
+ if (neg != n_a_d) {
+ i = neg;
+#ifdef NOISY_PIP
+ std::cout << "Found row with unknown parameter sign and negative "
+ "variable coefficients: " << i
+ << std::endl;
+#endif
+ Row &r = tableau.t[i];
+ context.add_row(r);
+ add_constraint(r);
+#ifdef NOISY_PIP
+ Linear_Expression e;
+ for (j=1; j<num_params; ++j)
+ e += r[j] * Variable(j-1);
+ Constraint c(e + r[0] >= 0);
+ std::cout << "Adding tautology: " << c
+ << std::endl;
+#endif
+ } else {
+#ifdef NOISY_PIP
+ std::cout << "Found row with mixed parameter sign: " << i__
+ << std::endl
+ << "Solution depends on the sign of parameter"
+ << std::endl;
+#endif
+ Row test(tableau.t[i__]);
+
+ /* Create a solution Node to become "true" version of current Node */
+ PIP_Tree_Node *tru = new PIP_Solution_Node(*this, true);
+ context.add_row(test);
+ PIP_Problem_Status status_t = tru->solve(tru, context);
+
+ /* Modify *this to become "false" version */
+ Constraint_System cs;
+ cs.swap(constraints_);
+ PIP_Tree_Node *fals = this;
+ Row &testf = context[context.num_rows()-1];
+ negate_assign(testf, test);
+ PIP_Problem_Status status_f = solve(fals, context);
+
+ if (status_t == UNFEASIBLE_PIP_PROBLEM
+ && status_f == UNFEASIBLE_PIP_PROBLEM) {
+ parent_ref = 0;
+ return UNFEASIBLE_PIP_PROBLEM;
+ } else if (status_t == UNFEASIBLE_PIP_PROBLEM) {
+ cs.swap(constraints_);
+ add_constraint(testf);
+ return OPTIMIZED_PIP_PROBLEM;
+ } else if (status_f == UNFEASIBLE_PIP_PROBLEM) {
+ cs.swap(tru->constraints_);
+ tru->add_constraint(test);
+ parent_ref = tru;
+ return OPTIMIZED_PIP_PROBLEM;
+ }
+
+ /* Create a decision Node to become parent of current Node */
+ PIP_Decision_Node *parent = new PIP_Decision_Node(fals, tru);
+ parent->add_constraint(test);
+
+ if (!cs.empty()) {
+ /* If node to be solved had tautologies, store them in a new
+ decision node */
+ parent = new PIP_Decision_Node(0, parent);
+ cs.swap(parent->constraints_);
+ }
+
+ parent_ref = parent;
+ return OPTIMIZED_PIP_PROBLEM;
+ }
+ }
//FIXME: to be finished
} // Main loop of the simplex algorithm
diff --git a/src/PIP_Tree.defs.hh b/src/PIP_Tree.defs.hh
index cb41f49..f23bf31 100644
--- a/src/PIP_Tree.defs.hh
+++ b/src/PIP_Tree.defs.hh
@@ -129,6 +129,9 @@ protected:
*/
virtual PIP_Problem_Status solve(PIP_Tree_Node*& parent_ref,
const Matrix& context) = 0;
+
+ //! Inserts a new parametric constraint in internal Row format
+ void add_constraint(const Row &x);
};
//! A tree node representing part of the space of solutions.
More information about the PPL-devel
mailing list