gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 4 0
merge default
4 files changed with 18 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -429,192 +429,198 @@
429 429
        break;
430 430
      default:
431 431
        break;
432 432
      }
433 433
    } else {
434 434
      switch (b) {
435 435
      case GLP_FR:
436 436
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
437 437
        break;
438 438
      case GLP_UP:
439 439
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
440 440
        break;
441 441
      case GLP_LO:
442 442
      case GLP_DB:
443 443
      case GLP_FX:
444 444
        if (lo == up)
445 445
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
446 446
        else
447 447
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
448 448
        break;
449 449
      default:
450 450
        break;
451 451
      }
452 452
    }
453 453
  }
454 454

	
455 455
  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
456 456
    int b = glp_get_row_type(lp, i);
457 457
    switch (b) {
458 458
    case GLP_UP:
459 459
    case GLP_DB:
460 460
    case GLP_FX:
461 461
      return glp_get_row_ub(lp, i);
462 462
    default:
463 463
      return INF;
464 464
    }
465 465
  }
466 466

	
467 467
  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
468 468
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
469 469
      glp_set_obj_coef(lp, i, 0.0);
470 470
    }
471 471
    for (ExprIterator it = b; it != e; ++it) {
472 472
      glp_set_obj_coef(lp, it->first, it->second);
473 473
    }
474 474
  }
475 475

	
476 476
  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
477 477
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
478 478
      Value val = glp_get_obj_coef(lp, i);
479 479
      if (val != 0.0) {
480 480
        *b = std::make_pair(i, val);
481 481
        ++b;
482 482
      }
483 483
    }
484 484
  }
485 485

	
486 486
  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
487 487
    //i = 0 means the constant term (shift)
488 488
    glp_set_obj_coef(lp, i, obj_coef);
489 489
  }
490 490

	
491 491
  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
492 492
    //i = 0 means the constant term (shift)
493 493
    return glp_get_obj_coef(lp, i);
494 494
  }
495 495

	
496 496
  void GlpkBase::_setSense(GlpkBase::Sense sense) {
497 497
    switch (sense) {
498 498
    case MIN:
499 499
      glp_set_obj_dir(lp, GLP_MIN);
500 500
      break;
501 501
    case MAX:
502 502
      glp_set_obj_dir(lp, GLP_MAX);
503 503
      break;
504 504
    }
505 505
  }
506 506

	
507 507
  GlpkBase::Sense GlpkBase::_getSense() const {
508 508
    switch(glp_get_obj_dir(lp)) {
509 509
    case GLP_MIN:
510 510
      return MIN;
511 511
    case GLP_MAX:
512 512
      return MAX;
513 513
    default:
514 514
      LEMON_ASSERT(false, "Wrong sense");
515 515
      return GlpkBase::Sense();
516 516
    }
517 517
  }
518 518

	
519 519
  void GlpkBase::_clear() {
520 520
    glp_erase_prob(lp);
521 521
    rows.clear();
522 522
    cols.clear();
523 523
  }
524 524

	
525
  void GlpkBase::freeEnv() {
526
    glp_free_env();
527
  }
528

	
529
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
530

	
525 531
  // GlpkLp members
526 532

	
527 533
  GlpkLp::GlpkLp()
528 534
    : LpBase(), GlpkBase(), LpSolver() {
529 535
    messageLevel(MESSAGE_NO_OUTPUT);
530 536
  }
531 537

	
532 538
  GlpkLp::GlpkLp(const GlpkLp& other)
533 539
    : LpBase(other), GlpkBase(other), LpSolver(other) {
534 540
    messageLevel(MESSAGE_NO_OUTPUT);
535 541
  }
536 542

	
537 543
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
538 544
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
539 545

	
540 546
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
541 547

	
542 548
  void GlpkLp::_clear_temporals() {
543 549
    _primal_ray.clear();
544 550
    _dual_ray.clear();
545 551
  }
546 552

	
547 553
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
548 554
    return solvePrimal();
549 555
  }
550 556

	
551 557
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
552 558
    _clear_temporals();
553 559

	
554 560
    glp_smcp smcp;
555 561
    glp_init_smcp(&smcp);
556 562

	
557 563
    switch (_message_level) {
558 564
    case MESSAGE_NO_OUTPUT:
559 565
      smcp.msg_lev = GLP_MSG_OFF;
560 566
      break;
561 567
    case MESSAGE_ERROR_MESSAGE:
562 568
      smcp.msg_lev = GLP_MSG_ERR;
563 569
      break;
564 570
    case MESSAGE_NORMAL_OUTPUT:
565 571
      smcp.msg_lev = GLP_MSG_ON;
566 572
      break;
567 573
    case MESSAGE_FULL_OUTPUT:
568 574
      smcp.msg_lev = GLP_MSG_ALL;
569 575
      break;
570 576
    }
571 577

	
572 578
    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
573 579
    return SOLVED;
574 580
  }
575 581

	
576 582
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
577 583
    _clear_temporals();
578 584

	
579 585
    glp_smcp smcp;
580 586
    glp_init_smcp(&smcp);
581 587

	
582 588
    switch (_message_level) {
583 589
    case MESSAGE_NO_OUTPUT:
584 590
      smcp.msg_lev = GLP_MSG_OFF;
585 591
      break;
586 592
    case MESSAGE_ERROR_MESSAGE:
587 593
      smcp.msg_lev = GLP_MSG_ERR;
588 594
      break;
589 595
    case MESSAGE_NORMAL_OUTPUT:
590 596
      smcp.msg_lev = GLP_MSG_ON;
591 597
      break;
592 598
    case MESSAGE_FULL_OUTPUT:
593 599
      smcp.msg_lev = GLP_MSG_ALL;
594 600
      break;
595 601
    }
596 602
    smcp.meth = GLP_DUAL;
597 603

	
598 604
    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
599 605
    return SOLVED;
600 606
  }
601 607

	
602 608
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
603 609
    return glp_get_col_prim(lp, i);
604 610
  }
605 611

	
606 612
  GlpkLp::Value GlpkLp::_getDual(int i) const {
607 613
    return glp_get_row_dual(lp, i);
608 614
  }
609 615

	
610 616
  GlpkLp::Value GlpkLp::_getPrimalValue() const {
611 617
    return glp_get_obj_val(lp);
612 618
  }
613 619

	
614 620
  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
