1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program PolySCIP */ 4 /* */ 5 /* Copyright (C) 2012-2021 Konrad-Zuse-Zentrum */ 6 /* fuer Informationstechnik Berlin */ 7 /* */ 8 /* PolySCIP is distributed under the terms of the ZIB Academic License. */ 9 /* */ 10 /* You should have received a copy of the ZIB Academic License */ 11 /* along with PolySCIP; see the file LICENCE. */ 12 /* */ 13 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 14 15 /** 16 * @file polyscip.h 17 * @brief PolySCIP solver class 18 * @author Sebastian Schenker 19 * 20 */ 21 22 #ifndef POLYSCIP_SRC_POLYSCIP_H_INCLUDED 23 #define POLYSCIP_SRC_POLYSCIP_H_INCLUDED 24 25 #include <cstdlib> 26 #include <functional> 27 #include <iostream> 28 #include <iterator> 29 #include <ostream> 30 #include <map> 31 #include <memory> 32 #include <string> 33 #include <utility> 34 #include <vector> 35 36 #include "cmd_line_args.h" 37 #include "objscip/objscip.h" 38 #include "polyscip_types.h" 39 #include "weight_space_polyhedron.h" 40 41 namespace polyscip { 42 43 /** 44 * @class TwoDProj 45 * @brief Class representing a two-dimensional projection of an outcome 46 */ 47 class TwoDProj { 48 public: 49 50 /** 51 * Default constructor 52 * @param outcome Corresponding outcome to take two-dimensional projection of 53 * @param first First (objective) index of outcome to consider for projection 54 * @param second Second (objective) index of outcome to consider for projection 55 */ 56 explicit TwoDProj(const OutcomeType& outcome, 57 std::size_t first, 58 std::size_t second); 59 60 /** 61 * Get first projection value 62 * @return First value of projection 63 */ getFirst()64 ValueType getFirst() const {return proj_.first;} 65 66 /** 67 * Get second projection value 68 * @return Second value of projection 69 */ getSecond()70 ValueType getSecond() const {return proj_.second;} 71 72 /** 73 * Ostream operator 74 * @param os Output stream 75 * @param proj Projection to write to stream 76 * @return Output stream 77 */ 78 friend std::ostream &operator<<(std::ostream& os, const TwoDProj& proj); 79 80 private: 81 std::pair<ValueType, ValueType> proj_; ///< Pair of projection values 82 83 }; 84 85 /** 86 * @class NondomProjections 87 * @brief Class representing non-dominated projections 88 */ 89 class NondomProjections { 90 public: 91 using ProjMap = std::map<TwoDProj, ResultContainer, std::function<bool(const TwoDProj&, const TwoDProj&)>>; ///< Container for non-dominated projections 92 93 /** 94 * Default constructor 95 * @param epsilon Error value for comparisons 96 * @param supported Results to take non-dominated projections 97 * @param first First (objective) index to consider for projection 98 * @param second Second (objective) index to consider for projection 99 */ 100 explicit NondomProjections(double epsilon, 101 const ResultContainer& supported, 102 std::size_t first, 103 std::size_t second); 104 105 /** 106 * Ostream operator 107 * @param os Output stream 108 * @param nd_proj Non-dominated projections to write to stream 109 * @return Output stream 110 */ 111 friend std::ostream &operator<<(std::ostream& os, const NondomProjections& nd_proj); 112 113 /** 114 * lhs-Projection epsilonDominates rhs-Projection if lhs.first - epsilon < rhs.first && lhs.second - epsilon < rhs.second 115 * @param lhs lhs-Projection 116 * @param rhs rhs-Projection 117 * @return true if lhs-Projection epsilon-dominated rhs-Projection; false otherwise 118 */ 119 bool epsilonDominates(const TwoDProj& lhs, 120 const TwoDProj& rhs) const; 121 122 /** 123 * Indicates that all stored projections are investigated 124 * @return true if all stored projections have been investigated; false otherwise 125 */ 126 bool finished() const; 127 128 /** 129 * Advances current_ iterator 130 */ 131 void update(); 132 133 /** 134 * Incorporates a new projection and corresponding result into non-dominated projections 135 * @param proj Projection to incorporated 136 * @param res Corresponding result of projection 137 */ 138 void update(TwoDProj proj, Result res); 139 140 /** 141 * Get outcomes corresponding to non-dominated projections 142 * @return Vector of outcomes corresponding to non-dominated projections 143 */ 144 std::vector<OutcomeType> getNondomProjOutcomes() const; 145 146 /** 147 * Get projection to be investigated 148 * @return Two-dimensional projection 149 */ getLeftProj()150 TwoDProj getLeftProj() const {return current_->first;}; 151 152 /** 153 * Get right neighbour of projection to be investigated 154 * @return Two-dimensional projection 155 */ getRightProj()156 TwoDProj getRightProj() const {return std::next(current_)->first;}; 157 158 /** 159 * Get projection with maximal value for second index 160 * @return Two-dimensional projection 161 */ getLastProj()162 TwoDProj getLastProj() const {return std::prev(end(nondom_projections_))->first;}; 163 164 165 private: 166 /** 167 * Add projection and corresponding result to non-dominated projections 168 * @param proj Projection to add 169 * @param res Corresponding result of projections 170 * @return Iterator pointing to proj 171 */ 172 ProjMap::iterator add(TwoDProj proj, 173 Result res); 174 175 double epsilon_; ///< Epsilon value used in fct 'epsilonDominates' 176 ProjMap nondom_projections_; ///< Container for non-dominated projections 177 ProjMap::iterator current_; ///< Currently investigated projection 178 }; 179 180 /** 181 * @class RectangularBox 182 * @brief A rectangular box R = [a_1,e_1) x ... x [a_k,e_k) is a k-ary Cartesian product of half-open intervals 183 */ 184 class RectangularBox { 185 public: 186 using Interval = std::pair<ValueType, ValueType>; ///< Interval I = [a,b) 187 188 /** 189 * Copy constructor 190 * @param box RectangularBox to copy 191 */ 192 explicit RectangularBox(const std::vector<Interval>& box); 193 194 /** 195 * Move constructor 196 * @param box RectangularBox to copy 197 */ 198 explicit RectangularBox(std::vector<Interval>&& box); 199 200 /** 201 * Ostream operator 202 * @param os Output stream to write to 203 * @param box Box to write to stream 204 * @return Output stream 205 */ 206 friend std::ostream &operator<<(std::ostream& os, const RectangularBox& box); 207 208 /** 209 * Indicates whether given box is subset 210 * @param other Box to compare 211 * @return true if 'other' is subset; false otherwise 212 */ 213 bool isSupersetOf(const RectangularBox &other) const; 214 215 /** 216 * Indicates whether given box is superset 217 * @param other Box to compare 218 * @return true if 'other' is superset; false otherwise 219 */ 220 bool isSubsetOf(const RectangularBox &other) const; 221 222 /** 223 * Indicates whether given box is disjoint 224 * @param other Box to compare 225 * @return true if 'other' is disjoint; false otherwise 226 */ 227 bool isDisjointFrom(const RectangularBox &other) const; 228 229 /** 230 * Indicates whether a_i + epsilon > e_i for all i 231 * @param epsilon Value to add to left interval limit 232 * @return true if a_i + epsilon <= e_i for all i; false otherwise 233 */ 234 bool isFeasible(double epsilon) const; 235 236 /** 237 * Makes disjoint rectangular boxes with respect to given box 238 * @param delta Feasibility threshold 239 * @param other Box to compare to 240 * @return Container of disjoint boxes 241 */ 242 std::vector<RectangularBox> getDisjointPartsFrom(double delta, const RectangularBox &other) const; 243 244 /** 245 * Get get number of intervals 246 * @return Dimension of rectangular box 247 */ 248 std::size_t size() const; 249 250 /** 251 * Get interval of box 252 * @param index Corresponding interval index 253 * @return Interval corresponding to index 254 */ 255 Interval getInterval(std::size_t index) const; 256 257 /** 258 * Indicates whether outcome dominates entire box 259 * @param outcome Outcome to compare to 260 * @return true if given outcome dominates entire box; false otherwise 261 */ 262 bool isDominated(const OutcomeType& outcome) const; 263 264 private: 265 /** 266 * Get interval intersection with respect to given dimension and given box 267 * @param index Interval index to take intersection 268 * @param other Box to consider intersection 269 * @return Interval intersection 270 */ 271 Interval getIntervalIntersection(std::size_t index, 272 const RectangularBox& other) const; 273 274 /** 275 * Constructor: constructs box first_beg x ... x (first_end-1) x second x third_bex x ... x (third_end-1) 276 * @param first_beg Iterator referring to interval 277 * @param first_end Iterator referring to past-the-end interval 278 * @param second Middle interval 279 * @param third_beg Iterator referring to interval 280 * @param third_end Iterator referring to past-the-end interval 281 */ 282 RectangularBox(std::vector<Interval>::const_iterator first_beg, 283 std::vector<Interval>::const_iterator first_end, 284 Interval second, 285 std::vector<Interval>::const_iterator third_beg, 286 std::vector<Interval>::const_iterator third_end); 287 288 std::vector<Interval> box_; ///< Container storing interval of rectangular box 289 }; 290 291 /** 292 * @class Polyscip 293 * @brief Class for PolySCIP solver functions 294 */ 295 class Polyscip { 296 public: 297 298 /** 299 * Different statuses of PolySCIP solver 300 */ 301 enum class PolyscipStatus { 302 Unsolved, ///< Initial status after calling public constructor 303 ProblemRead, ///< Status after problem instance was read successfully 304 LexOptPhase, ///< Status after lexicographic optimal results were computed 305 WeightSpacePhase, ///< Status while results of weight space polyhedron are computed 306 TwoProjPhase, ///< Status while computing 2-dimensional non-dominated projection results 307 Finished, ///< Status if problem was solved successfully 308 TimeLimitReached, ///< Status if given time limit was reached 309 Error ///< Status if an error occured 310 }; 311 312 using ObjPair = std::pair<std::size_t, std::size_t>; ///< Pair of objectives indices 313 314 /** 315 * Default constructor 316 * @param argc Argument count 317 * @param argv Argument vector 318 */ 319 explicit Polyscip(int argc, 320 const char *const *argv); 321 322 /** 323 * Destructor 324 */ 325 ~Polyscip(); 326 327 /** 328 * Read multi-objective problem file 329 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 330 */ 331 SCIP_RETCODE readProblem(); 332 333 /** 334 * Compute non-dominated points of given problem 335 * @attention readProblem() needs to be called before 336 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 337 */ 338 SCIP_RETCODE computeNondomPoints(); 339 340 /** 341 * Indicates whether results shold be written to a file 342 * @return true if results should be written to a file; otherwise false 343 */ writeResults()344 bool writeResults() const {return cmd_line_args_.writeResults();}; 345 346 /** 347 * Write results to file named 'solutions_name-of-problem-file.txt' 348 */ 349 void writeResultsToFile() const; 350 351 /** 352 * Print results 353 * @param os Output stream to print to 354 */ 355 void printResults(std::ostream &os = std::cout) const; 356 357 /** 358 * Print PolySCIP status 359 * @param os Output stream to print to 360 */ 361 void printStatus(std::ostream& os = std::cout) const; 362 363 /** 364 * Get PolySCIP status 365 * @return Current PolySCIP status 366 */ 367 PolyscipStatus getStatus() const; 368 369 /** 370 * Get number of bounded results 371 * @return Number of computed bounded results 372 */ 373 std::size_t numberOfBoundedResults() const; 374 375 /** 376 * Get number of unbounded results 377 * @return Number of computed unbounded results 378 */ 379 std::size_t numberofUnboundedResults() const; 380 381 /** 382 * Indicates whether dominated results were computed 383 * @return true if dominated bounded results were computed 384 */ 385 bool dominatedPointsFound() const; 386 387 /** 388 * Get iterator to beginning of bounded results 389 * @return Const_iterator to beginning of bounded results 390 */ boundedCBegin()391 ResultContainer::const_iterator boundedCBegin() {return bounded_.cbegin();}; 392 393 /** 394 * Get iterator to past-the-end of bounded results 395 * @return Const_iterator to past-the-end of bounded results 396 */ boundedCEnd()397 ResultContainer::const_iterator boundedCEnd() {return bounded_.cend();}; 398 399 private: 400 401 /** 402 * Check whether file can be opened 403 * @param filename Name of file to open 404 * @return true if corresponding file can be opened; false otherwise 405 */ 406 bool filenameIsOkay(const std::string &filename); 407 408 /** 409 * Compute lexicographic optimal results 410 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 411 * @param orig_vals Container storing original non-zero objective coefficients for each objective 412 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 413 */ 414 SCIP_RETCODE computeLexicographicOptResults(std::vector<std::vector<SCIP_VAR*>>& orig_vars, 415 std::vector<std::vector<ValueType>>& orig_vals); 416 417 /** 418 * Compute lexicographic optimal result with given objective having highest preference 419 * @param obj Objective with highest preference 420 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 421 * @param orig_vals Container storing original non-zero objective coefficients for each objective 422 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 423 */ 424 SCIP_RETCODE computeLexicographicOptResult(std::size_t obj, 425 std::vector<std::vector<SCIP_VAR*>>& orig_vars, 426 std::vector<std::vector<ValueType>>& orig_vals); 427 428 429 /** 430 * Checks whether results corresponding to given iterator is dominated or equal to other given elements 431 * @param it Const_iterator corresponding to result 432 * @param beg_it Const_iterator to beginning of result container 433 * @param end_it Const_iterator to past-the-end of result container 434 * @return true if result given by it is dominated or equal to other given results; false otherwise 435 */ 436 bool isDominatedOrEqual(ResultContainer::const_iterator it, 437 ResultContainer::const_iterator beg_it, 438 ResultContainer::const_iterator end_it) const; 439 440 /** 441 * Set weighted objective: weight * (c_1,...,c_k) \\cdot x 442 * @param weight Weight 443 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 444 */ 445 SCIP_RETCODE setWeightedObjective(const WeightType& weight); 446 447 /** 448 * Solves currently considered SCIP instance 449 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 450 */ 451 SCIP_RETCODE solve(); 452 453 /** 454 * Resolve INFORUNBD SCIP status to either infeasible or unbounded 455 * @param weight Weight yielding INFORUNBD status 456 * @param with_presolving Indicates whether presolving should be used or not 457 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 458 */ 459 SCIP_STATUS separateINFORUNBD(const WeightType& weight, 460 bool with_presolving = true); 461 462 /** 463 * Handle SCIP status that is neither optimal nor unbounded 464 * @param status Current SCIP status 465 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 466 */ 467 SCIP_RETCODE handleNonOptNonUnbdStatus(SCIP_STATUS status); 468 469 /** 470 * Handle unbounded SCIP status 471 * @param check_if_new_result Indicates whether to check if computed results is already known 472 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 473 */ 474 SCIP_RETCODE handleUnboundedStatus(bool check_if_new_result=false); 475 476 /** 477 * Indicates whether given outcomes coincide within some epsilon error 478 * @param a First outcome to compare 479 * @param b Second outcome to compare 480 * @param epsilon Allowed error 481 * @return true if outcomes coincides; false otherwise 482 */ 483 static bool outcomesCoincide(const OutcomeType& a, 484 const OutcomeType& b, 485 double epsilon); 486 487 /** 488 * Indicates whether given outcome was not computed before 489 * @param outcome Outcome to check 490 * @param outcome_is_bounded Indicates whether given outcome is bounded or unbounded 491 * @return true if given outcome was not computed before; false otherwise 492 */ 493 bool outcomeIsNew(const OutcomeType& outcome, 494 bool outcome_is_bounded) const; 495 496 /** 497 * Indicates whether given outcome is new with respect to other given results 498 * @param outcome Outcome to check 499 * @param beg Const_iterator to beginning of result container 500 * @param last Const_iterator to past-the-end of result container 501 * @return true if given outcome does not coincide with outcomes; false otherwise 502 */ 503 bool outcomeIsNew(const OutcomeType& outcome, 504 ResultContainer::const_iterator beg, 505 ResultContainer::const_iterator last) const; 506 507 /** 508 * Get computed result 509 * @param outcome_is_bounded Indicates whether previous computation yielded unbounded status 510 * @param primal_sol Corresponding SCIP primal solution pointer if previous computation yielded optimal status 511 * @return Result type 512 */ 513 Result getResult(bool outcome_is_bounded = false, 514 SCIP_SOL* primal_sol = nullptr); 515 516 /** 517 * Get bounded optimal result 518 * @return Result type 519 */ 520 Result getOptimalResult(); 521 522 /** 523 * Print objective 524 * @param obj_no Corresponding index of objective 525 * @param nonzero_indices Indices of variables with non-zero coefficients 526 * @param nonzero_vals Corresponding non-zero coefficient variable values 527 * @param os Output stream to write to 528 */ 529 void printObjective(std::size_t obj_no, 530 const std::vector<int>& nonzero_indices, 531 const std::vector<SCIP_Real>& nonzero_vals, 532 std::ostream& os = std::cout) const; 533 534 /** 535 * Indicates whether objective given by index is redundant 536 * @param begin_nonzeros begin_nonzeros[i+1] = begin_nonzeros[i] + obj_probdata->getNumberNonzeroCoeffs(i) 537 * @param obj_to_nonzero_indices indices of non-zero variables for each objective 538 * @param obj_to_nonzero_values non-zero variables for each objective 539 * @param index index of objective to check 540 * @return true if checked objective is redundant; false otherwise 541 */ 542 bool objIsRedundant(const std::vector<int>& begin_nonzeros, 543 const std::vector<std::vector<int>>& obj_to_nonzero_indices, 544 const std::vector<std::vector<SCIP_Real>>& obj_to_nonzero_values, 545 std::size_t index) const; 546 547 /** 548 * Compute non-dominated extreme point results 549 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 550 */ 551 SCIP_RETCODE computeWeightSpaceResults(); 552 553 /** 554 * Compute bounded non-dominated extreme points for objective for which unbounded ray exits 555 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 556 */ 557 SCIP_RETCODE computeBoundedNondomResultsForUnbdObjs(); 558 559 /** 560 * Compute non-dominated points which are not lexicographically optimal 561 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 562 * @param orig_vals Container storing original non-zero objective coefficients for each objective 563 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 564 */ 565 SCIP_RETCODE computeNonLexicographicNondomResults(const std::vector<std::vector<SCIP_VAR*>>& orig_vars, 566 const std::vector<std::vector<ValueType>>& orig_vals); 567 568 /** 569 * Compute non-dominated points via subproblems with weighted Tchebycheff norm 570 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 571 * @param orig_vals Container storing original non-zero objective coefficients for each objective 572 * @param obj_1 Index of first considered objective 573 * @param obj_2 Index of second considered objective 574 * @return Container of non-dominated outcomes which are also non-dominated for projection onto obj_1 and obj_2 575 */ 576 std::vector<OutcomeType> solveWeightedTchebycheff(const std::vector<std::vector<SCIP_VAR*>>& orig_vars, 577 const std::vector<std::vector<ValueType>>& orig_vals, 578 std::size_t obj_1, 579 std::size_t obj_2); 580 581 /** 582 * Compute disjoint rectangular boxes from given feasible rectangular boxes 583 * @param feasible_boxes List of feasible boxes 584 * @return Vector of disjoint feasible rectangular boxes 585 */ 586 std::vector<RectangularBox> computeDisjointBoxes(std::list<RectangularBox>&& feasible_boxes) const; 587 588 /** 589 * Compute feasible rectangular boxes 590 * @param proj_nondom_outcomes Non-dominated outcomes which are non-dominated for objective pair 591 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 592 * @param orig_vals Container storing original non-zero objective coefficients for each objective 593 * @return List of feasible rectangular boxes 594 */ 595 std::list<RectangularBox> computeFeasibleBoxes( 596 const std::map<ObjPair, std::vector<OutcomeType>> &proj_nondom_outcomes, 597 const std::vector<std::vector<SCIP_VAR *>> &orig_vars, 598 const std::vector<std::vector<ValueType>> &orig_vals); 599 600 /** 601 * Compute locally non-dominated results in given rectangular box 602 * @param box Rectangular box 603 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 604 * @param orig_vals Container storing original non-zero objective coefficients for each objective 605 * @return Container with locally non-dominated results 606 */ 607 ResultContainer computeNondomPointsInBox(const RectangularBox& box, 608 const std::vector<std::vector<SCIP_VAR *>>& orig_vars, 609 const std::vector<std::vector<ValueType>>& orig_vals); 610 611 /** 612 * Indicates whether given outcome is globally dominated 613 * @param outcome Outcome to check for dominance 614 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 615 * @param orig_vals Container storing original non-zero objective coefficients for each objective 616 * @return true if given outcome is dominated; false otherwise 617 */ 618 bool boxResultIsDominated(const OutcomeType& outcome, 619 const std::vector<std::vector<SCIP_VAR*>>& orig_vars, 620 const std::vector<std::vector<ValueType>>& orig_vals); 621 622 623 /** 624 * Create constraint: new_var - beta_i * orig_vals \\cdot orig_vars >= - beta_i * rhs 625 * @param new_var Non-original variable 626 * @param orig_vars Container storing original problem variables with non-zero coefficients for each objective 627 * @param orig_vals Container storing original non-zero objective coefficients for each objective 628 * @param rhs rhs value 629 * @param beta_i coefficient 630 * @return Pointer to corresponding SCIP constraint 631 */ 632 SCIP_CONS* createNewVarTransformCons(SCIP_VAR *new_var, 633 const std::vector<SCIP_VAR *> &orig_vars, 634 const std::vector<ValueType> &orig_vals, 635 const ValueType &rhs, 636 const ValueType &beta_i); 637 638 /** 639 * Create constraint: lhs <= vals \\cdot vars <= rhs 640 * @param vars Considered variables 641 * @param vals Considered coefficient values 642 * @param lhs lhs value 643 * @param rhs rhs value 644 * @return Pointer to corresponding SCIP constraint 645 */ 646 SCIP_CONS* createObjValCons(const std::vector<SCIP_VAR *>& vars, 647 const std::vector<ValueType>& vals, 648 const ValueType& lhs, 649 const ValueType& rhs); 650 651 /** 652 * Computes non-dominated point which fulfills: obj_val_cons1 = obj_val_cons1_rhs and obj_val_cons2 = obj_val_cons2_rhs 653 * @param obj_val_cons1 First constraint to consider 654 * @param obj_val_cons2 Second constraint to consider 655 * @param obj_val_cons1_rhs Corresponding rhs of first constraint 656 * @param obj_val_cons2_rhs Corresponding rhs of second constraint 657 * @param obj_1 Considered objective index corresponding to first constraint 658 * @param obj_2 Considered objective index corresponding to second constraint 659 * @param results Container to store computed non-dominated result 660 * @return SCIP_OKAY if everything worked; otherwise a suitable error code is passed 661 */ 662 SCIP_RETCODE computeNondomProjResult(SCIP_CONS* obj_val_cons1, 663 SCIP_CONS* obj_val_cons2, 664 ValueType obj_val_cons1_rhs, 665 ValueType obj_val_cons2_rhs, 666 std::size_t obj_1, 667 std::size_t obj_2, 668 ResultContainer &results); 669 670 /** 671 * Indicates whether unbounded results were computed 672 * @return true if unbounded results were computed; false otherwise 673 */ unboundedResultsExist()674 bool unboundedResultsExist() const {return !unbounded_.empty();}; 675 676 /** 677 * Print solution 678 * @param sol Solution to print 679 * @param os Output stream to write to 680 */ 681 void printSol(const SolType& sol, 682 std::ostream& os) const; 683 684 /** 685 * Print outcome 686 * @param outcome Outcome to print 687 * @param os Output stream to write to 688 * @param desc Description to print before given outcome 689 */ 690 void outputOutcome(const OutcomeType &outcome, 691 std::ostream& os, 692 const std::string desc ="") const; 693 694 /** 695 * Constructor 696 * @param cmd_line_args Command line parameter object 697 * @param scip SCIP pointer 698 * @param no_objs Number of considered objective 699 * @param clock_total Clock measuring total computation time 700 */ 701 explicit Polyscip(const CmdLineArgs& cmd_line_args, 702 SCIP* scip, 703 std::size_t no_objs, 704 SCIP_CLOCK *clock_total); 705 706 CmdLineArgs cmd_line_args_; ///< Object containing command line parameter information 707 PolyscipStatus polyscip_status_; ///< Current PolySCIP status 708 SCIP* scip_; ///< SCIP pointer 709 SCIP_Objsense obj_sense_; ///< Objective sense of given problem 710 std::size_t no_objs_; ///< Considered number of objectives 711 SCIP_CLOCK* clock_total_; ///< Clock measuring the time needed for the entire computation 712 bool only_weight_space_phase_; ///< Indicates whether only non-dominated extreme points should be computed 713 bool is_sub_prob_; ///< Indicates whether PolySCIP instance belongs to subproblem 714 std::unique_ptr<WeightSpacePolyhedron> weight_space_poly_; ///< Pointer holding weight space polyhedron object 715 ResultContainer bounded_; ///< Container storing bounded non-dominated results 716 ResultContainer unbounded_; ///< Container storing unbounded non-dominated results 717 std::vector<std::size_t> unbd_orig_objs_; ///< Container storing objectives indices for which unbounded rays were found 718 }; 719 720 } 721 722 #endif //POLYSCIP_SRC_POLYSCIP_H_INCLUDED 723