gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfix #430 to branch 1.1
0 2 0
merge 1.1
1 file changed with 12 insertions and 4 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -1511,240 +1511,240 @@
1511 1511

	
1512 1512
    ///\param e is a linear expression of type \ref Expr.
1513 1513
    ///
1514 1514
    void obj(const Expr& e) {
1515 1515
      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
1516 1516
                    ExprIterator(e.comps.end(), cols));
1517 1517
      obj_const_comp = *e;
1518 1518
    }
1519 1519

	
1520 1520
    ///Get the objective function
1521 1521

	
1522 1522
    ///\return the objective function as a linear expression of type
1523 1523
    ///Expr.
1524 1524
    Expr obj() const {
1525 1525
      Expr e;
1526 1526
      _getObjCoeffs(InsertIterator(e.comps, cols));
1527 1527
      *e = obj_const_comp;
1528 1528
      return e;
1529 1529
    }
1530 1530

	
1531 1531

	
1532 1532
    ///Set the direction of optimization
1533 1533
    void sense(Sense sense) { _setSense(sense); }
1534 1534

	
1535 1535
    ///Query the direction of the optimization
1536 1536
    Sense sense() const {return _getSense(); }
1537 1537

	
1538 1538
    ///Set the sense to maximization
1539 1539
    void max() { _setSense(MAX); }
1540 1540

	
1541 1541
    ///Set the sense to maximization
1542 1542
    void min() { _setSense(MIN); }
1543 1543

	
1544 1544
    ///Clears the problem
1545 1545
    void clear() { _clear(); }
1546 1546

	
1547 1547
    /// Sets the message level of the solver
1548 1548
    void messageLevel(MessageLevel level) { _messageLevel(level); }
1549 1549

	
1550 1550
    ///@}
1551 1551

	
1552 1552
  };
1553 1553

	
1554 1554
  /// Addition
1555 1555

	
1556 1556
  ///\relates LpBase::Expr
1557 1557
  ///
1558 1558
  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
1559 1559
    LpBase::Expr tmp(a);
1560 1560
    tmp+=b;
1561 1561
    return tmp;
1562 1562
  }
1563 1563
  ///Substraction
1564 1564

	
1565 1565
  ///\relates LpBase::Expr
1566 1566
  ///
1567 1567
  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
1568 1568
    LpBase::Expr tmp(a);
1569 1569
    tmp-=b;
1570 1570
    return tmp;
1571 1571
  }
1572 1572
  ///Multiply with constant
1573 1573

	
1574 1574
  ///\relates LpBase::Expr
1575 1575
  ///
1576 1576
  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
1577 1577
    LpBase::Expr tmp(a);
1578 1578
    tmp*=b;
1579 1579
    return tmp;
1580 1580
  }
1581 1581

	
1582 1582
  ///Multiply with constant
1583 1583

	
1584 1584
  ///\relates LpBase::Expr
1585 1585
  ///
1586 1586
  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
1587 1587
    LpBase::Expr tmp(b);
1588 1588
    tmp*=a;
1589 1589
    return tmp;
1590 1590
  }
1591 1591
  ///Divide with constant
1592 1592

	
1593 1593
  ///\relates LpBase::Expr
1594 1594
  ///
1595 1595
  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
1596 1596
    LpBase::Expr tmp(a);
1597 1597
    tmp/=b;
1598 1598
    return tmp;
1599 1599
  }
1600 1600

	
1601 1601
  ///Create constraint
1602 1602

	
1603 1603
  ///\relates LpBase::Constr
1604 1604
  ///
1605 1605
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1606 1606
                                   const LpBase::Expr &f) {
1607
    return LpBase::Constr(0, f - e, LpBase::INF);
1607
    return LpBase::Constr(0, f - e, LpBase::NaN);
1608 1608
  }
1609 1609

	
1610 1610
  ///Create constraint
1611 1611

	
1612 1612
  ///\relates LpBase::Constr
1613 1613
  ///
1614 1614
  inline LpBase::Constr operator<=(const LpBase::Value &e,
1615 1615
                                   const LpBase::Expr &f) {
1616 1616
    return LpBase::Constr(e, f, LpBase::NaN);
1617 1617
  }
1618 1618

	
1619 1619
  ///Create constraint
1620 1620

	
1621 1621
  ///\relates LpBase::Constr
1622 1622
  ///
1623 1623
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1624 1624
                                   const LpBase::Value &f) {
1625
    return LpBase::Constr(- LpBase::INF, e, f);
1625
    return LpBase::Constr(LpBase::NaN, e, f);
1626 1626
  }
1627 1627

	
1628 1628
  ///Create constraint
1629 1629

	
1630 1630
  ///\relates LpBase::Constr
1631 1631
  ///
1632 1632
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1633 1633
                                   const LpBase::Expr &f) {
1634
    return LpBase::Constr(0, e - f, LpBase::INF);
1634
    return LpBase::Constr(0, e - f, LpBase::NaN);
1635 1635
  }
1636 1636

	
1637 1637

	
1638 1638
  ///Create constraint
1639 1639

	
1640 1640
  ///\relates LpBase::Constr
1641 1641
  ///
1642 1642
  inline LpBase::Constr operator>=(const LpBase::Value &e,
1643 1643
                                   const LpBase::Expr &f) {
1644 1644
    return LpBase::Constr(LpBase::NaN, f, e);
1645 1645
  }
1646 1646

	
1647 1647

	
1648 1648
  ///Create constraint
1649 1649

	
1650 1650
  ///\relates LpBase::Constr
1651 1651
  ///
1652 1652
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1653 1653
                                   const LpBase::Value &f) {
1654
    return LpBase::Constr(f, e, LpBase::INF);
1654
    return LpBase::Constr(f, e, LpBase::NaN);
1655 1655
  }
1656 1656

	
1657 1657
  ///Create constraint
1658 1658

	
1659 1659
  ///\relates LpBase::Constr
1660 1660
  ///
1661 1661
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1662 1662
                                   const LpBase::Value &f) {
1663 1663
    return LpBase::Constr(f, e, f);
1664 1664
  }
1665 1665

	
1666 1666
  ///Create constraint
1667 1667

	
1668 1668
  ///\relates LpBase::Constr
1669 1669
  ///
1670 1670
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1671 1671
                                   const LpBase::Expr &f) {
1672 1672
    return LpBase::Constr(0, f - e, 0);
1673 1673
  }
1674 1674

	
1675 1675
  ///Create constraint
1676 1676

	
1677 1677
  ///\relates LpBase::Constr
1678 1678
  ///
1679 1679
  inline LpBase::Constr operator<=(const LpBase::Value &n,
1680 1680
                                   const LpBase::Constr &c) {
1681 1681
    LpBase::Constr tmp(c);
1682 1682
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1683 1683
    tmp.lowerBound()=n;
1684 1684
    return tmp;
1685 1685
  }
1686 1686
  ///Create constraint
1687 1687

	
1688 1688
  ///\relates LpBase::Constr
1689 1689
  ///
1690 1690
  inline LpBase::Constr operator<=(const LpBase::Constr &c,
1691 1691
                                   const LpBase::Value &n)
1692 1692
  {
1693 1693
    LpBase::Constr tmp(c);
1694 1694
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1695 1695
    tmp.upperBound()=n;
1696 1696
    return tmp;
1697 1697
  }
1698 1698

	
1699 1699
  ///Create constraint
1700 1700

	
1701 1701
  ///\relates LpBase::Constr
1702 1702
  ///
1703 1703
  inline LpBase::Constr operator>=(const LpBase::Value &n,
1704 1704
                                   const LpBase::Constr &c) {
1705 1705
    LpBase::Constr tmp(c);
1706 1706
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1707 1707
    tmp.upperBound()=n;
1708 1708
    return tmp;
1709 1709
  }
1710 1710
  ///Create constraint
1711 1711

	
1712 1712
  ///\relates LpBase::Constr
1713 1713
  ///
1714 1714
  inline LpBase::Constr operator>=(const LpBase::Constr &c,
1715 1715
                                   const LpBase::Value &n)
1716 1716
  {
1717 1717
    LpBase::Constr tmp(c);
1718 1718
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1719 1719
    tmp.lowerBound()=n;
1720 1720
    return tmp;
1721 1721
  }
1722 1722

	
1723 1723
  ///Addition
1724 1724

	
1725 1725
  ///\relates LpBase::DualExpr
1726 1726
  ///
1727 1727
  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
1728 1728
                                    const LpBase::DualExpr &b) {
1729 1729
    LpBase::DualExpr tmp(a);
1730 1730
    tmp+=b;
1731 1731
    return tmp;
1732 1732
  }
1733 1733
  ///Substraction
1734 1734

	
1735 1735
  ///\relates LpBase::DualExpr
1736 1736
  ///
1737 1737
  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
1738 1738
                                    const LpBase::DualExpr &b) {
1739 1739
    LpBase::DualExpr tmp(a);
1740 1740
    tmp-=b;
1741 1741
    return tmp;
1742 1742
  }
1743 1743
  ///Multiply with constant
1744 1744

	
1745 1745
  ///\relates LpBase::DualExpr
1746 1746
  ///
1747 1747
  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
1748 1748
                                    const LpBase::Value &b) {
1749 1749
    LpBase::DualExpr tmp(a);
1750 1750
    tmp*=b;
Ignore white space 192 line context
... ...
@@ -73,192 +73,200 @@
73 73
  lp.colUpperBound(z,1);
74 74
  lp.colBounds(z,1,2);
75 75

	
76 76
  {
77 77
    LP::Expr e,f,g;
78 78
    LP::Col p1,p2,p3,p4,p5;
79 79
    LP::Constr c;
80 80

	
81 81
    p1=lp.addCol();
82 82
    p2=lp.addCol();
83 83
    p3=lp.addCol();
84 84
    p4=lp.addCol();
85 85
    p5=lp.addCol();
86 86

	
87 87
    e[p1]=2;
88 88
    *e=12;
89 89
    e[p1]+=2;
90 90
    *e+=12;
91 91
    e[p1]-=2;
92 92
    *e-=12;
93 93

	
94 94
    e=2;
95 95
    e=2.2;
96 96
    e=p1;
97 97
    e=f;
98 98

	
99 99
    e+=2;
100 100
    e+=2.2;
101 101
    e+=p1;
102 102
    e+=f;
103 103

	
104 104
    e-=2;
105 105
    e-=2.2;
106 106
    e-=p1;
107 107
    e-=f;
108 108

	
109 109
    e*=2;
110 110
    e*=2.2;
111 111
    e/=2;
112 112
    e/=2.2;
113 113

	
114 114
    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
115 115
       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
116 116
       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
117 117
       2.2*f+f*2.2+f/2.2+
118 118
       2*f+f*2+f/2+
119 119
       2.2*p1+p1*2.2+p1/2.2+
120 120
       2*p1+p1*2+p1/2
121 121
       );
122 122

	
123 123

	
124 124
    c = (e  <= f  );
125 125
    c = (e  <= 2.2);
126 126
    c = (e  <= 2  );
127 127
    c = (e  <= p1 );
128 128
    c = (2.2<= f  );
129 129
    c = (2  <= f  );
130 130
    c = (p1 <= f  );
131 131
    c = (p1 <= p2 );
132 132
    c = (p1 <= 2.2);
133 133
    c = (p1 <= 2  );
134 134
    c = (2.2<= p2 );
135 135
    c = (2  <= p2 );
136 136

	
137 137
    c = (e  >= f  );
138 138
    c = (e  >= 2.2);
139 139
    c = (e  >= 2  );
140 140
    c = (e  >= p1 );
141 141
    c = (2.2>= f  );
142 142
    c = (2  >= f  );
143 143
    c = (p1 >= f  );
144 144
    c = (p1 >= p2 );
145 145
    c = (p1 >= 2.2);
146 146
    c = (p1 >= 2  );
147 147
    c = (2.2>= p2 );
148 148
    c = (2  >= p2 );
149 149

	
150 150
    c = (e  == f  );
151 151
    c = (e  == 2.2);
152 152
    c = (e  == 2  );
153 153
    c = (e  == p1 );
154 154
    c = (2.2== f  );
155 155
    c = (2  == f  );
156 156
    c = (p1 == f  );
157 157
    //c = (p1 == p2 );
158 158
    c = (p1 == 2.2);
159 159
    c = (p1 == 2  );
160 160
    c = (2.2== p2 );
161 161
    c = (2  == p2 );
162 162

	
163 163
    c = ((2 <= e) <= 3);
164 164
    c = ((2 <= p1) <= 3);
165 165

	
166 166
    c = ((2 >= e) >= 3);
167 167
    c = ((2 >= p1) >= 3);
168 168

	
169
    { //Tests for #430
170
      LP::Col v=lp.addCol();
171
      LP::Constr c = v >= -3;
172
      c = c <= 4;
173
      LP::Constr c2;
174
      c2 = -3 <= v <= 4;
175
    }
176

	
169 177
    e[x[3]]=2;
170 178
    e[x[3]]=4;
171 179
    e[x[3]]=1;
172 180
    *e=12;
173 181

	
174 182
    lp.addRow(-LP::INF,e,23);
175 183
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
176 184
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
177 185

	
178 186
    lp.addRow(x[1]+x[3]<=x[5]-3);
179 187
    lp.addRow((-7<=x[1]+x[3]-12)<=3);
180 188
    lp.addRow(x[1]<=x[5]);
181 189

	
182 190
    std::ostringstream buf;
183 191

	
184 192

	
185 193
    e=((p1+p2)+(p1-0.99*p2));
186 194
    //e.prettyPrint(std::cout);
187 195
    //(e<=2).prettyPrint(std::cout);
188 196
    double tolerance=0.001;
189 197
    e.simplify(tolerance);
190 198
    buf << "Coeff. of p2 should be 0.01";
191 199
    check(e[p2]>0, buf.str());
192 200

	
193 201
    tolerance=0.02;
194 202
    e.simplify(tolerance);
195 203
    buf << "Coeff. of p2 should be 0";
196 204
    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
197 205

	
198 206
    //Test for clone/new
199 207
    LP* lpnew = lp.newSolver();
200 208
    LP* lpclone = lp.cloneSolver();
201 209
    delete lpnew;
202 210
    delete lpclone;
203 211

	
204 212
  }
