BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/QP_solution.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2007  ETH Zurich (Switzerland).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licenseges holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/QP_solver/include/CGAL/QP_solution.h $
00015 // $Id: QP_solution.h 46451 2008-10-23 14:31:10Z gaertner $
00016 // 
00017 //
00018 // Author(s)     : Kaspar Fischer
00019 //               : Bernd Gaertner <gaertner@inf.ethz.ch>
00020 //               : Sven Schoenherr
00021 //               : Franz Wessendorp
00022 
00023 #ifndef CGAL_QP_SOLUTION_H
00024 #define CGAL_QP_SOLUTION_H
00025 
00026 #include <iostream>
00027 #include <vector>
00028 #include <CGAL/basic.h>
00029 #include <CGAL/Handle_for.h>
00030 #include <CGAL/function_objects.h>
00031 #include <CGAL/Algebraic_structure_traits.h>
00032 #include <boost/bind.hpp>
00033 #include <boost/function.hpp>
00034 #include <boost/iterator/counting_iterator.hpp>
00035 #include <boost/iterator/transform_iterator.hpp>
00036 
00037 CGAL_BEGIN_NAMESPACE
00038 
00039 // forward references
00040 template <typename Q, typename ET, typename Tags>
00041 class QP_solver;
00042 
00043 namespace QP_solution_detail {
00044   template <typename ET>
00045   class Quotient_normalizer;
00046   
00047   template <typename ET>
00048   class Value_by_index;
00049 
00050   template <typename ET>
00051   class Unbounded_direction_by_index;
00052 
00053   template <typename ET>
00054   class Lambda_by_index;
00055 }
00056 
00057 // global status type
00058 enum Quadratic_program_status 
00059   { 
00060     QP_UPDATE, 
00061     QP_INFEASIBLE, 
00062     QP_UNBOUNDED, 
00063     QP_OPTIMAL 
00064   };
00065 
00066 // abstract base class of all QP-solvers
00067 // -------------------------------------
00068 template <class ET>
00069 class QP_solver_base
00070 {
00071 public:
00072   // types
00073   typedef  CGAL::Creator_2< ET, ET, Quotient<ET> >
00074   U_Quotient_creator;  // unnormalized quotient creator ET x ET -> (ET, ET)
00075 
00076   typedef QP_solution_detail::Quotient_normalizer<ET> 
00077   Quotient_normalizer; // normalizer (ET, ET) -> (ET, ET)
00078 
00079   typedef boost::function1< Quotient<ET>, ET > 
00080   Quotient_maker;
00081 
00082   typedef std::vector<int> 
00083   Indices;
00084 
00085   typedef Indices::iterator    
00086   Index_mutable_iterator;
00087 
00088   typedef Indices::const_iterator    
00089   Index_const_iterator;
00090 
00091   typedef typename QP_solution_detail::Value_by_index<ET> Value_by_index;
00092 
00093   typedef typename boost::transform_iterator
00094   <Value_by_index, boost::counting_iterator<int> >
00095   Variable_numerator_iterator;
00096 
00097   typedef boost::transform_iterator
00098   <Quotient_maker, Variable_numerator_iterator>
00099   Variable_value_iterator;
00100 
00101   typedef typename QP_solution_detail::Unbounded_direction_by_index<ET> 
00102   Unbounded_direction_by_index;
00103 
00104   typedef boost::transform_iterator
00105   <Unbounded_direction_by_index, boost::counting_iterator<int> >
00106   Unbounded_direction_iterator;
00107 
00108   typedef typename QP_solution_detail::Lambda_by_index<ET> 
00109   Lambda_by_index;
00110   
00111   typedef boost::transform_iterator
00112   <Lambda_by_index, boost::counting_iterator<int> >
00113   Lambda_numerator_iterator;
00114 
00115   typedef boost::transform_iterator
00116   <Quotient_maker,Lambda_numerator_iterator>
00117   Lambda_iterator;
00118 
00119 public:
00120 
00121   // virtual access functions to solution that will 
00122   // be overridden by QP_solver below
00123 
00124   // Solution
00125   // --------
00126   virtual ET solution_numerator() const = 0;
00127   virtual ET solution_denominator() const = 0;
00128   Quotient<ET> solution( ) const
00129   { 
00130     // workaround to please Boost 1.33.1: 
00131     ET n = solution_numerator();
00132     ET d = solution_denominator();
00133     return 
00134       boost::bind 
00135       (Quotient_normalizer(), boost::bind
00136        (U_Quotient_creator(), _1, _2))
00137       (n, d);
00138       // (solution_numerator(), solution_denominator());
00139   }
00140   virtual Quadratic_program_status status() const = 0;
00141   virtual int iterations() const = 0;
00142 
00143   // Variable values
00144   // ---------------
00145   virtual ET variable_numerator_value (int i) const = 0; 
00146   virtual const ET& variables_common_denominator( ) const = 0;
00147   virtual int number_of_variables() const = 0;
00148 
00149   // value type ET
00150   Variable_numerator_iterator
00151   original_variables_numerator_begin( ) const
00152   { return Variable_numerator_iterator 
00153       (boost::counting_iterator<int>(0), 
00154        Value_by_index(this));}
00155                                   
00156     
00157   Variable_numerator_iterator
00158   original_variables_numerator_end  ( ) const
00159   { return Variable_numerator_iterator 
00160       (boost::counting_iterator<int>(number_of_variables()) , 
00161        Value_by_index(this));} 
00162 
00163   // value type Quotient<ET>   
00164   Variable_value_iterator
00165   original_variable_values_begin( ) const
00166   { return Variable_value_iterator
00167       (original_variables_numerator_begin(),
00168        boost::bind 
00169        (boost::bind 
00170         (Quotient_normalizer(), boost::bind
00171          (U_Quotient_creator(), _1, _2)), _1, variables_common_denominator()));
00172   }
00173     
00174   Variable_value_iterator
00175   original_variable_values_end  ( ) const
00176   { return Variable_value_iterator
00177       (original_variables_numerator_end(),
00178        boost::bind 
00179        (boost::bind 
00180         (Quotient_normalizer(), boost::bind
00181          (U_Quotient_creator(), _1, _2)), _1, variables_common_denominator()));
00182   }
00183     
00184   // Basic variables and constraints
00185   // -------------------------------
00186   virtual Index_const_iterator 
00187   basic_original_variable_indices_begin() const = 0;
00188   virtual Index_const_iterator 
00189   basic_original_variable_indices_end() const = 0;
00190   virtual int number_of_basic_original_variables() const = 0;
00191   virtual Index_const_iterator 
00192   basic_constraint_indices_begin() const = 0;
00193   virtual Index_const_iterator 
00194   basic_constraint_indices_end() const = 0;
00195   virtual int number_of_basic_constraints() const = 0;
00196 
00197   // Unboundedness
00198   // -------------
00199   virtual ET unbounded_direction_value(int i) const = 0;
00200 
00201   Unbounded_direction_iterator unbounded_direction_begin() const 
00202   { return Unbounded_direction_iterator 
00203       (boost::counting_iterator<int>(0), 
00204        Unbounded_direction_by_index(this));}
00205 
00206   // Returns the past-the-end iterator corresponding to
00207   // unbounded_direction_begin().
00208   Unbounded_direction_iterator unbounded_direction_end() const
00209   { return Unbounded_direction_iterator 
00210       (boost::counting_iterator<int>(number_of_variables()), 
00211        Unbounded_direction_by_index(this));}
00212 
00213 
00214   // Optimality
00215   // ----------
00216   virtual ET lambda_numerator(int i) const = 0;
00217   virtual int number_of_constraints() const = 0;
00218 
00219   // value type ET
00220   Lambda_numerator_iterator 
00221   lambda_numerator_begin() const 
00222   { return Lambda_numerator_iterator 
00223       (boost::counting_iterator<int>(0), 
00224        Lambda_by_index(this));}
00225 
00226   Lambda_numerator_iterator 
00227   lambda_numerator_end() const
00228   { return Lambda_numerator_iterator 
00229       (boost::counting_iterator<int>(number_of_constraints()), 
00230        Lambda_by_index(this));}
00231 
00232   // value type Quotient<ET>
00233   Lambda_iterator
00234   lambda_begin() const
00235   {
00236     return Lambda_iterator
00237      (lambda_numerator_begin(),
00238       boost::bind 
00239       (boost::bind 
00240        (Quotient_normalizer(), boost::bind
00241         (U_Quotient_creator(), _1, _2)), _1, variables_common_denominator()));
00242   }
00243 
00244   Lambda_iterator
00245   lambda_end() const
00246   {
00247     return Lambda_iterator
00248      (lambda_numerator_end(),
00249       boost::bind 
00250       (boost::bind 
00251        (Quotient_normalizer(), boost::bind
00252         (U_Quotient_creator(), _1, _2)), _1, variables_common_denominator()));
00253   }
00254 
00255   // destruction
00256   // -----------
00257   virtual ~QP_solver_base() {}
00258 };
00259 
00260 
00261 // Quadratic_program_solution class: a handle for QP_solver_base<ET>
00262 // ----------------------------------------------------------------- 
00263 template <class ET_>
00264 class Quadratic_program_solution: Handle_for<const QP_solver_base<ET_>*> 
00265 {
00266 public:
00267   typedef ET_ ET;
00268   // interface types
00269   // ===============
00270 
00271   // variable values / indices
00272   // -------------------------
00273   typedef typename QP_solver_base<ET>::Variable_value_iterator
00274   Variable_value_iterator;
00275 
00276   typedef typename QP_solver_base<ET>::Variable_numerator_iterator
00277   Variable_numerator_iterator;
00278 
00279   typedef typename QP_solver_base<ET>::Index_const_iterator
00280   Index_iterator;
00281 
00282   // certificates
00283   // ------------
00284   typedef typename QP_solver_base<ET>::Unbounded_direction_iterator
00285   Unboundedness_certificate_iterator;
00286   
00287   typedef 
00288   typename QP_solver_base<ET>::Lambda_numerator_iterator
00289   Optimality_certificate_numerator_iterator;
00290   
00291   typedef typename QP_solver_base<ET>::Lambda_iterator
00292   Optimality_certificate_iterator;
00293 
00294   typedef typename QP_solver_base<ET>::Lambda_numerator_iterator
00295   Infeasibility_certificate_iterator;
00296 
00297   // methods
00298   // -------
00299   Quadratic_program_solution ()
00300     : Handle_for<const QP_solver_base<ET>*>(), et0(0)
00301   {
00302     *(this->ptr()) = 0; // unitialized solution
00303   }
00304 
00305   Quadratic_program_solution (const QP_solver_base<ET>* s)
00306     : Handle_for<const QP_solver_base<ET>*>(s), et0(0)
00307   {}
00308 
00309   Quadratic_program_solution& 
00310   operator= (const Quadratic_program_solution& sol)
00311   {
00312     if (this != &sol) {
00313       // delete the old solver if necessary
00314       if (!this->is_shared()) delete *(this->ptr());
00315       this->Handle_for<const QP_solver_base<ET>*>::operator=(sol);
00316     }
00317     return *this;
00318   }
00319 
00320   ~Quadratic_program_solution()
00321   {
00322     if (!this->is_shared()) delete *(this->ptr());
00323   }
00324 
00325 private:
00326   const QP_solver_base<ET>* solver() const 
00327   {
00328     return *(this->Ptr());
00329   }
00330 
00331 public:
00332   bool is_void() const 
00333   {
00334     return solver() == 0;
00335   }
00336 
00337   Quotient<ET> objective_value() const
00338   {
00339     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00340     return solver()->solution();
00341   }
00342 
00343   ET objective_value_numerator() const
00344   {
00345     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00346     return solver()->solution_numerator();
00347   }
00348 
00349   ET objective_value_denominator() const
00350   {
00351     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00352     return solver()->solution_denominator();
00353   }
00354 
00355   Quadratic_program_status status() const
00356   {
00357     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00358     return solver()->status();
00359   }
00360 
00361   bool is_optimal() const
00362   {
00363     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00364     return status() == QP_OPTIMAL;
00365   }
00366 
00367   bool is_infeasible() const
00368   {
00369     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00370     return status() == QP_INFEASIBLE;
00371   }
00372 
00373   bool is_unbounded() const
00374   {
00375     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00376     return status() == QP_UNBOUNDED;
00377   }
00378 
00379   int number_of_iterations() const
00380   { 
00381     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00382     return solver()->iterations();
00383   }
00384 
00385   Variable_value_iterator variable_values_begin() const
00386   {
00387    CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00388    return solver()->original_variable_values_begin();
00389   }
00390 
00391   Variable_value_iterator variable_values_end() const
00392   {
00393     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00394     return solver()->original_variable_values_end();
00395   }
00396 
00397   Variable_numerator_iterator variable_numerators_begin() const
00398   {
00399    CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00400    return solver()->original_variables_numerator_begin();
00401   }
00402 
00403   Variable_numerator_iterator variable_numerators_end() const
00404   {
00405     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00406     return solver()->original_variables_numerator_end();
00407   }
00408 
00409   const ET& variables_common_denominator() const
00410   {
00411     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00412     return solver()->variables_common_denominator();
00413   }
00414 
00415   Index_iterator basic_variable_indices_begin() const
00416   {
00417     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00418     return solver()->basic_original_variable_indices_begin();
00419   }
00420 
00421   Index_iterator basic_variable_indices_end() const
00422   {
00423     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00424     return solver()->basic_original_variable_indices_end();
00425   }
00426 
00427   int number_of_basic_variables() const
00428   {
00429     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00430     return solver()->number_of_basic_original_variables();
00431   }
00432 
00433   Index_iterator basic_constraint_indices_begin() const
00434   {
00435     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00436     return solver()->basic_constraint_indices_begin();
00437   }
00438 
00439   Index_iterator basic_constraint_indices_end() const
00440   {
00441     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00442     return solver()->basic_constraint_indices_end();
00443   }
00444 
00445   int number_of_basic_constraints() const
00446   {
00447     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00448     return solver()->number_of_basic_constraints();
00449   }
00450 
00451   Optimality_certificate_numerator_iterator 
00452   optimality_certificate_numerators_begin() const
00453   {
00454     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00455     CGAL_qpe_assertion(status() == QP_OPTIMAL);
00456     return solver()->lambda_numerator_begin();
00457   }
00458 
00459   Optimality_certificate_numerator_iterator 
00460   optimality_certificate_numerators_end() const
00461   {
00462     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00463     CGAL_qpe_assertion(status() == QP_OPTIMAL);
00464     return solver()->lambda_numerator_end();
00465   }
00466 
00467   Optimality_certificate_iterator 
00468   optimality_certificate_begin() const
00469   {
00470     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00471     CGAL_qpe_assertion(status() == QP_OPTIMAL);
00472     return solver()->lambda_begin();
00473   }
00474 
00475   Optimality_certificate_iterator 
00476   optimality_certificate_end() const
00477   {
00478     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00479     CGAL_qpe_assertion(status() == QP_OPTIMAL);
00480     return solver()->lambda_end();
00481   }
00482 
00483   // infeasibility
00484   // -------------
00485   Infeasibility_certificate_iterator 
00486   infeasibility_certificate_begin() const
00487   {
00488     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00489     CGAL_qpe_assertion(status() == QP_INFEASIBLE);
00490     return solver()->lambda_numerator_begin();
00491   }
00492 
00493   Infeasibility_certificate_iterator 
00494   infeasibility_certificate_end() const
00495   {
00496     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00497     CGAL_qpe_assertion(status() == QP_INFEASIBLE);
00498     return solver()->lambda_numerator_end();
00499   }
00500   
00501   // unboundedness
00502   // -------------
00503   Unboundedness_certificate_iterator unboundedness_certificate_begin() const
00504   {
00505     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00506     CGAL_qpe_assertion(status() == QP_UNBOUNDED);
00507     return solver()->unbounded_direction_begin();
00508   }
00509 
00510   Unboundedness_certificate_iterator unboundedness_certificate_end() const
00511   {
00512     CGAL_qpe_assertion_msg(!is_void(), "Solution not initialized");
00513     CGAL_qpe_assertion(status() == QP_UNBOUNDED);
00514     return solver()->unbounded_direction_end();
00515   }
00516 
00517 private:
00518   ET et0; // 0
00519 
00520   // validity
00521   // --------
00522   
00523   // error message returned by failing validation
00524   std::string err_msg;
00525 
00526   // the error message is set by the following function
00527   bool error (const std::string& message) 
00528   {
00529     err_msg = message;
00530     return false;
00531   }
00532 
00533 public:
00534   bool is_valid() const
00535   {
00536     return err_msg.empty();
00537   }
00538 
00539   const std::string& get_error() const
00540   {
00541     return err_msg;
00542   }
00543 
00544   // these four methods use the certificates to validate the solution
00545   // of all four program types; in case this fails, the solution becomes
00546   // invalid (and this explains why the methods are non-const)
00547   template <class QuadraticProgram>
00548   bool solves_quadratic_program 
00549   (const QuadraticProgram& qp)
00550   { return solves_program(qp, Tag_false(), Tag_false()); }
00551 
00552   template <class LinearProgram>
00553   bool solves_linear_program 
00554   (const LinearProgram& lp)
00555   { return solves_program(lp, Tag_true(), Tag_false()); }
00556 
00557   template <class NonnegativeQuadraticProgram>
00558   bool solves_nonnegative_quadratic_program 
00559   (const NonnegativeQuadraticProgram& qp)
00560   { return solves_program(qp, Tag_false(), Tag_true()); }
00561 
00562   template <class NonnegativeLinearProgram>
00563   bool solves_nonnegative_linear_program 
00564   (const NonnegativeLinearProgram& lp)
00565   { return solves_program(lp, Tag_true(), Tag_true()); }
00566 
00567   // helper used by all four validation methods above; see
00568   // QP_solver/QP_solution_impl.h for its implementation 
00569   template <class Program, typename Is_linear, typename Is_nonnegative>
00570   bool solves_program (const Program& p, 
00571                        Is_linear is_linear, Is_nonnegative is_nonnegative);
00572 
00573 private:
00574   // helpers used by the previous method 
00575   template <typename Program>
00576   bool is_feasible (const Program& p, 
00577                     typename std::vector<ET>& ax_minus_b,
00578                     Tag_true /*is_nonnegative*/);
00579   template <typename Program>
00580   bool is_feasible (const Program& p, 
00581                     typename std::vector<ET>& ax_minus_b,
00582                     Tag_false /*is_nonnegative*/);
00583 
00584   template <typename Program>
00585   bool is_optimal_1 (const Program& p);
00586 
00587   template <typename Program>
00588   bool is_optimal_2 (const Program& p, 
00589                      const typename std::vector<ET>& ax_minus_b);
00590 
00591   template <typename Program>
00592   bool is_optimal_3 (const Program& p, typename std::vector<ET>& two_Dx,
00593                      Tag_true /*is_linear*/, Tag_true /*is_nonnegative*/);
00594   template <typename Program>
00595   bool is_optimal_3 (const Program& p, typename std::vector<ET>& two_Dx,
00596                      Tag_false /*is_linear*/, Tag_true /*is_nonnegative*/);
00597   template <typename Program>
00598   bool is_optimal_3 (const Program& p, typename std::vector<ET>& two_Dx,
00599                      Tag_true /*is_linear*/, Tag_false /*is_nonnegative*/);
00600   template <typename Program>
00601   bool is_optimal_3 (const Program& p, typename std::vector<ET>& two_Dx,
00602                      Tag_false /*is_linear*/, Tag_false /*is_nonnegative*/);
00603 
00604   template <typename Program>
00605   bool is_infeasible_1 (const Program& p);
00606 
00607   template <typename Program>
00608   bool is_infeasible_2 (const Program& p, 
00609                         typename std::vector<ET>& lambda_a,
00610                         Tag_true /*is_nonnegative*/);
00611   template <typename Program>
00612   bool is_infeasible_2 (const Program& p, 
00613                         typename std::vector<ET>& lambda_a,
00614                         Tag_false /*is_nonnegative*/);
00615 
00616   template <typename Program>
00617   bool is_infeasible_3 (const Program& p, 
00618                         const typename std::vector<ET>& /*lambda_a*/,
00619                         Tag_true /*is_nonnegative*/); 
00620   template <typename Program>
00621   bool is_infeasible_3 (const Program& p, 
00622                         const typename std::vector<ET>& lambda_a,
00623                         Tag_false /*is_nonnegative*/);
00624  
00625   template <typename Program>
00626   bool is_unbounded_1 (const Program& p);
00627  
00628   template <typename Program>
00629   bool is_unbounded_2 (const Program& p, Tag_true /*is_nonnegative*/);
00630   template <typename Program>
00631   bool is_unbounded_2 (const Program& p, Tag_false /*is_nonnegative*/);
00632 
00633   template <typename Program>
00634   bool is_unbounded_3 (const Program& p, Tag_true /*is_linear*/);
00635   template <typename Program>
00636   bool is_unbounded_3 (const Program& p, Tag_false /*is_linear*/);
00637 
00638   template <typename Program>
00639   bool is_value_correct 
00640   (const Program& p, typename std::vector<ET>& /*two_Dx*/, 
00641    Tag_true /*is_linear*/); 
00642   
00643   template <typename Program>
00644   bool is_value_correct 
00645   (const Program& p, typename std::vector<ET>& two_Dx,
00646    Tag_false /*is_linear*/); 
00647 
00648   template <typename Program>
00649   bool are_constraints_feasible 
00650   (const Program& p, typename std::vector<ET>& ax);
00651 
00652   template <typename Program>
00653   bool are_bounds_feasible (const Program& p,  Tag_true /*is_nonnegative*/);
00654   template <typename Program>
00655   bool are_bounds_feasible (const Program& p,  Tag_false /*is_nonnegative*/);
00656   
00657   template <typename Program, typename Z_iterator >
00658   void add_Az 
00659   (const Program& p, Z_iterator z, typename std::vector<ET>& v);
00660 
00661   template <typename Program, typename Z_iterator >
00662   void add_two_Dz 
00663   (const Program& p, Z_iterator z, typename std::vector<ET>& v);
00664   
00665   template <typename Program, typename Z_iterator >
00666   void add_zA 
00667   (const Program& p, Z_iterator z, typename std::vector<ET>& v);
00668 
00669   template <typename Program>
00670   void add_c
00671   (const Program& p, typename std::vector<ET>& v);
00672 
00673 }; 
00674 
00675 // output
00676 template <typename ET>
00677 std::ostream& operator<<
00678   (std::ostream& o, const Quadratic_program_solution<ET>& s)
00679 {
00680   o << "status:          ";
00681   switch (s.status()) {
00682   case QP_INFEASIBLE:
00683     return o << "INFEASIBLE\n";
00684   case QP_UNBOUNDED:
00685     return o << "UNBOUNDED\n";
00686   case QP_OPTIMAL:
00687     o << "OPTIMAL\n";
00688     break;
00689   default:
00690     CGAL_qpe_assertion(false);
00691   }
00692   o << "objective value: " << s.objective_value() << "\n";
00693   o << "variable values:\n";
00694   int j=0;
00695   for ( typename Quadratic_program_solution<ET>::Variable_value_iterator 
00696           it = s.variable_values_begin(); 
00697         it < s.variable_values_end(); ++it, ++j)
00698     o << "  " << j << ": " << *it << "\n";
00699   return o; 
00700 }
00701 
00702 // Details
00703 namespace QP_solution_detail {
00704   // Quotient_normalizer
00705   // -------------------
00706   template < typename ET>
00707   class Quotient_normalizer {
00708   public:
00709     typedef CGAL::Quotient<ET> result_type;
00710    
00711   private:
00712       typedef CGAL::Algebraic_structure_traits<ET> AST;
00713       typedef typename AST::Algebraic_category Category; 
00714     
00715   public:
00716       typedef CGAL::Boolean_tag<
00717       CGAL::is_same_or_derived<CGAL::Unique_factorization_domain_tag,Category>::value> 
00718       Has_gcd;
00719     
00720       typedef CGAL::Boolean_tag<
00721       CGAL::is_same_or_derived<CGAL::Integral_domain_tag,Category>::value> 
00722       Has_exact_division;
00723 
00724     CGAL::Quotient<ET> normalize 
00725     (const CGAL::Quotient<ET>& q, 
00726      Tag_true /*has_gcd*/,
00727      Tag_true /*has_exact_division*/) const
00728     {
00729       if (CGAL::is_zero (q.numerator()))
00730         return CGAL::Quotient<ET>(ET(0), ET(1));
00731       ET gcd = CGAL::gcd (q.numerator(), q.denominator());
00732       return CGAL::Quotient<ET> 
00733         (CGAL::integral_division (q.numerator(), gcd),
00734          CGAL::integral_division (q.denominator(), gcd));
00735     }  
00736 
00737     CGAL::Quotient<ET> normalize 
00738     (const CGAL::Quotient<ET>& q, 
00739      Tag_true /*has_gcd*/,
00740      Tag_false /*has_exact_division*/) const
00741     {
00742       return q;
00743     }
00744   
00745     CGAL::Quotient<ET> normalize 
00746     (const CGAL::Quotient<ET>& q, 
00747      Tag_false /*has_gcd*/,
00748      Tag_true /*has_exact_division*/) const
00749     {
00750       return q;
00751     }
00752 
00753     CGAL::Quotient<ET> normalize 
00754     (const CGAL::Quotient<ET>& q, 
00755      Tag_false /*has_gcd*/,
00756      Tag_false /*has_exact_division*/) const
00757     {
00758       return q;
00759     }
00760 
00761     CGAL::Quotient<ET> operator() (const CGAL::Quotient<ET>& q) const
00762     {
00763       return normalize (q, Has_gcd(), Has_exact_division());
00764     }
00765   };
00766 
00767   // Value_by_index
00768   // --------------
00769   template < typename ET>
00770   class Value_by_index : public std::unary_function< int, ET>
00771   {
00772   public:
00773     typedef QP_solver_base<ET> QP;
00774     typedef ET result_type;
00775 
00776     Value_by_index(const QP* solver)
00777       : s (solver)
00778     {}
00779 
00780     // returns value * denominator 
00781     result_type operator () ( int i) const
00782     {
00783       return s->variable_numerator_value(i);
00784     }
00785     
00786     const QP* s;
00787   };
00788 
00789   // Unbounded_direction_by_index
00790   // ----------------------------
00791   template < typename ET>
00792   class Unbounded_direction_by_index : public std::unary_function< int, ET>
00793   {
00794   public:
00795     typedef QP_solver_base<ET> QP;
00796     typedef ET result_type;
00797 
00798     Unbounded_direction_by_index(const QP* solver)
00799       : s (solver)
00800     {}
00801 
00802     result_type operator () ( int i) const
00803     {
00804       return s->unbounded_direction_value(i);
00805     }
00806       
00807     const QP* s;
00808   };
00809 
00810   // Lambda_by_index
00811   // ---------------
00812   template < typename ET>
00813   class Lambda_by_index : public std::unary_function< int, ET>
00814   {
00815   public:
00816     typedef QP_solver_base<ET> QP;
00817     typedef ET result_type;
00818 
00819     Lambda_by_index(const QP* solver)
00820       : s (solver)
00821     {}
00822 
00823     result_type operator () ( int i) const
00824     {
00825       return s->lambda_numerator(i);
00826     }
00827       
00828     const QP* s;
00829   };
00830 }
00831 CGAL_END_NAMESPACE
00832 
00833 #include <CGAL/QP_solver/QP_solution_impl.h>
00834 
00835 #endif// CGAL_QP_SOLUTION_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines