BWAPI
|
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 // Licensees 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_solver/Initialization.h $ 00015 // $Id: Initialization.h 46194 2008-10-09 13:07:49Z gaertner $ 00016 // 00017 // 00018 // Author(s) : Sven Schoenherr 00019 // Bernd Gaertner <gaertner@inf.ethz.ch> 00020 // Franz Wessendorp 00021 // Kaspar Fischer 00022 00023 #include<CGAL/QP_functions.h> 00024 00025 CGAL_BEGIN_NAMESPACE 00026 00027 // creation & initialization 00028 // ------------------------- 00029 template < typename Q, typename ET, typename Tags > 00030 QP_solver<Q, ET, Tags>:: 00031 QP_solver(const Q& qp, const Quadratic_program_options& options) 00032 : et0(0), et1(1), et2(2), 00033 strategyP(0), 00034 inv_M_B(vout4), 00035 d(inv_M_B.denominator()), 00036 m_phase(-1), is_phaseI(false), is_phaseII(false), 00037 is_RTS_transition(false), 00038 is_LP(check_tag(Is_linear())), is_QP(!is_LP), 00039 //no_ineq(check_tag(Has_equalities_only_and_full_rank())), 00040 no_ineq(QP_functions_detail::is_in_equational_form(qp)), 00041 // may change after phase I 00042 has_ineq(!no_ineq), 00043 is_nonnegative(check_tag(Is_nonnegative())) 00044 { 00045 // init diagnostics 00046 diagnostics.redundant_equations = false; 00047 00048 // initialization as in the standard-form case: 00049 set_verbosity(options.get_verbosity()); 00050 // only if C_entry is double, we actually get filtered strategies, 00051 // otherwise we fall back to the respective non-filtered ones 00052 set_pricing_strategy(options.get_pricing_strategy()); 00053 00054 // Note: we first set the bounds and then call set() because set() 00055 // accesses qp_fl, qp_l, etc. 00056 set_explicit_bounds(qp); 00057 set(qp); 00058 00059 // initialize and solve immediately: 00060 init(); 00061 solve(); 00062 } 00063 00064 // set-up of QP 00065 00066 template < typename Q, typename ET, typename Tags > 00067 void QP_solver<Q, ET, Tags>:: 00068 set_D(const Q& /*qp*/, Tag_true /*is_linear*/) 00069 { 00070 // dummy value, never used 00071 qp_D = 0; 00072 } 00073 00074 template < typename Q, typename ET, typename Tags > 00075 void QP_solver<Q, ET, Tags>:: 00076 set_D(const Q& qp, Tag_false /*is_linear*/) 00077 { 00078 qp_D = qp.get_d(); 00079 } 00080 00081 template < typename Q, typename ET, typename Tags > 00082 void QP_solver<Q, ET, Tags>:: 00083 set(const Q& qp) 00084 { 00085 // assertions: 00086 CGAL_qpe_assertion(qp.get_n() >= 0); 00087 CGAL_qpe_assertion(qp.get_m() >= 0); 00088 00089 // store QP 00090 qp_n = qp.get_n(); qp_m = qp.get_m(); 00091 qp_A = qp.get_a(); qp_b = qp.get_b(); qp_c = qp.get_c(); qp_c0 = qp.get_c0(); 00092 00093 set_D(qp, Is_linear()); 00094 qp_r = qp.get_r(); 00095 00096 // set up slack variables and auxiliary problem 00097 // -------------------------------------------- 00098 00099 // reserve memory for slack and artificial part of `A': 00100 if (has_ineq) { 00101 const unsigned int eq = std::count(qp_r, qp_r+qp_m, CGAL::EQUAL); 00102 slack_A.reserve(qp_m - eq); 00103 art_A.reserve ( eq); 00104 art_s.insert(art_s.end(), qp_m, A_entry(0)); 00105 } else 00106 art_A.reserve( qp_m); 00107 00108 // decide on which bound the variables sit initially: 00109 if (!check_tag(Is_nonnegative())) 00110 init_x_O_v_i(); 00111 00112 set_up_auxiliary_problem(); 00113 00114 e = qp_m-slack_A.size(); // number of equalities 00115 l = (std::min)(qp_n+e+1, qp_m); // maximal size of basis in phase I 00116 00117 // diagnostic output: 00118 CGAL_qpe_debug { 00119 if (vout.verbose()) { 00120 if (vout2.verbose()) { 00121 vout2.out() << "======" << std::endl 00122 << "Set-Up" << std::endl 00123 << "======" << std::endl; 00124 } 00125 } 00126 } 00127 vout << "[ " << (is_LP ? "LP" : "QP") 00128 << ", " << qp_n << " variables, " << qp_m << " constraints" 00129 << " ]" << std::endl; 00130 CGAL_qpe_debug { 00131 if (vout2.verbose() && (!slack_A.empty())) { 00132 vout2.out() << " (" << slack_A.size() << " inequalities)"; 00133 } 00134 if (vout2.verbose()) { 00135 if (has_ineq) 00136 vout2.out() << "flag: has inequalities or rank not full" 00137 << std::endl; 00138 if (vout4.verbose()) print_program(); 00139 } 00140 } 00141 00142 // set up pricing strategy: 00143 if (strategyP != static_cast< Pricing_strategy*>(0)) 00144 strategyP->set(*this, vout2); 00145 00146 // set up basis inverse: 00147 inv_M_B.set(qp_n, qp_m, e); 00148 00149 // set phase: 00150 m_phase = 0; 00151 is_phaseI = false; 00152 is_phaseII = false; 00153 } 00154 00155 template < typename Q, typename ET, typename Tags > 00156 void QP_solver<Q, ET, Tags>:: 00157 set_explicit_bounds(const Q& qp) 00158 { 00159 set_explicit_bounds (qp, Is_nonnegative()); 00160 } 00161 00162 template < typename Q, typename ET, typename Tags > 00163 void QP_solver<Q, ET, Tags>:: 00164 set_explicit_bounds(const Q& /*qp*/, Tag_true) { 00165 // dummy values, never used 00166 qp_fl = 0; 00167 qp_l = 0; 00168 qp_fu = 0; 00169 qp_u = 0; 00170 } 00171 00172 template < typename Q, typename ET, typename Tags > 00173 void QP_solver<Q, ET, Tags>:: 00174 set_explicit_bounds(const Q& qp, Tag_false) { 00175 qp_fl = qp.get_fl(); 00176 qp_l = qp.get_l(); 00177 qp_fu = qp.get_fu(); 00178 qp_u = qp.get_u(); 00179 } 00180 00181 00182 00183 template < typename Q, typename ET, typename Tags > 00184 void QP_solver<Q, ET, Tags>:: 00185 init_x_O_v_i() 00186 { 00187 // allocate storage: 00188 x_O_v_i.reserve(qp_n); 00189 x_O_v_i.resize (qp_n); 00190 00191 // constants for comparisions: 00192 const L_entry l0(0); 00193 const U_entry u0(0); 00194 00195 // our initial solution will have all original variables nonbasic, 00196 // and so we initialize them to zero (if the bound on the variable 00197 // allows it), or to the variable's lower or upper bound: 00198 for (int i = 0; i < qp_n; ++i) { 00199 CGAL_qpe_assertion( !*(qp_fl+i) || !*(qp_fu+i) || *(qp_l+i)<=*(qp_u+i)); 00200 00201 if (*(qp_fl+i)) // finite lower bound? 00202 if (*(qp_fu+i)) // finite lower and finite upper bound? 00203 if (*(qp_l+i) == *(qp_u+i)) // fixed variable? 00204 x_O_v_i[i] = FIXED; 00205 else // finite lower and finite upper? 00206 if (*(qp_l+i) <= l0 && u0 <= *(qp_u+i)) 00207 x_O_v_i[i] = ZERO; 00208 else 00209 x_O_v_i[i] = LOWER; 00210 else // finite lower and infinite upper? 00211 if (*(qp_l+i) <= l0) 00212 x_O_v_i[i] = ZERO; 00213 else 00214 x_O_v_i[i] = LOWER; 00215 else // infinite lower bound? 00216 if (*(qp_fu+i)) // infinite lower and finite upper? 00217 if (u0 <= *(qp_u+i)) 00218 x_O_v_i[i] = ZERO; 00219 else 00220 x_O_v_i[i] = UPPER; 00221 else // infinite lower and infinite upper? 00222 x_O_v_i[i] = ZERO; 00223 } 00224 } 00225 00226 template < typename Q, typename ET, typename Tags > 00227 void QP_solver<Q, ET, Tags>:: 00228 set_up_auxiliary_problem() 00229 { 00230 ET b_max(et0); 00231 const C_entry c1(1); 00232 int i_max = -1; // i_max-th inequality is the most infeasible one 00233 int i_max_absolute = -1; // absolute index of most infeasible ineq 00234 00235 for (int i = 0; i < qp_m; ++i) { 00236 // Note: For nonstandard form problems, our initial solution is not the 00237 // zero vector (but the vector with values original_variable_value(i), 00238 // 0<=i<qp_n), and therefore, rhs=b-Ax is not simply b as in the standard 00239 // form case, but Ax_init-b: 00240 const ET rhs = check_tag(Is_nonnegative())? 00241 ET(*(qp_b+i)) : ET(*(qp_b+i)) - multiply__A_ixO(i); 00242 00243 if (has_ineq && (*(qp_r+i) != CGAL::EQUAL)) { // inequality constraint, so we 00244 // add a slack variable, and (if 00245 // needed) a special artificial 00246 if (*(qp_r+i) == CGAL::SMALLER) { // '<=' 00247 00248 // add special artificial ('< -0') in case the inequality is 00249 // infeasible for our starting point (which is the origin): 00250 if (rhs < et0) { 00251 art_s[i] = -c1; 00252 if (-rhs > b_max) { 00253 i_max = slack_A.size(); 00254 i_max_absolute = i; 00255 b_max = -rhs; 00256 } 00257 } 00258 00259 // slack variable: 00260 slack_A.push_back(std::make_pair(i, false)); 00261 } else { // '>=' 00262 00263 // add special artificial ('> +0') in case the inequality is 00264 // infeasible for our starting point (which is the origin): 00265 if (rhs > et0) { 00266 art_s[i] = c1; 00267 if (rhs > b_max) { 00268 i_max = slack_A.size(); 00269 i_max_absolute = i; 00270 b_max = rhs; 00271 } 00272 } 00273 00274 // store slack column 00275 slack_A.push_back(std::make_pair(i, true)); 00276 } 00277 00278 } else // equality constraint, so we 00279 // add an artificial variable 00280 // (Note: if rhs==et0 here then the artificial variable is (at the 00281 // moment!) not needed. However, we nonetheless add it, for the following 00282 // reason. If we did and were given an equality problem with the zero 00283 // vector as the right-hand side then NO artificials would be added at 00284 // all; so our initial basis would be empty, something we do not want.) 00285 art_A.push_back(std::make_pair(i, rhs < et0)); 00286 } 00287 00288 // Note: in order to make our initial starting point (which is the origin) a 00289 // feasible point of the auxiliary problem, we need to initialize the 00290 // special artificial value correctly, namely to 00291 // 00292 // max { |b_i| | i is index of an infeasible inequality constraint }. (C1) 00293 // 00294 // The index of this "most infeasible" constraint is, at this point of the 00295 // code, i_max (or i_max is -1 in which case all inequality constraints are 00296 // feasible and hence no special artififial column is needed at all). 00297 00298 // prepare initialization of special artificial column: 00299 // Note: the real work is done in init_basis() below. 00300 if (i_max >= 0) { 00301 art_s_i = i_max; // Note: the actual 00302 art_basic = i_max_absolute; // initialization of art_s_i 00303 // will be done in init_basis() 00304 // below. We misuse art_s_i to 00305 // remember i_max and art_basic 00306 // to remember i_max_absolute 00307 } else { // no special art col needed 00308 art_s_i = -1; 00309 art_s.clear(); 00310 } 00311 } 00312 00313 // initialization (phase I) 00314 template < typename Q, typename ET, typename Tags > 00315 void QP_solver<Q, ET, Tags>:: 00316 init() 00317 { 00318 CGAL_qpe_debug { 00319 vout2 << std::endl 00320 << "==============" << std::endl 00321 << "Initialization" << std::endl 00322 << "==============" << std::endl; 00323 00324 } 00325 00326 // set status: 00327 m_phase = 1; 00328 m_status = QP_UPDATE; 00329 m_pivots = 0; 00330 is_phaseI = true; 00331 is_phaseII = false; 00332 00333 // initial basis and basis inverse 00334 init_basis(); 00335 00336 // initialize additional data members 00337 init_additional_data_members(); 00338 00339 // initial solution 00340 init_solution(); 00341 00342 // initialize pricing strategy 00343 CGAL_qpe_assertion(strategyP != static_cast< Pricing_strategy*>(0)); 00344 strategyP->init(0); 00345 00346 // basic feasible solution already available? 00347 if (art_basic == 0) { 00348 00349 // transition to phase II 00350 CGAL_qpe_debug { 00351 if (vout2.verbose()) { 00352 vout2.out() << std::endl 00353 << "no artificial variables at all " 00354 << "--> skip phase I" 00355 << std::endl; 00356 } 00357 } 00358 transition(); 00359 } 00360 } 00361 00362 // Set up the initial basis and basis inverse. 00363 template < typename Q, typename ET, typename Tags > 00364 void QP_solver<Q, ET, Tags>:: 00365 init_basis() 00366 { 00367 int s_i = -1; 00368 int s_i_absolute = -1; 00369 const int s = slack_A.size(); 00370 00371 // has special artificial column? 00372 if (!art_s.empty()) { 00373 00374 // Note: we maintain the information about the special artificial column in 00375 // the variable art_s_i and the vector s_art; in addition, however, we also 00376 // add a special "fake" column to art_A. This "fake" column has (in 00377 // constrast to the special artificial column) only one nonzero entry, 00378 // namely a +-1 for the most infeasible row (see (C1) above). 00379 00380 // add "fake" column to art_A: 00381 s_i = art_s_i; // s_i-th ineq. is most infeasible, see (C1) 00382 s_i_absolute = art_basic; // absolute index of most infeasible ineq 00383 art_s_i = qp_n+s+art_A.size(); // number of special artificial var 00384 // BG: By construction of art_s_i (= i_max) in set_up_auxiliary_problem(), 00385 // s_i conforms with the indexing of slack_A, and the sign of the +-1 00386 // entry is just the negative of the corresponding slackie; this explains 00387 // the second parameter of make_pair. But the index passed as the 00388 // first parameter must refer to the ABSOLUTE index of the most 00389 // infeasible row. Putting s_i here is therefore a mistake unless 00390 // we only have equality constraints 00391 00392 // art_A.push_back(std::make_pair(s_i, !slack_A[s_i].second)); 00393 CGAL_qpe_assertion(s_i_absolute >= 0); 00394 CGAL_qpe_assertion(s_i_absolute == slack_A[s_i].first); 00395 art_A.push_back(std::make_pair(s_i_absolute, !slack_A[s_i].second)); 00396 } 00397 00398 // initialize indices of basic variables: 00399 if (!in_B.empty()) in_B.clear(); 00400 in_B.reserve(qp_n+s+art_A.size()); 00401 in_B.insert(in_B.end(), qp_n, -1); // no original variable is basic 00402 00403 init_basis__slack_variables(s_i, no_ineq); 00404 00405 if (!B_O.empty()) B_O.clear(); 00406 B_O.reserve(qp_n); // all artificial variables are basic 00407 for (int i = 0; i < (int)art_A.size(); ++i) { 00408 B_O .push_back(qp_n+s+i); 00409 in_B.push_back(i); 00410 } 00411 art_basic = art_A.size(); 00412 00413 // initialize indices of 'basic' and 'nonbasic' constraints: 00414 if (!C.empty()) C.clear(); 00415 init_basis__constraints(s_i, no_ineq); 00416 00417 // diagnostic output: 00418 CGAL_qpe_debug { 00419 if (vout.verbose()) print_basis(); 00420 } 00421 00422 // initialize basis inverse (explain: 'art_s' not needed here (todo kf: don't 00423 // understand this note)): 00424 // BG: as we only look at the basic constraints, the fake column in art_A 00425 // will do as nicely as the actual column arts_s 00426 inv_M_B.init(art_A.size(), art_A.begin()); 00427 } 00428 00429 template < typename Q, typename ET, typename Tags > inline // no ineq. 00430 void QP_solver<Q, ET, Tags>:: 00431 init_basis__slack_variables( int, Tag_true) 00432 { 00433 // nop 00434 } 00435 00436 template < typename Q, typename ET, typename Tags > // has ineq. 00437 void QP_solver<Q, ET, Tags>:: 00438 init_basis__slack_variables(int s_i, Tag_false) // Note: s_i-th inequality is 00439 // the most infeasible one, 00440 // see (C1). 00441 { 00442 const int s = slack_A.size(); 00443 00444 // reserve memory: 00445 if (!B_S.empty()) B_S.clear(); 00446 B_S.reserve(s); 00447 00448 // all slack variables are basic, except the slack variable corresponding to 00449 // special artificial variable (which is nonbasic): (todo kf: I do not 00450 // understand this) 00451 // BG: the s_i-th inequality is the most infeasible one, and the i-th 00452 // inequality corresponds to the slackie of index qp_n + i 00453 for (int i = 0; i < s; ++i) // go through all inequalities 00454 if (i != s_i) { 00455 in_B.push_back(B_S.size()); 00456 B_S .push_back(i+qp_n); 00457 } else 00458 in_B.push_back(-1); 00459 } 00460 00461 template < typename Q, typename ET, typename Tags > inline // no ineq. 00462 void QP_solver<Q, ET, Tags>:: 00463 init_basis__constraints( int, Tag_true) 00464 { 00465 // reserve memory: 00466 C.reserve(qp_m); 00467 in_C.reserve(qp_m); 00468 00469 // As there are no inequalities, C consists of all inequality constraints 00470 // only, so we add them all: 00471 for (int i = 0; i < qp_m; ++i) { 00472 C.push_back(i); 00473 } 00474 } 00475 00476 template < typename Q, typename ET, typename Tags > // has ineq. 00477 void QP_solver<Q, ET, Tags>:: 00478 init_basis__constraints(int s_i, Tag_false) // Note: s_i-th inequality is the 00479 // most infeasible one, see (C1). 00480 { 00481 int i, j; 00482 00483 // reserve memory: 00484 if (!in_C.empty()) in_C.clear(); 00485 if (! S_B.empty()) S_B.clear(); 00486 C.reserve(l); 00487 S_B.reserve(slack_A.size()); 00488 00489 // store constraints' indices: 00490 in_C.insert(in_C.end(), qp_m, -1); 00491 if (s_i >= 0) s_i = slack_A[s_i].first; // now s_i is absolute index 00492 // of most infeasible row 00493 for (i = 0, j = 0; i < qp_m; ++i) 00494 if (*(qp_r+i) == CGAL::EQUAL) { // equal. constraint basic 00495 C.push_back(i); 00496 in_C[i] = j; 00497 ++j; 00498 } else { // ineq. constraint nonbasic 00499 if (i != s_i) // unless it's most infeasible 00500 S_B.push_back(i); 00501 } 00502 // now handle most infeasible inequality if any 00503 if (s_i >= 0) { 00504 C.push_back(s_i); 00505 in_C[s_i] = j; 00506 } 00507 } 00508 00509 // Initialize r_C. 00510 template < typename Q, typename ET, typename Tags > // Standard form 00511 void QP_solver<Q, ET, Tags>:: 00512 init_r_C(Tag_true) 00513 { 00514 } 00515 00516 // Initialize r_C. 00517 template < typename Q, typename ET, typename Tags > // Upper bounded 00518 void QP_solver<Q, ET, Tags>:: 00519 init_r_C(Tag_false) 00520 { 00521 r_C.resize(C.size()); 00522 multiply__A_CxN_O(r_C.begin()); 00523 } 00524 00525 // Initialize r_S_B. 00526 template < typename Q, typename ET, typename Tags > // Standard form 00527 void QP_solver<Q, ET, Tags>:: 00528 init_r_S_B(Tag_true) 00529 { 00530 } 00531 00532 // Initialize r_S_B. 00533 template < typename Q, typename ET, typename Tags > // Upper bounded 00534 void QP_solver<Q, ET, Tags>:: 00535 init_r_S_B(Tag_false) 00536 { 00537 r_S_B.resize(S_B.size()); 00538 multiply__A_S_BxN_O(r_S_B.begin()); 00539 } 00540 00541 template < typename Q, typename ET, typename Tags > inline // no ineq. 00542 void QP_solver<Q, ET, Tags>:: 00543 init_solution__b_C(Tag_true) 00544 { 00545 b_C.reserve(qp_m); 00546 std::copy(qp_b, qp_b+qp_m, std::back_inserter(b_C)); 00547 } 00548 00549 template < typename Q, typename ET, typename Tags > inline // has ineq. 00550 void QP_solver<Q, ET, Tags>:: 00551 init_solution__b_C(Tag_false) 00552 { 00553 b_C.insert(b_C.end(), l, et0); 00554 B_by_index_accessor b_accessor(qp_b); // todo kf: is there some boost 00555 // replacement for this accessor? 00556 std::copy(B_by_index_iterator(C.begin(), b_accessor), 00557 B_by_index_iterator(C.end (), b_accessor), 00558 b_C.begin()); 00559 } 00560 00561 // initial solution 00562 template < typename Q, typename ET, typename Tags > 00563 void 00564 QP_solver<Q, ET, Tags>:: 00565 init_solution() 00566 { 00567 // initialize exact version of `qp_b' restricted to basic constraints C 00568 // (implicit conversion to ET): 00569 if (!b_C.empty()) b_C.clear(); 00570 init_solution__b_C(no_ineq); 00571 00572 // initialize exact version of `aux_c' and 'minus_c_B', the 00573 // latter restricted to basic variables B_O: 00574 if (!minus_c_B.empty()) minus_c_B.clear(); 00575 minus_c_B.insert(minus_c_B.end(), l, -et1); // todo: what is minus_c_B? 00576 CGAL_qpe_assertion(l >= (int)art_A.size()); 00577 if (art_s_i > 0) 00578 minus_c_B[art_A.size()-1] *= ET(qp_n+qp_m); // Note: the idea here is to 00579 // give more weight to the 00580 // special artifical variable 00581 // so that it gets removed very 00582 // early, - todo kf: why? 00583 00584 // ...and now aux_c: as we want to make all artificial variables (including 00585 // the special one) zero, we weigh these variables with >= 1 in the objective 00586 // function (and leave the other entries in the objective function at zero): 00587 aux_c.reserve(art_A.size()); 00588 aux_c.insert(aux_c.end(), art_A.size(), 0); 00589 for (int col=qp_n+slack_A.size(); col<number_of_working_variables(); ++col) 00590 if (col==art_s_i) // special artificial? 00591 aux_c[col-qp_n-slack_A.size()]= qp_n+qp_m; 00592 else // normal artificial 00593 aux_c[col-qp_n-slack_A.size()]= 1; 00594 00595 // allocate memory for current solution: 00596 if (!lambda.empty()) lambda.clear(); 00597 if (!x_B_O .empty()) x_B_O .clear(); 00598 if (!x_B_S .empty()) x_B_S .clear(); 00599 lambda.insert(lambda.end(), l, et0); 00600 x_B_O .insert(x_B_O .end(), l, et0); 00601 x_B_S .insert(x_B_S .end(), slack_A.size(), et0); 00602 00603 #if 0 // todo kf: I guess the following can be removed... 00604 //TESTING the updates of r_C, r_S_B, r_B_O, w 00605 // ratio_test_bound_index = LOWER; 00606 //direction = 1; 00607 #endif 00608 00609 // The following sets the pricing direction to "up" (meaning that 00610 // the priced variable will be increased and not decreased); the 00611 // statement is completely useless except that it causes debugging 00612 // output to be consistent in case we are running in standard form. 00613 // (If we are in standard form, the variable 'direction' is never 00614 // touched; otherwise, it will be set to the correct value during 00615 // each pricing step.) 00616 direction = 1; 00617 00618 // initialization of vectors r_C, r_S_B: 00619 init_r_C(Is_nonnegative()); 00620 init_r_S_B(Is_nonnegative()); 00621 00622 // compute initial solution: 00623 compute_solution(Is_nonnegative()); 00624 00625 // diagnostic output: 00626 CGAL_qpe_debug { 00627 if (vout.verbose()) print_solution(); 00628 } 00629 } 00630 00631 // Initialize additional data members. 00632 template < typename Q, typename ET, typename Tags > 00633 void 00634 QP_solver<Q, ET, Tags>:: 00635 init_additional_data_members() 00636 { 00637 // todo kf: do we really have to insert et0, or would it suffice to just 00638 // resize() in the following statements? 00639 // BG: no clue, but it's at least safe that way 00640 00641 if (!A_Cj.empty()) A_Cj.clear(); 00642 A_Cj.insert(A_Cj.end(), l, et0); 00643 if (!two_D_Bj.empty()) two_D_Bj.clear(); 00644 two_D_Bj.insert(two_D_Bj.end(), l, et0); 00645 00646 if (!q_lambda.empty()) q_lambda.clear(); 00647 q_lambda.insert(q_lambda.end(), l, et0); 00648 if (!q_x_O.empty()) q_x_O.clear(); 00649 q_x_O.insert(q_x_O.end(), l, et0); 00650 if (!q_x_S.empty()) q_x_S.clear(); 00651 q_x_S.insert(q_x_S.end(), slack_A.size(), et0); 00652 00653 if (!tmp_l.empty()) tmp_l.clear(); 00654 tmp_l.insert(tmp_l.end(), l, et0); 00655 if (!tmp_l_2.empty()) tmp_l_2.clear(); 00656 tmp_l_2.insert(tmp_l_2.end(), l, et0); 00657 if (!tmp_x.empty()) tmp_x.clear(); 00658 tmp_x.insert(tmp_x.end(), l, et0); 00659 if (!tmp_x_2.empty()) tmp_x_2.clear(); 00660 tmp_x_2.insert(tmp_x_2.end(), l, et0); 00661 } 00662 00663 CGAL_END_NAMESPACE 00664 00665 // ===== EOF ==================================================================