205 213

	
206 214
  {
207 215
    LP::DualExpr e,f,g;
208 216
    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
209 217
      p4 = INVALID, p5 = INVALID;
210 218

	
211 219
    e[p1]=2;
212 220
    e[p1]+=2;
213 221
    e[p1]-=2;
214 222

	
215 223
    e=p1;
216 224
    e=f;
217 225

	
218 226
    e+=p1;
219 227
    e+=f;
220 228

	
221 229
    e-=p1;
222 230
    e-=f;
223 231

	
224 232
    e*=2;
225 233
    e*=2.2;
226 234
    e/=2;
227 235
    e/=2.2;
228 236

	
229 237
    e=((p1+p2)+(p1-p2)+
230 238
       (p1+f)+(f+p1)+(f+g)+
231 239
       (p1-f)+(f-p1)+(f-g)+
232 240
       2.2*f+f*2.2+f/2.2+
233 241
       2*f+f*2+f/2+
234 242
       2.2*p1+p1*2.2+p1/2.2+
235 243
       2*p1+p1*2+p1/2
236 244
       );
237 245
  }
238 246

	
239 247
}
240 248

	
241 249
void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
242 250
                   double exp_opt) {
243 251
  using std::string;
244 252
  lp.solve();
245 253

	
246 254
  std::ostringstream buf;
247 255
  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
248 256

	
249 257
  check(lp.primalType()==stat, buf.str());
250 258

	
251 259
  if (stat ==  LpSolver::OPTIMAL) {
252 260
    std::ostringstream sbuf;
253 261
    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
254 262
         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
255 263
    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
256 264
  }
257 265
}
258 266

	
259 267
void aTest(LpSolver & lp)
260 268
{
261 269
  typedef LpSolver LP;
262 270

	
263 271
 //The following example is very simple
264 272

	
0 comments (0 inline)