615 621
    switch (glp_get_col_stat(lp, i)) {
616 622
    case GLP_BS:
617 623
      return BASIC;
618 624
    case GLP_UP:
619 625
      return UPPER;
620 626
    case GLP_LO:
Ignore white space 192 line context
... ...
@@ -7,192 +7,204 @@
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_GLPK_H
20 20
#define LEMON_GLPK_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-GLPK lp solver interface.
24 24
///\ingroup lp_group
25 25

	
26 26
#include <lemon/lp_base.h>
27 27

	
28 28
// forward declaration
29 29
#ifndef _GLP_PROB
30 30
#define _GLP_PROB
31 31
typedef struct { double _prob; } glp_prob;
32 32
/* LP/MIP problem object */
33 33
#endif
34 34

	
35 35
namespace lemon {
36 36

	
37 37

	
38 38
  /// \brief Base interface for the GLPK LP and MIP solver
39 39
  ///
40 40
  /// This class implements the common interface of the GLPK LP and MIP solver.
41 41
  /// \ingroup lp_group
42 42
  class GlpkBase : virtual public LpBase {
43 43
  protected:
44 44

	
45 45
    typedef glp_prob LPX;
46 46
    glp_prob* lp;
47 47

	
48 48
    GlpkBase();
49 49
    GlpkBase(const GlpkBase&);
50 50
    virtual ~GlpkBase();
51 51

	
52 52
  protected:
53 53

	
54 54
    virtual int _addCol();
55 55
    virtual int _addRow();
56 56

	
57 57
    virtual void _eraseCol(int i);
58 58
    virtual void _eraseRow(int i);
59 59

	
60 60
    virtual void _eraseColId(int i);
61 61
    virtual void _eraseRowId(int i);
62 62

	
63 63
    virtual void _getColName(int col, std::string& name) const;
64 64
    virtual void _setColName(int col, const std::string& name);
65 65
    virtual int _colByName(const std::string& name) const;
66 66

	
67 67
    virtual void _getRowName(int row, std::string& name) const;
68 68
    virtual void _setRowName(int row, const std::string& name);
69 69
    virtual int _rowByName(const std::string& name) const;
70 70

	
71 71
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
72 72
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
73 73

	
74 74
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
75 75
    virtual void _getColCoeffs(int i, InsertIterator b) const;
76 76

	
77 77
    virtual void _setCoeff(int row, int col, Value value);
78 78
    virtual Value _getCoeff(int row, int col) const;
79 79

	
80 80
    virtual void _setColLowerBound(int i, Value value);
81 81
    virtual Value _getColLowerBound(int i) const;
82 82

	
83 83
    virtual void _setColUpperBound(int i, Value value);
84 84
    virtual Value _getColUpperBound(int i) const;
85 85

	
86 86
    virtual void _setRowLowerBound(int i, Value value);
87 87
    virtual Value _getRowLowerBound(int i) const;
88 88

	
89 89
    virtual void _setRowUpperBound(int i, Value value);
90 90
    virtual Value _getRowUpperBound(int i) const;
91 91

	
92 92
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
93 93
    virtual void _getObjCoeffs(InsertIterator b) const;
94 94

	
95 95
    virtual void _setObjCoeff(int i, Value obj_coef);
96 96
    virtual Value _getObjCoeff(int i) const;
97 97

	
98 98
    virtual void _setSense(Sense);
99 99
    virtual Sense _getSense() const;
100 100

	
101 101
    virtual void _clear();
102 102

	
103
  private:
104

	
105
    static void freeEnv();
106

	
107
    struct FreeEnvHelper {
108
      ~FreeEnvHelper() {
109
        freeEnv();
110
      }
111
    };
112
    
113
    static FreeEnvHelper freeEnvHelper;
114
    
103 115
  public:
104 116

	
105 117
    ///Pointer to the underlying GLPK data structure.
106 118
    LPX *lpx() {return lp;}
107 119
    ///Const pointer to the underlying GLPK data structure.
108 120
    const LPX *lpx() const {return lp;}
109 121

	
110 122
    ///Returns the constraint identifier understood by GLPK.
111 123
    int lpxRow(Row r) const { return rows(id(r)); }
112 124

	
113 125
    ///Returns the variable identifier understood by GLPK.
114 126
    int lpxCol(Col c) const { return cols(id(c)); }
115 127

	
116 128
  };
117 129

	
118 130
  /// \brief Interface for the GLPK LP solver
119 131
  ///
120 132
  /// This class implements an interface for the GLPK LP solver.
121 133
  ///\ingroup lp_group
122 134
  class GlpkLp : public LpSolver, public GlpkBase {
123 135
  public:
124 136

	
125 137
    ///\e
126 138
    GlpkLp();
127 139
    ///\e
128 140
    GlpkLp(const GlpkLp&);
129 141

	
130 142
    ///\e
131 143
    virtual GlpkLp* cloneSolver() const;
132 144
    ///\e
133 145
    virtual GlpkLp* newSolver() const;
134 146

	
135 147
  private:
136 148

	
137 149
    mutable std::vector<double> _primal_ray;
138 150
    mutable std::vector<double> _dual_ray;
139 151

	
140 152
    void _clear_temporals();
141 153

	
142 154
  protected:
143 155

	
144 156
    virtual const char* _solverName() const;
145 157

	
146 158
    virtual SolveExitStatus _solve();
147 159
    virtual Value _getPrimal(int i) const;
148 160
    virtual Value _getDual(int i) const;
149 161

	
150 162
    virtual Value _getPrimalValue() const;
151 163

	
152 164
    virtual VarStatus _getColStatus(int i) const;
153 165
    virtual VarStatus _getRowStatus(int i) const;
154 166

	
155 167
    virtual Value _getPrimalRay(int i) const;
156 168
    virtual Value _getDualRay(int i) const;
157 169

	
158 170
    virtual ProblemType _getPrimalType() const;
159 171
    virtual ProblemType _getDualType() const;
160 172

	
161 173
  public:
162 174

	
163 175
    ///Solve with primal simplex
164 176
    SolveExitStatus solvePrimal();
165 177

	
166 178
    ///Solve with dual simplex
167 179
    SolveExitStatus solveDual();
168 180

	
169 181
    ///Turns on or off the presolver
170 182

	
171 183
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
172 184
    ///
173 185
    ///The presolver is off by default.
174 186
    void presolver(bool b);
175 187

	
176 188
    ///Enum for \c messageLevel() parameter
177 189
    enum MessageLevel {
178 190
      /// no output (default value)
179 191
      MESSAGE_NO_OUTPUT = 0,
180 192
      /// error messages only
181 193
      MESSAGE_ERROR_MESSAGE = 1,
182 194
      /// normal output
183 195
      MESSAGE_NORMAL_OUTPUT = 2,
184 196
      /// full output (includes informational messages)
185 197
      MESSAGE_FULL_OUTPUT = 3
186 198
    };
187 199

	
188 200
  private:
189 201

	
190 202
    MessageLevel _message_level;
191 203

	
192 204
  public:
193 205

	
194 206
    ///Set the verbosity of the messages
195 207

	
196 208
    ///Set the verbosity of the messages
197 209
    ///
198 210
    ///\param m is the level of the messages output by the solver routines.
0 comments (0 inline)