qp_solver.h
来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 1,686 行 · 第 1/4 页
H
1,686 行
// new basis found? if ( B.size() == (unsigned int)qp_m) { i = -1; } CGAL_optimisation_assertion( check_basis( Is_lp())); } // update of basis and basis inverse void update_basis( Tag_false) // QP { if ( B.size() < max_basis) { // append variable to basis append_variable(); // remove variable from basis (if any) if ( i >= 0) remove_variable(); } else { remove_variable(); inv_M_B.multiply( A_j.begin(), two_D_Bj.begin(), q_lambda.begin(), q_x.begin()); nu = std::inner_product( q_x.begin(), q_x.end(), two_D_Bj.begin(), std::inner_product( q_lambda.begin(), q_lambda.end(), A_j.begin(), ( j < qp_n) ? -et_2*d*ET( qp_D[ j][ j]) : et_0)); append_variable(); } } void update_basis( Tag_true) // LP { CGAL_optimisation_debug { vout2 << std::endl << "<--> non-basic variable " << j << " replaces basic variable " << B[ i] << std::endl; } // update basis int l = B[ i]; in_B[ l ] = -1; // `i' leaves basis in_B[ j ] = i; // `j' enters basis B[ i] = j; // `j' replaces `i' in basis if ( is_phase_I) { if ( j >= qp_n) ++art_basic; if ( l >= qp_n) --art_basic; } CGAL_optimisation_debug { vout2 << "new "; vout2 << "basis: "; if ( vout2.verbose()) { std::copy( B.begin(), B.end(), std::ostream_iterator<int>(vout2.out()," ")); vout2.out() << std::endl; } vout3 << "new basis-inverse:" << std::endl; } // update basis inverse inv_M_B.replace( i, q_x.begin()); // update status minus_c_B[ i] = -ET( is_phase_I ? aux_c[ j] : qp_c[ j]); // notify pricing strategy strategyP->leaving_basis( l); // new basis found i = -1; } // computation of current solution void compute_current_solution( ) { if ( is_phase_I) { inv_M_B.multiply_l( minus_c_B.begin(), lambda.begin()); inv_M_B.multiply_x( b.begin(), x_B.begin()); } else { inv_M_B.multiply( b.begin(), minus_c_B.begin(), lambda.begin(), x_B.begin()); } CGAL_optimisation_debug { vout2 << std::endl; vout2 << " -c_B: "; if ( vout2.verbose()) { std::copy( minus_c_B.begin(), minus_c_B.begin()+B.size(), std::ostream_iterator<ET>( vout2.out(), " ")); vout2.out() << std::endl; } vout2 << "lambda: "; if ( vout2.verbose()) { std::copy( lambda.begin(), lambda.begin()+qp_m, std::ostream_iterator<ET>( vout2.out(), " ")); vout2.out() << std::endl; } vout2 << " x_B: "; if ( vout2.verbose()) { std::copy( x_B.begin(), x_B.begin()+B.size(), std::ostream_iterator<ET>( vout2.out(), " ")); vout2.out() << std::endl; } } } // iterated ratio test and update // ------------------------------ void iterated_ratio_test_update( ) { loop_until_basis_found( Is_lp()); } // loop until new basis is found void loop_until_basis_found( Tag_false) // QP { while ( i >= 0 ) { // ratio test (iterated) ratio_test_iterated(); // check for unboundedness if ( q_i == et_0 ) { m_phase = 3; m_status = UNBOUNDED; CGAL_optimisation_debug { vout1 << " "; vout << "problem is UNBOUNDED" << std::endl; } return; } // update (iterated) update_iterated(); } } void loop_until_basis_found( Tag_true) // LP { // nop } // ratio test (iterated) void ratio_test_iterated( ) { CGAL_optimisation_debug { vout2 << std::endl << "Ratio Test (iterated)" << std::endl << "---------------------" << std::endl; } // get `q_x' unsigned int l = in_B[ j]; std::copy( inv_M_B.column_begin( qp_m+l)+qp_m, inv_M_B.column_end ( qp_m+l) , q_x.begin()); CGAL_optimisation_debug { vout2 << "q_x[ " << l << "]: "; if ( vout2.verbose()) { std::copy( q_x.begin(), q_x.begin()+B.size(), std::ostream_iterator<ET>( vout2.out(), " ")); vout2.out() << std::endl; } } // store frequently used values ET x_j = x_B[ l]; ET q_j = q_x[ l]; int sign_q_i_q_j = CGAL_NTS sign( q_j); // initialize minimum x_i = ( sign_q_i_q_j < 0) ? et_1 : -et_1; // trick: initialize q_i = et_0; // minimum with +oo // check `t_i's Value_iterator x_it = x_B.begin(); Value_iterator q_it = q_x.begin(); for ( unsigned int k = 0; k < B.size(); ++k, ++x_it, ++q_it) { if ( ( k != l) // t_i > 0 ? && (/* (( *q_it > et_0) && ( *x_it * q_j < x_j * *q_it)) ||*/ (( *q_it < et_0) && ( *x_it * q_j > x_j * *q_it))) // t_i < t_min ? && ( ( ( CGAL_NTS sign( *q_it) * sign_q_i_q_j > 0) && ( *x_it * q_i > x_i * *q_it)) || ( ( CGAL_NTS sign( *q_it) * sign_q_i_q_j < 0) && ( *x_it * q_i < x_i * *q_it)))) { // store new minimum i = k; x_i = *x_it; q_i = *q_it; sign_q_i_q_j = CGAL_NTS sign( q_j) * CGAL_NTS sign( q_i); } } // check `t_j' if ( ( x_j > et_0) && ( CGAL_NTS sign( x_i) * sign_q_i_q_j <= 0)) { i = -1; q_i = et_1; } CGAL_optimisation_debug { vout2 << std::endl; for ( unsigned int k = 0; k < B.size(); ++k) { if ( k != l) { vout2 << "t_" << k << ": " << x_j * q_x[k] - x_B[k] * q_j << '/' << q_x[k] << ( ( q_i != et_0) && (i == (int)k) ? " *" : "") << std::endl; } } vout2 << "t_j: " << x_j << '/' << et_1 << ( ( q_i > et_0) && ( i < 0) ? " *" : "") << std::endl << std::endl; if ( q_i != et_0) { if ( i < 0) { vout2 << "leaving variable: none" << std::endl; } else { vout1 << ", "; vout << "leaving"; vout2 << " variable"; vout << ": "; vout << B[ i]; vout2 << " (= B[ " << i << "])" << std::endl; } } } } // update (iterated) void update_iterated( ) { if ( i >= 0) { CGAL_optimisation_debug { vout2 << std::endl << "Update (iterated)" << std::endl << "-----------------"; } // update basis and basis inverse remove_variable(); CGAL_optimisation_assertion( check_basis( Is_lp())); // compute current solution compute_current_solution(); } } bool check_basis( Tag_true) // LP { return true; } bool check_basis( Tag_false) { if ( is_phase_I) return true; Values result( qp_m+B.size()); Values col_l( qp_m, et_0), col_x( B.size()); unsigned int i, j; // first part for ( i = 0; i < (unsigned int)qp_m; ++i) { // get source column for ( j = 0; j < B.size(); ++j) col_x[ j] = qp_A[ B[ j]][ i]; // compute target column inv_M_B.multiply( col_l.begin(), col_x.begin(), result.begin(), result.begin()+qp_m); // check result /* std::copy( result.begin(), result.end(), std::ostream_iterator<ET>( std::cerr, " ")); std::cerr << endl; */ for ( j = 0; j < qp_m+B.size(); ++j) { if ( ( ( j == i) && result[ j] != d) || ( ( j != i) && result[ j] != et_0)) return false; } } // second part for ( i = 0; i < B.size(); ++i) { j = B[ i]; // get source column std::copy( qp_A[ j], qp_A[ j]+qp_m, col_l.begin()); Access_D_Bj access_D_Bj( qp_D[ j], nt_0, 0, qp_n); std::transform( D_Bj_iterator( B.begin(), access_D_Bj), D_Bj_iterator( B.end (), access_D_Bj), col_x.begin(), std::bind1st( std::multiplies<ET>(), et_2)); // compute target column inv_M_B.multiply( col_l.begin(), col_x.begin(), result.begin(), result.begin()+qp_m); // check result /* std::copy( result.begin(), result.end(), std::ostream_iterator<ET>( std::cerr, " ")); std::cerr << endl; */ for ( j = 0; j < qp_m+B.size(); ++j) { if ( ( ( j == i+qp_m) && result[ j] != d) || ( ( j != i+qp_m) && result[ j] != et_0)) return false; } } return true; } }; CGAL_END_NAMESPACE#include <CGAL/_QP_solver/Pricing_strategy_base.h>#include <CGAL/_QP_solver/Full_exact_pricing.h>CGAL_BEGIN_NAMESPACEtemplate < class Rep_ >QP_solver<Rep_>:: QP_solver( int verbose, std::ostream& stream) : nt_0( 0), nt_1( 1), nt_minus_1( -nt_1), et_0( 0), et_1( 1), et_2( 2), vout1( verbose == 1, stream), vout2( verbose >= 2, stream), vout3( verbose == 3, stream), vout ( verbose > 0, stream), qp_n( 0), qp_m( 0), inv_M_B( vout3), m_phase( 0), d( inv_M_B.denominator()), strategyP( new Pricing_strategy_default) { CGAL_optimisation_debug { vout2 << "======================================" << std::endl << "The CGAL Solver for Quadratic Programs" << std::endl << "======================================" << std::endl; } }template < class Rep_ >const typename QP_solver<Rep_>::Pricing_strategy&QP_solver<Rep_>:: pricing_strategy() const { return *strategyP; } template < class Rep_ >voidQP_solver<Rep_>:: set_pricing_strategy( typename QP_solver<Rep_>::Pricing_strategy& pricing_strategy) { CGAL_optimisation_debug { vout2 << std::endl << "-----------------------" << std::endl << "Pricing Strategy Change" << std::endl << "-----------------------" << std::endl; } strategyP = &pricing_strategy; strategyP->set( *this, vout2); }CGAL_END_NAMESPACE#ifdef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION# include <CGAL/_QP_solver/QP_solver.C>#endif#endif // CGAL_QP_SOLVER_H// ===== EOF ==================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?