mirror of https://github.com/CGAL/cgal
- basic interface for QP_solution enhanced; interface types and names
are now consistently only introduced in QP_solution, while the virtual functions in QP_solver_base are implementation-centered
This commit is contained in:
parent
0e70b553b7
commit
191f397d13
|
|
@ -84,12 +84,32 @@ int main(const int argNr,const char **args) {
|
||||||
cout << "Objective function value: " <<
|
cout << "Objective function value: " <<
|
||||||
CGAL::to_double(s.solution()) << endl;
|
CGAL::to_double(s.solution()) << endl;
|
||||||
|
|
||||||
// cout << "Variable values:" << endl;
|
cout << "Variable values:" << endl;
|
||||||
// Solution::Variable_value_iterator it
|
Solution::Variable_value_iterator vit =
|
||||||
// = s.variable_values_begin() ;
|
s.variable_values_begin() ;
|
||||||
// for (unsigned int i=0; i < qp.n(); ++it, ++i)
|
for (unsigned int i=0; i < qp.n(); ++vit, ++i)
|
||||||
// cout << " " << qp.name_of_variable(i) << " = "
|
cout << " " << qp.name_of_variable(i) << " = "
|
||||||
// << CGAL::to_double(*it) << endl;
|
<< CGAL::to_double(*vit) << endl;
|
||||||
|
|
||||||
|
cout << "Basic variables (index, value):" << endl;
|
||||||
|
Solution::Index_iterator iit =
|
||||||
|
s.basic_variable_indices_begin();
|
||||||
|
vit = s.variable_values_begin();
|
||||||
|
for ( ; iit < s.basic_variable_indices_end(); ++iit)
|
||||||
|
cout << " (" << *iit << ", "
|
||||||
|
<< CGAL::to_double(vit[*iit]) << ")" << endl;
|
||||||
|
cout << " There are " << s.number_of_basic_variables()
|
||||||
|
<< " basic variables. " << endl;
|
||||||
|
|
||||||
|
cout << "Basic constraints: " << endl;
|
||||||
|
Solution::Index_iterator cit =
|
||||||
|
s.basic_constraint_indices_begin();
|
||||||
|
for ( ; cit < s.basic_constraint_indices_end(); ++cit)
|
||||||
|
cout << *cit << " ";
|
||||||
|
cout << endl;
|
||||||
|
cout << " There are " << s.number_of_basic_constraints()
|
||||||
|
<< " basic constraints. " << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s.status() == CGAL::QP_INFEASIBLE)
|
if (s.status() == CGAL::QP_INFEASIBLE)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ public:
|
||||||
Indices;
|
Indices;
|
||||||
|
|
||||||
typedef Indices::iterator
|
typedef Indices::iterator
|
||||||
Index_iterator;
|
Index_mutable_iterator;
|
||||||
|
|
||||||
typedef Indices::const_iterator
|
typedef Indices::const_iterator
|
||||||
Index_const_iterator;
|
Index_const_iterator;
|
||||||
|
|
@ -91,8 +91,16 @@ public:
|
||||||
virtual Quotient<ET> solution() const = 0;
|
virtual Quotient<ET> solution() const = 0;
|
||||||
virtual QP_status status() const = 0;
|
virtual QP_status status() const = 0;
|
||||||
virtual ET variable_value (int i) const = 0;
|
virtual ET variable_value (int i) const = 0;
|
||||||
virtual Variable_value_iterator variable_values_begin() const = 0;
|
virtual Variable_value_iterator original_variable_values_begin() const = 0;
|
||||||
virtual Variable_value_iterator variable_values_end() const = 0;
|
virtual Variable_value_iterator original_variable_values_end() const = 0;
|
||||||
|
virtual Index_const_iterator
|
||||||
|
basic_original_variable_indices_begin() const = 0;
|
||||||
|
virtual Index_const_iterator
|
||||||
|
basic_original_variable_indices_end() const = 0;
|
||||||
|
virtual int number_of_basic_original_variables() const = 0;
|
||||||
|
virtual Index_const_iterator basic_constraint_indices_begin() const = 0;
|
||||||
|
virtual Index_const_iterator basic_constraint_indices_end() const = 0;
|
||||||
|
virtual int number_of_basic_constraints() const = 0;
|
||||||
virtual bool is_valid() const = 0;
|
virtual bool is_valid() const = 0;
|
||||||
|
|
||||||
// destruction (overridden by QP_solver)
|
// destruction (overridden by QP_solver)
|
||||||
|
|
@ -112,10 +120,13 @@ private:
|
||||||
return (*(this->Ptr()))->variable_value(i);
|
return (*(this->Ptr()))->variable_value(i);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// types
|
// interface types
|
||||||
typedef typename QP_solver_base<ET>::Variable_value_iterator
|
typedef typename QP_solver_base<ET>::Variable_value_iterator
|
||||||
Variable_value_iterator;
|
Variable_value_iterator;
|
||||||
|
|
||||||
|
typedef typename QP_solver_base<ET>::Index_const_iterator
|
||||||
|
Index_iterator;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
QP_solution ()
|
QP_solution ()
|
||||||
: Handle_for<const QP_solver_base<ET>*>()
|
: Handle_for<const QP_solver_base<ET>*>()
|
||||||
|
|
@ -139,12 +150,42 @@ public:
|
||||||
|
|
||||||
Variable_value_iterator variable_values_begin() const
|
Variable_value_iterator variable_values_begin() const
|
||||||
{
|
{
|
||||||
return (*(this->Ptr()))->variable_values_begin();
|
return (*(this->Ptr()))->original_variable_values_begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable_value_iterator variable_values_end() const
|
Variable_value_iterator variable_values_end() const
|
||||||
{
|
{
|
||||||
return (*(this->Ptr()))->variable_values_end();
|
return (*(this->Ptr()))->original_variable_values_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
Index_iterator basic_variable_indices_begin() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->basic_original_variable_indices_begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Index_iterator basic_variable_indices_end() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->basic_original_variable_indices_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int number_of_basic_variables() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->number_of_basic_original_variables();
|
||||||
|
}
|
||||||
|
|
||||||
|
Index_iterator basic_constraint_indices_begin() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->basic_constraint_indices_begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Index_iterator basic_constraint_indices_end() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->basic_constraint_indices_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int number_of_basic_constraints() const
|
||||||
|
{
|
||||||
|
return (*(this->Ptr()))->number_of_basic_constraints();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_valid() const
|
bool is_valid() const
|
||||||
|
|
|
||||||
|
|
@ -148,13 +148,6 @@ public: // public types
|
||||||
Bd_selector<Q, typename Tags::Is_in_standard_form>::
|
Bd_selector<Q, typename Tags::Is_in_standard_form>::
|
||||||
FU_iterator FU_iterator;
|
FU_iterator FU_iterator;
|
||||||
|
|
||||||
// typedef typename Q::D_iterator D_iterator;
|
|
||||||
// typedef typename Q::L_iterator L_iterator;
|
|
||||||
// typedef typename Q::U_iterator U_iterator;
|
|
||||||
// typedef typename Q::FL_iterator FL_iterator;
|
|
||||||
// typedef typename Q::FU_iterator FU_iterator;
|
|
||||||
|
|
||||||
|
|
||||||
// types from the Tags
|
// types from the Tags
|
||||||
typedef typename Tags::Is_linear Is_linear;
|
typedef typename Tags::Is_linear Is_linear;
|
||||||
typedef typename Tags::Is_symmetric Is_symmetric;
|
typedef typename Tags::Is_symmetric Is_symmetric;
|
||||||
|
|
@ -212,7 +205,7 @@ private: // private types
|
||||||
public: // export some additional types:
|
public: // export some additional types:
|
||||||
|
|
||||||
typedef typename Base::Indices Indices;
|
typedef typename Base::Indices Indices;
|
||||||
typedef typename Base::Index_iterator Index_iterator;
|
typedef typename Base::Index_mutable_iterator Index_iterator;
|
||||||
typedef typename Base::Index_const_iterator Index_const_iterator;
|
typedef typename Base::Index_const_iterator Index_const_iterator;
|
||||||
|
|
||||||
// For problems in nonstandard form we also export the following type, which
|
// For problems in nonstandard form we also export the following type, which
|
||||||
|
|
@ -622,24 +615,24 @@ public:
|
||||||
int number_of_original_variables( ) const { return qp_n; }
|
int number_of_original_variables( ) const { return qp_n; }
|
||||||
|
|
||||||
Variable_numerator_iterator
|
Variable_numerator_iterator
|
||||||
variables_numerator_begin( ) const
|
original_variables_numerator_begin( ) const
|
||||||
{ return Variable_numerator_iterator( O.begin(), Value_by_index(this));}
|
{ return Variable_numerator_iterator( O.begin(), Value_by_index(this));}
|
||||||
|
|
||||||
|
|
||||||
Variable_numerator_iterator
|
Variable_numerator_iterator
|
||||||
variables_numerator_end ( ) const
|
original_variables_numerator_end ( ) const
|
||||||
{ return Variable_numerator_iterator( O.end(), Value_by_index(this));}
|
{ return Variable_numerator_iterator( O.end(), Value_by_index(this));}
|
||||||
|
|
||||||
Variable_value_iterator
|
Variable_value_iterator
|
||||||
variable_values_begin( ) const
|
original_variable_values_begin( ) const
|
||||||
{ return Variable_value_iterator(
|
{ return Variable_value_iterator(
|
||||||
variables_numerator_begin(),
|
original_variables_numerator_begin(),
|
||||||
Quotient_maker( Quotient_creator(Quotient_normalizer(), U_Quotient_creator()) , d)); }
|
Quotient_maker( Quotient_creator(Quotient_normalizer(), U_Quotient_creator()) , d)); }
|
||||||
|
|
||||||
Variable_value_iterator
|
Variable_value_iterator
|
||||||
variable_values_end ( ) const
|
original_variable_values_end ( ) const
|
||||||
{ return Variable_value_iterator(
|
{ return Variable_value_iterator(
|
||||||
variables_numerator_end(),
|
original_variables_numerator_end(),
|
||||||
Quotient_maker( Quotient_creator(Quotient_normalizer(), U_Quotient_creator()) , d)); }
|
Quotient_maker( Quotient_creator(Quotient_normalizer(), U_Quotient_creator()) , d)); }
|
||||||
|
|
||||||
// access to slack variables
|
// access to slack variables
|
||||||
|
|
@ -659,9 +652,9 @@ public:
|
||||||
int number_of_basic_slack_variables( ) const { return B_S.size(); }
|
int number_of_basic_slack_variables( ) const { return B_S.size(); }
|
||||||
|
|
||||||
Basic_variable_index_iterator
|
Basic_variable_index_iterator
|
||||||
basic_original_variables_index_begin( ) const { return B_O.begin(); }
|
basic_original_variable_indices_begin( ) const { return B_O.begin(); }
|
||||||
Basic_variable_index_iterator
|
Basic_variable_index_iterator
|
||||||
basic_original_variables_index_end ( ) const { return B_O.end(); }
|
basic_original_variable_indices_end ( ) const { return B_O.end(); }
|
||||||
|
|
||||||
Basic_variable_numerator_iterator
|
Basic_variable_numerator_iterator
|
||||||
basic_original_variables_numerator_begin( ) const { return x_B_O.begin(); }
|
basic_original_variables_numerator_begin( ) const { return x_B_O.begin(); }
|
||||||
|
|
@ -805,9 +798,9 @@ public:
|
||||||
int number_of_basic_constraints( ) const { return C.size(); }
|
int number_of_basic_constraints( ) const { return C.size(); }
|
||||||
|
|
||||||
Basic_constraint_index_iterator
|
Basic_constraint_index_iterator
|
||||||
basic_constraints_index_begin( ) const { return C.begin(); }
|
basic_constraint_indices_begin( ) const { return C.begin(); }
|
||||||
Basic_constraint_index_iterator
|
Basic_constraint_index_iterator
|
||||||
basic_constraints_index_end ( ) const { return C.end(); }
|
basic_constraint_indices_end ( ) const { return C.end(); }
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
template < class RndAccIt1, class RndAccIt2, class NT >
|
template < class RndAccIt1, class RndAccIt2, class NT >
|
||||||
|
|
|
||||||
|
|
@ -170,8 +170,8 @@ update_maxima( )
|
||||||
|
|
||||||
Basic_constraint_index_iterator it;
|
Basic_constraint_index_iterator it;
|
||||||
Values_NT_iterator v_it = lambda_NT.begin();
|
Values_NT_iterator v_it = lambda_NT.begin();
|
||||||
for ( it = this->solver().basic_constraints_index_begin();
|
for ( it = this->solver().basic_constraint_indices_begin();
|
||||||
it != this->solver().basic_constraints_index_end(); ++it, ++v_it) {
|
it != this->solver().basic_constraint_indices_end(); ++it, ++v_it) {
|
||||||
row = *it;
|
row = *it;
|
||||||
|
|
||||||
// row not handled yet?
|
// row not handled yet?
|
||||||
|
|
@ -228,8 +228,8 @@ update_maxima( Tag_false)
|
||||||
|
|
||||||
Basic_variable_index_iterator it;
|
Basic_variable_index_iterator it;
|
||||||
Values_NT_iterator v_it = x_B_O_NT.begin();
|
Values_NT_iterator v_it = x_B_O_NT.begin();
|
||||||
for ( it = this->solver().basic_original_variables_index_begin();
|
for ( it = this->solver().basic_original_variable_indices_begin();
|
||||||
it != this->solver().basic_original_variables_index_end();
|
it != this->solver().basic_original_variable_indices_end();
|
||||||
++it, ++v_it) {
|
++it, ++v_it) {
|
||||||
row = *it;
|
row = *it;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,22 +132,25 @@ solution_numerator( ) const
|
||||||
if (is_QP) {
|
if (is_QP) {
|
||||||
// quadratic part
|
// quadratic part
|
||||||
i=0;
|
i=0;
|
||||||
for (Variable_numerator_iterator i_it = variables_numerator_begin();
|
for (Variable_numerator_iterator
|
||||||
i_it < variables_numerator_end(); ++i_it, ++i) {
|
i_it = original_variables_numerator_begin();
|
||||||
|
i_it < original_variables_numerator_end(); ++i_it, ++i) {
|
||||||
// do something only if *i_it != 0
|
// do something only if *i_it != 0
|
||||||
if (*i_it == et0) continue;
|
if (*i_it == et0) continue;
|
||||||
s = et0; // contribution of i-th row
|
s = et0; // contribution of i-th row
|
||||||
j=0;
|
j=0;
|
||||||
for (Variable_numerator_iterator j_it = variables_numerator_begin();
|
for (Variable_numerator_iterator
|
||||||
j_it < variables_numerator_end(); ++j_it, ++j)
|
j_it = original_variables_numerator_begin();
|
||||||
|
j_it < original_variables_numerator_end(); ++j_it, ++j)
|
||||||
s += ET(qp_D[i][j]) * *j_it;
|
s += ET(qp_D[i][j]) * *j_it;
|
||||||
z += s * *i_it;
|
z += s * *i_it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// linear part
|
// linear part
|
||||||
j=0; s = et0;
|
j=0; s = et0;
|
||||||
for (Variable_numerator_iterator j_it = variables_numerator_begin();
|
for (Variable_numerator_iterator
|
||||||
j_it < variables_numerator_end(); ++j_it, ++j)
|
j_it = original_variables_numerator_begin();
|
||||||
|
j_it < original_variables_numerator_end(); ++j_it, ++j)
|
||||||
s += ET(qp_c[j]) * *j_it;
|
s += ET(qp_c[j]) * *j_it;
|
||||||
z += d * s;
|
z += d * s;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,14 +192,16 @@ bool QP_solver<Q, ET, Tags>::is_value_correct() const
|
||||||
// compute x^T D x + d c = sum_i x_i (D_i x + d c_i)
|
// compute x^T D x + d c = sum_i x_i (D_i x + d c_i)
|
||||||
ET z = et0; // for x^T D x + d c
|
ET z = et0; // for x^T D x + d c
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Variable_numerator_iterator i_it = variables_numerator_begin();
|
for (Variable_numerator_iterator
|
||||||
i_it < variables_numerator_end(); ++i_it, ++i) {
|
i_it = original_variables_numerator_begin();
|
||||||
|
i_it < original_variables_numerator_end(); ++i_it, ++i) {
|
||||||
if (*i_it == et0) continue; // no contribution from this variable
|
if (*i_it == et0) continue; // no contribution from this variable
|
||||||
ET s = et0; // for D_i x + c_i
|
ET s = et0; // for D_i x + c_i
|
||||||
int j = 0;
|
int j = 0;
|
||||||
if (is_QP) {
|
if (is_QP) {
|
||||||
for (Variable_numerator_iterator j_it = variables_numerator_begin();
|
for (Variable_numerator_iterator j_it =
|
||||||
j_it < variables_numerator_end(); ++j_it, ++j)
|
original_variables_numerator_begin();
|
||||||
|
j_it < original_variables_numerator_end(); ++j_it, ++j)
|
||||||
s += ET(qp_D[i][j]) * *j_it; // D_ij x_j
|
s += ET(qp_D[i][j]) * *j_it; // D_ij x_j
|
||||||
}
|
}
|
||||||
// now s = D_i x
|
// now s = D_i x
|
||||||
|
|
@ -411,14 +413,14 @@ bool QP_solver<Q, ET, Tags>::is_solution_feasible() const
|
||||||
CGAL_qpe_assertion(is_phaseII);
|
CGAL_qpe_assertion(is_phaseII);
|
||||||
|
|
||||||
Values lhs_col(qp_m, et0);
|
Values lhs_col(qp_m, et0);
|
||||||
Variable_numerator_iterator it = variables_numerator_begin();
|
Variable_numerator_iterator it = original_variables_numerator_begin();
|
||||||
for (int i=0; i<qp_n; ++i, ++it) {
|
for (int i=0; i<qp_n; ++i, ++it) {
|
||||||
|
|
||||||
// check bounds on original variables:
|
// check bounds on original variables:
|
||||||
const ET var = is_basic(i)? x_B_O[in_B[i]] : // should be ET &
|
const ET var = is_basic(i)? x_B_O[in_B[i]] : // should be ET &
|
||||||
nonbasic_original_variable_value(i) * d;
|
nonbasic_original_variable_value(i) * d;
|
||||||
if (var != *it)
|
if (var != *it)
|
||||||
return false; // variables_numerator_begin() inconsistent
|
return false; // original_variables_numerator_begin() inconsistent
|
||||||
if (has_finite_lower_bound(i) && var < lower_bound(i) * d ||
|
if (has_finite_lower_bound(i) && var < lower_bound(i) * d ||
|
||||||
has_finite_upper_bound(i) && var > upper_bound(i) * d)
|
has_finite_upper_bound(i) && var > upper_bound(i) * d)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue