|
PPL
0.12.1
|
00001 /* PIP_Problem class implementation: non-inline functions. 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 00023 00024 #include "ppl-config.h" 00025 #include "PIP_Problem.defs.hh" 00026 #include "PIP_Tree.defs.hh" 00027 00028 namespace PPL = Parma_Polyhedra_Library; 00029 00031 std::ostream& 00032 PPL::IO_Operators::operator<<(std::ostream& s, const PIP_Problem& pip) { 00033 s << "Space dimension: " << pip.space_dimension(); 00034 s << "\nConstraints:"; 00035 for (PIP_Problem::const_iterator i = pip.constraints_begin(), 00036 i_end = pip.constraints_end(); i != i_end; ++i) 00037 s << "\n" << *i; 00038 s << "\nProblem parameters: " << pip.parameter_space_dimensions(); 00039 if (pip.get_big_parameter_dimension() == not_a_dimension()) 00040 s << "\nNo big-parameter set.\n"; 00041 else 00042 s << "\nBig-parameter: " << Variable(pip.get_big_parameter_dimension()); 00043 s << "\n"; 00044 return s; 00045 } 00046 00047 PPL::PIP_Problem::PIP_Problem(const dimension_type dim) 00048 : external_space_dim(dim), 00049 internal_space_dim(0), 00050 status(PARTIALLY_SATISFIABLE), 00051 current_solution(0), 00052 input_cs(), 00053 first_pending_constraint(0), 00054 parameters(), 00055 initial_context(), 00056 big_parameter_dimension(not_a_dimension()) { 00057 // Check for space dimension overflow. 00058 if (dim > max_space_dimension()) 00059 throw std::length_error("PPL::PIP_Problem::PIP_Problem(dim):\n" 00060 "dim exceeds the maximum allowed " 00061 "space dimension."); 00062 control_parameters_init(); 00063 PPL_ASSERT(OK()); 00064 } 00065 00066 PPL::PIP_Problem::PIP_Problem(const PIP_Problem &y) 00067 : external_space_dim(y.external_space_dim), 00068 internal_space_dim(y.internal_space_dim), 00069 status(y.status), 00070 current_solution(0), 00071 input_cs(y.input_cs), 00072 first_pending_constraint(y.first_pending_constraint), 00073 parameters(y.parameters), 00074 initial_context(y.initial_context), 00075 big_parameter_dimension(y.big_parameter_dimension) { 00076 if (y.current_solution != 0) { 00077 current_solution = y.current_solution->clone(); 00078 current_solution->set_owner(this); 00079 } 00080 control_parameters_copy(y); 00081 PPL_ASSERT(OK()); 00082 } 00083 00084 PPL::PIP_Problem::~PIP_Problem() { 00085 delete current_solution; 00086 } 00087 00088 void 00089 PPL::PIP_Problem::control_parameters_init() { 00090 control_parameters[CUTTING_STRATEGY] = CUTTING_STRATEGY_FIRST; 00091 control_parameters[PIVOT_ROW_STRATEGY] = PIVOT_ROW_STRATEGY_FIRST; 00092 } 00093 00094 void 00095 PPL::PIP_Problem::control_parameters_copy(const PIP_Problem& y) { 00096 for (dimension_type i = CONTROL_PARAMETER_NAME_SIZE; i-- > 0; ) 00097 control_parameters[i] = y.control_parameters[i]; 00098 } 00099 00100 PPL::PIP_Problem_Status 00101 PPL::PIP_Problem::solve() const { 00102 switch (status) { 00103 00104 case UNSATISFIABLE: 00105 PPL_ASSERT(OK()); 00106 return UNFEASIBLE_PIP_PROBLEM; 00107 00108 case OPTIMIZED: 00109 PPL_ASSERT(OK()); 00110 return OPTIMIZED_PIP_PROBLEM; 00111 00112 case PARTIALLY_SATISFIABLE: 00113 { 00114 PIP_Problem& x = const_cast<PIP_Problem&>(*this); 00115 // Allocate PIP solution tree root, if needed. 00116 if (current_solution == 0) 00117 x.current_solution = new PIP_Solution_Node(this); 00118 00119 // Properly resize context matrix. 00120 const dimension_type new_num_cols = parameters.size() + 1; 00121 const dimension_type old_num_cols = initial_context.num_columns(); 00122 if (old_num_cols < new_num_cols) 00123 x.initial_context.add_zero_columns(new_num_cols - old_num_cols); 00124 00125 // Computed once for all (to be used inside loop). 00126 const Variables_Set::const_iterator param_begin = parameters.begin(); 00127 const Variables_Set::const_iterator param_end = parameters.end(); 00128 00129 // This flag will be set if we insert a pending constraint 00130 // in the initial context. 00131 bool check_feasible_context = false; 00132 00133 // Go through all pending constraints. 00134 for (Constraint_Sequence::const_iterator 00135 cs_i = nth_iter(input_cs, first_pending_constraint), 00136 cs_end = input_cs.end(); cs_i != cs_end; ++cs_i) { 00137 const Constraint& c = *cs_i; 00138 const dimension_type c_space_dim = c.space_dimension(); 00139 PPL_ASSERT(external_space_dim >= c_space_dim); 00140 00141 // Check if constraint has a non-zero variable coefficient. 00142 bool has_nonzero_variable_coefficient = false; 00143 for (dimension_type i = c_space_dim; i-- > 0; ) { 00144 if (c.coefficient(Variable(i)) != 0 00145 && parameters.count(i) == 0) { 00146 has_nonzero_variable_coefficient = true; 00147 break; 00148 } 00149 } 00150 // Constraints having a non-zero variable coefficient 00151 // should not be inserted in context. 00152 if (has_nonzero_variable_coefficient) 00153 continue; 00154 00155 check_feasible_context = true; 00156 00157 x.initial_context.add_zero_rows(1, Row_Flags()); 00158 00159 Row& row = x.initial_context[x.initial_context.num_rows()-1]; 00160 00161 { 00162 Row::iterator itr = row.end(); 00163 00164 if (c.inhomogeneous_term() != 0) { 00165 itr = row.insert(0, c.inhomogeneous_term()); 00166 // Adjust inhomogeneous term if strict. 00167 if (c.is_strict_inequality()) 00168 --(*itr); 00169 } else { 00170 // Adjust inhomogeneous term if strict. 00171 if (c.is_strict_inequality()) 00172 itr = row.insert(0, -1); 00173 } 00174 dimension_type i = 1; 00175 00176 // itr may still be end(), but it can still be used as hint. 00177 for (Variables_Set::const_iterator 00178 pi = param_begin; pi != param_end; ++pi, ++i) { 00179 if (*pi < c_space_dim) { 00180 Coefficient_traits::const_reference coeff_pi 00181 = c.coefficient(Variable(*pi)); 00182 if (coeff_pi != 0) 00183 itr = row.insert(itr, i, coeff_pi); 00184 } else 00185 break; 00186 } 00187 } 00188 00189 // If it is an equality, also insert its negation. 00190 if (c.is_equality()) { 00191 x.initial_context.add_zero_rows(1, Row_Flags()); 00192 00193 // The reference `row' has been invalidated. 00194 00195 Row& last_row = x.initial_context[x.initial_context.num_rows()-1]; 00196 00197 last_row = x.initial_context[x.initial_context.num_rows()-2]; 00198 00199 for (Row::iterator 00200 i = last_row.begin(), i_end = last_row.end(); i != i_end; ++i) 00201 neg_assign(*i); 00202 } 00203 } 00204 00205 if (check_feasible_context) { 00206 // Check for feasibility of initial context. 00207 Matrix ctx_copy(initial_context); 00208 if (!PIP_Solution_Node::compatibility_check(ctx_copy)) { 00209 // Problem found to be unfeasible. 00210 delete x.current_solution; 00211 x.current_solution = 0; 00212 x.status = UNSATISFIABLE; 00213 PPL_ASSERT(OK()); 00214 return UNFEASIBLE_PIP_PROBLEM; 00215 } 00216 } 00217 00218 // Update tableau and mark constraints as no longer pending. 00219 x.current_solution->update_tableau(*this, 00220 external_space_dim, 00221 first_pending_constraint, 00222 input_cs, 00223 parameters); 00224 x.internal_space_dim = external_space_dim; 00225 x.first_pending_constraint = input_cs.size(); 00226 00227 // Actually solve problem. 00228 x.current_solution = x.current_solution->solve(*this, 00229 check_feasible_context, 00230 initial_context, 00231 parameters, 00232 external_space_dim, 00233 /*indent_level=*/ 0); 00234 // Update problem status. 00235 x.status = (x.current_solution != 0) ? OPTIMIZED : UNSATISFIABLE; 00236 00237 PPL_ASSERT(OK()); 00238 return (x.current_solution != 0) 00239 ? OPTIMIZED_PIP_PROBLEM 00240 : UNFEASIBLE_PIP_PROBLEM; 00241 } // End of handler for PARTIALLY_SATISFIABLE case. 00242 00243 } // End of switch. 00244 00245 // We should not be here! 00246 PPL_UNREACHABLE; 00247 return UNFEASIBLE_PIP_PROBLEM; 00248 } 00249 00250 PPL::PIP_Tree 00251 PPL::PIP_Problem::solution() const { 00252 if (status == PARTIALLY_SATISFIABLE) 00253 solve(); 00254 return current_solution; 00255 } 00256 00257 PPL::PIP_Tree 00258 PPL::PIP_Problem::optimizing_solution() const { 00259 if (status == PARTIALLY_SATISFIABLE) 00260 solve(); 00261 return current_solution; 00262 } 00263 00264 bool 00265 PPL::PIP_Problem::OK() const { 00266 #ifndef NDEBUG 00267 using std::endl; 00268 using std::cerr; 00269 #endif 00270 00271 if (external_space_dim < internal_space_dim) { 00272 #ifndef NDEBUG 00273 cerr << "The internal space dimension of the PIP_Problem is " 00274 << "greater than its external space dimension." 00275 << endl; 00276 ascii_dump(cerr); 00277 #endif 00278 return false; 00279 } 00280 00281 // Constraint system should be OK. 00282 const dimension_type input_cs_num_rows = input_cs.size(); 00283 for (dimension_type i = input_cs_num_rows; i-- > 0; ) 00284 if (!input_cs[i].OK()) 00285 return false; 00286 00287 // Constraint system should be space dimension compatible. 00288 for (dimension_type i = input_cs_num_rows; i-- > 0; ) { 00289 if (input_cs[i].space_dimension() > external_space_dim) { 00290 #ifndef NDEBUG 00291 cerr << "The space dimension of the PIP_Problem is smaller than " 00292 << "the space dimension of one of its constraints." 00293 << endl; 00294 ascii_dump(cerr); 00295 #endif 00296 return false; 00297 } 00298 } 00299 00300 // Test validity of control parameter values. 00301 Control_Parameter_Value strategy = control_parameters[CUTTING_STRATEGY]; 00302 if (strategy != CUTTING_STRATEGY_FIRST 00303 && strategy != CUTTING_STRATEGY_DEEPEST 00304 && strategy != CUTTING_STRATEGY_ALL) { 00305 #ifndef NDEBUG 00306 cerr << "Invalid value for the CUTTING_STRATEGY control parameter." 00307 << endl; 00308 ascii_dump(cerr); 00309 #endif 00310 return false; 00311 } 00312 00313 strategy = control_parameters[PIVOT_ROW_STRATEGY]; 00314 if (strategy < PIVOT_ROW_STRATEGY_FIRST 00315 || strategy > PIVOT_ROW_STRATEGY_MAX_COLUMN) { 00316 #ifndef NDEBUG 00317 cerr << "Invalid value for the PIVOT_ROW_STRATEGY control parameter." 00318 << endl; 00319 ascii_dump(cerr); 00320 #endif 00321 return false; 00322 } 00323 00324 if (big_parameter_dimension != not_a_dimension() 00325 && parameters.count(big_parameter_dimension) == 0) { 00326 #ifndef NDEBUG 00327 cerr << "The big parameter is set, but it is not a parameter." << endl; 00328 ascii_dump(cerr); 00329 #endif 00330 return false; 00331 } 00332 00333 if (!parameters.OK()) 00334 return false; 00335 if (!initial_context.OK()) 00336 return false; 00337 00338 if (current_solution != 0) { 00339 // Check well formedness of the solution tree. 00340 if (!current_solution->OK()) { 00341 #ifndef NDEBUG 00342 cerr << "The computed solution tree is broken.\n"; 00343 ascii_dump(cerr); 00344 #endif 00345 return false; 00346 } 00347 // Check that all nodes in the solution tree belong to *this. 00348 if (!current_solution->check_ownership(this)) { 00349 #ifndef NDEBUG 00350 cerr << "There are nodes in the solution tree " 00351 << "that are not owned by *this.\n"; 00352 ascii_dump(cerr); 00353 #endif 00354 return false; 00355 } 00356 } 00357 00358 // All checks passed. 00359 return true; 00360 } 00361 00362 void 00363 PPL::PIP_Problem::ascii_dump(std::ostream& s) const { 00364 using namespace IO_Operators; 00365 s << "\nexternal_space_dim: " << external_space_dim << "\n"; 00366 s << "\ninternal_space_dim: " << internal_space_dim << "\n"; 00367 00368 const dimension_type input_cs_size = input_cs.size(); 00369 00370 s << "\ninput_cs( " << input_cs_size << " )\n"; 00371 for (dimension_type i = 0; i < input_cs_size; ++i) 00372 input_cs[i].ascii_dump(s); 00373 00374 s << "\nfirst_pending_constraint: " << first_pending_constraint << "\n"; 00375 00376 s << "\nstatus: "; 00377 switch (status) { 00378 case UNSATISFIABLE: 00379 s << "UNSATISFIABLE"; 00380 break; 00381 case OPTIMIZED: 00382 s << "OPTIMIZED"; 00383 break; 00384 case PARTIALLY_SATISFIABLE: 00385 s << "PARTIALLY_SATISFIABLE"; 00386 break; 00387 } 00388 s << "\n"; 00389 00390 s << "\nparameters"; 00391 parameters.ascii_dump(s); 00392 00393 s << "\ninitial_context\n"; 00394 initial_context.ascii_dump(s); 00395 00396 s << "\ncontrol_parameters\n"; 00397 for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) { 00398 Control_Parameter_Value value = control_parameters[i]; 00399 switch (value) { 00400 case CUTTING_STRATEGY_FIRST: 00401 s << "CUTTING_STRATEGY_FIRST"; 00402 break; 00403 case CUTTING_STRATEGY_DEEPEST: 00404 s << "CUTTING_STRATEGY_DEEPEST"; 00405 break; 00406 case CUTTING_STRATEGY_ALL: 00407 s << "CUTTING_STRATEGY_ALL"; 00408 break; 00409 case PIVOT_ROW_STRATEGY_FIRST: 00410 s << "PIVOT_ROW_STRATEGY_FIRST"; 00411 break; 00412 case PIVOT_ROW_STRATEGY_MAX_COLUMN: 00413 s << "PIVOT_ROW_STRATEGY_MAX_COLUMN"; 00414 break; 00415 default: 00416 s << "Invalid control parameter value"; 00417 } 00418 s << "\n"; 00419 } 00420 00421 s << "\nbig_parameter_dimension: " << big_parameter_dimension << "\n"; 00422 00423 s << "\ncurrent_solution: "; 00424 if (current_solution == 0) 00425 s << "BOTTOM\n"; 00426 else if (const PIP_Decision_Node* dec = current_solution->as_decision()) { 00427 s << "DECISION\n"; 00428 dec->ascii_dump(s); 00429 } 00430 else { 00431 const PIP_Solution_Node* sol = current_solution->as_solution(); 00432 PPL_ASSERT(sol != 0); 00433 s << "SOLUTION\n"; 00434 sol->ascii_dump(s); 00435 } 00436 } 00437 00438 PPL_OUTPUT_DEFINITIONS(PIP_Problem) 00439 00440 bool 00441 PPL::PIP_Problem::ascii_load(std::istream& s) { 00442 std::string str; 00443 if (!(s >> str) || str != "external_space_dim:") 00444 return false; 00445 00446 if (!(s >> external_space_dim)) 00447 return false; 00448 00449 if (!(s >> str) || str != "internal_space_dim:") 00450 return false; 00451 00452 if (!(s >> internal_space_dim)) 00453 return false; 00454 00455 if (!(s >> str) || str != "input_cs(") 00456 return false; 00457 00458 dimension_type input_cs_size; 00459 00460 if (!(s >> input_cs_size)) 00461 return false; 00462 00463 if (!(s >> str) || str != ")") 00464 return false; 00465 00466 Constraint c(Constraint::zero_dim_positivity()); 00467 for (dimension_type i = 0; i < input_cs_size; ++i) { 00468 if (!c.ascii_load(s)) 00469 return false; 00470 input_cs.push_back(c); 00471 } 00472 00473 if (!(s >> str) || str != "first_pending_constraint:") 00474 return false; 00475 00476 if (!(s >> first_pending_constraint)) 00477 return false; 00478 00479 if (!(s >> str) || str != "status:") 00480 return false; 00481 00482 if (!(s >> str)) 00483 return false; 00484 00485 if (str == "UNSATISFIABLE") 00486 status = UNSATISFIABLE; 00487 else if (str == "OPTIMIZED") 00488 status = OPTIMIZED; 00489 else if (str == "PARTIALLY_SATISFIABLE") 00490 status = PARTIALLY_SATISFIABLE; 00491 else 00492 return false; 00493 00494 if (!(s >> str) || str != "parameters") 00495 return false; 00496 00497 if (!parameters.ascii_load(s)) 00498 return false; 00499 00500 if (!(s >> str) || str != "initial_context") 00501 return false; 00502 00503 if (!initial_context.ascii_load(s)) 00504 return false; 00505 00506 if (!(s >> str) || str != "control_parameters") 00507 return false; 00508 00509 for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) { 00510 if (!(s >> str)) 00511 return false; 00512 Control_Parameter_Value value; 00513 if (str == "CUTTING_STRATEGY_FIRST") 00514 value = CUTTING_STRATEGY_FIRST; 00515 else if (str == "CUTTING_STRATEGY_DEEPEST") 00516 value = CUTTING_STRATEGY_DEEPEST; 00517 else if (str == "CUTTING_STRATEGY_ALL") 00518 value = CUTTING_STRATEGY_ALL; 00519 else if (str == "PIVOT_ROW_STRATEGY_FIRST") 00520 value = PIVOT_ROW_STRATEGY_FIRST; 00521 else if (str == "PIVOT_ROW_STRATEGY_MAX_COLUMN") 00522 value = PIVOT_ROW_STRATEGY_MAX_COLUMN; 00523 else 00524 return false; 00525 control_parameters[i] = value; 00526 } 00527 00528 if (!(s >> str) || str != "big_parameter_dimension:") 00529 return false; 00530 if (!(s >> big_parameter_dimension)) 00531 return false; 00532 00533 // Release current_solution tree (if any). 00534 delete current_solution; 00535 current_solution = 0; 00536 // Load current_solution (if any). 00537 if (!(s >> str) || str != "current_solution:") 00538 return false; 00539 if (!(s >> str)) 00540 return false; 00541 if (str == "BOTTOM") 00542 current_solution = 0; 00543 else if (str == "DECISION") { 00544 PIP_Decision_Node* dec = new PIP_Decision_Node(0, 0, 0); 00545 current_solution = dec; 00546 if (!dec->ascii_load(s)) 00547 return false; 00548 dec->set_owner(this); 00549 } 00550 else if (str == "SOLUTION") { 00551 PIP_Solution_Node* sol = new PIP_Solution_Node(0); 00552 current_solution = sol; 00553 if (!sol->ascii_load(s)) 00554 return false; 00555 sol->set_owner(this); 00556 } 00557 else 00558 // Unknown node kind. 00559 return false; 00560 00561 PPL_ASSERT(OK()); 00562 return true; 00563 } 00564 00565 void 00566 PPL::PIP_Problem::clear() { 00567 external_space_dim = 0; 00568 internal_space_dim = 0; 00569 status = PARTIALLY_SATISFIABLE; 00570 if (current_solution != 0) { 00571 delete current_solution; 00572 current_solution = 0; 00573 } 00574 input_cs.clear(); 00575 first_pending_constraint = 0; 00576 parameters.clear(); 00577 initial_context.clear(); 00578 control_parameters_init(); 00579 big_parameter_dimension = not_a_dimension(); 00580 } 00581 00582 void 00583 PPL::PIP_Problem 00584 ::add_space_dimensions_and_embed(const dimension_type m_vars, 00585 const dimension_type m_params) { 00586 // Adding no space dims at all is a no-op: 00587 // this avoids invalidating problem status (if it was optimized). 00588 if (m_vars == 0 && m_params == 0) 00589 return; 00590 00591 // The space dimension of the resulting PIP problem should not 00592 // overflow the maximum allowed space dimension. 00593 dimension_type available = max_space_dimension() - space_dimension(); 00594 bool should_throw = (m_vars > available); 00595 if (!should_throw) { 00596 available -= m_vars; 00597 should_throw = (m_params > available); 00598 } 00599 if (should_throw) 00600 throw std::length_error("PPL::PIP_Problem::" 00601 "add_space_dimensions_and_embed(m_v, m_p):\n" 00602 "adding m_v+m_p new space dimensions exceeds " 00603 "the maximum allowed space dimension."); 00604 // First add PIP variables ... 00605 external_space_dim += m_vars; 00606 // ... then add PIP parameters. 00607 for (dimension_type i = m_params; i-- > 0; ) { 00608 parameters.insert(Variable(external_space_dim)); 00609 ++external_space_dim; 00610 } 00611 // Update problem status. 00612 if (status != UNSATISFIABLE) 00613 status = PARTIALLY_SATISFIABLE; 00614 PPL_ASSERT(OK()); 00615 } 00616 00617 void 00618 PPL::PIP_Problem 00619 ::add_to_parameter_space_dimensions(const Variables_Set& p_vars) { 00620 if (p_vars.space_dimension() > external_space_dim) 00621 throw std::invalid_argument("PPL::PIP_Problem::" 00622 "add_to_parameter_space_dimension(p_vars):\n" 00623 "*this and p_vars are dimension " 00624 "incompatible."); 00625 const dimension_type original_size = parameters.size(); 00626 parameters.insert(p_vars.begin(), p_vars.end()); 00627 // Do not allow to turn variables into parameters. 00628 for (Variables_Set::const_iterator p = p_vars.begin(), 00629 end = p_vars.end(); p != end; ++p) { 00630 if (*p < internal_space_dim) { 00631 throw std::invalid_argument("PPL::PIP_Problem::" 00632 "add_to_parameter_space_dimension(p_vars):" 00633 "p_vars contain variable indices."); 00634 } 00635 } 00636 00637 // If a new parameter was inserted, set the internal status to 00638 // PARTIALLY_SATISFIABLE. 00639 if (parameters.size() != original_size && status != UNSATISFIABLE) 00640 status = PARTIALLY_SATISFIABLE; 00641 } 00642 00643 void 00644 PPL::PIP_Problem::add_constraint(const Constraint& c) { 00645 if (c.space_dimension() > external_space_dim) { 00646 std::ostringstream s; 00647 s << "PPL::PIP_Problem::add_constraint(c):\n" 00648 << "dim == "<< external_space_dim << " and c.space_dimension() == " 00649 << c.space_dimension() << " are dimension incompatible."; 00650 throw std::invalid_argument(s.str()); 00651 } 00652 input_cs.push_back(c); 00653 // Update problem status. 00654 if (status != UNSATISFIABLE) 00655 status = PARTIALLY_SATISFIABLE; 00656 } 00657 00658 void 00659 PPL::PIP_Problem::add_constraints(const Constraint_System &cs) { 00660 for (Constraint_System::const_iterator ci = cs.begin(), 00661 ci_end = cs.end(); ci != ci_end; ++ci) 00662 add_constraint(*ci); 00663 } 00664 00665 bool 00666 PPL::PIP_Problem::is_satisfiable() const { 00667 if (status == PARTIALLY_SATISFIABLE) 00668 solve(); 00669 return status == OPTIMIZED; 00670 } 00671 00672 void 00673 PPL::PIP_Problem::set_control_parameter(Control_Parameter_Value value) { 00674 switch (value) { 00675 case CUTTING_STRATEGY_FIRST: 00676 // Intentionally fall through. 00677 case CUTTING_STRATEGY_DEEPEST: 00678 // Intentionally fall through. 00679 case CUTTING_STRATEGY_ALL: 00680 control_parameters[CUTTING_STRATEGY] = value; 00681 break; 00682 case PIVOT_ROW_STRATEGY_FIRST: 00683 // Intentionally fall through. 00684 case PIVOT_ROW_STRATEGY_MAX_COLUMN: 00685 control_parameters[PIVOT_ROW_STRATEGY] = value; 00686 break; 00687 default: 00688 throw std::invalid_argument("PPL::PIP_Problem::set_control_parameter(v)" 00689 ":\ninvalid value."); 00690 } 00691 } 00692 00693 void 00694 PPL::PIP_Problem::set_big_parameter_dimension(dimension_type big_dim) { 00695 if (parameters.count(big_dim) == 0) 00696 throw std::invalid_argument("PPL::PIP_Problem::" 00697 "set_big_parameter_dimension(big_dim):\n" 00698 "dimension 'big_dim' is not a parameter."); 00699 if (big_dim < internal_space_dim) 00700 throw std::invalid_argument("PPL::PIP_Problem::" 00701 "set_big_parameter_dimension(big_dim):\n" 00702 "only newly-added parameters can be" 00703 "converted into the big parameter."); 00704 big_parameter_dimension = big_dim; 00705 } 00706 00707 PPL::memory_size_type 00708 PPL::PIP_Problem::external_memory_in_bytes() const { 00709 memory_size_type n = initial_context.external_memory_in_bytes(); 00710 // Adding the external memory for `current_solution'. 00711 if (current_solution != 0) 00712 n += current_solution->total_memory_in_bytes(); 00713 // Adding the external memory for `input_cs'. 00714 n += input_cs.capacity() * sizeof(Constraint); 00715 for (const_iterator i = input_cs.begin(), 00716 i_end = input_cs.end(); i != i_end; ++i) 00717 n += (i->external_memory_in_bytes()); 00718 // FIXME: Adding the external memory for `parameters'. 00719 n += parameters.size() * sizeof(dimension_type); 00720 00721 return n; 00722 } 00723 00724 PPL::memory_size_type 00725 PPL::PIP_Problem::total_memory_in_bytes() const { 00726 return sizeof(*this) + external_memory_in_bytes(); 00727 } 00728 00729 void 00730 PPL::PIP_Problem::print_solution(std::ostream& s, int indent) const { 00731 switch (status) { 00732 00733 case UNSATISFIABLE: 00734 PPL_ASSERT(current_solution == 0); 00735 PIP_Tree_Node::indent_and_print(s, indent, "_|_\n"); 00736 break; 00737 00738 case OPTIMIZED: 00739 PPL_ASSERT(current_solution != 0); 00740 current_solution->print(s, indent); 00741 break; 00742 00743 case PARTIALLY_SATISFIABLE: 00744 throw std::logic_error("PIP_Problem::print_solution():\n" 00745 "the PIP problem has not been solved."); 00746 } 00747 } 00748