|
7 | 7 | import re |
8 | 8 | import tempfile |
9 | 9 | import unittest |
| 10 | +from decimal import Decimal |
10 | 11 |
|
11 | 12 | from pulp import ( |
12 | 13 | LpAffineExpression, |
@@ -1803,6 +1804,31 @@ def test_regression_805(self): |
1803 | 1804 | self.assertEqual(c.name, "Test2") |
1804 | 1805 | self.assertEqual(c.expr.name, "Test1") |
1805 | 1806 |
|
| 1807 | + def test_decimal_815_addinplace(self): |
| 1808 | + # See: https://github.com/coin-or/pulp/issues/815 |
| 1809 | + m1 = 3 |
| 1810 | + m2 = Decimal("8.1") |
| 1811 | + extra = 5 |
| 1812 | + |
| 1813 | + x = LpVariable("x", lowBound=0, upBound=50, cat=LpContinuous) |
| 1814 | + y = LpVariable("y", lowBound=0, upBound=Decimal("32.24"), cat=LpContinuous) |
| 1815 | + include_extra = LpVariable("include_extra1", cat=LpBinary) |
| 1816 | + |
| 1817 | + expression = LpAffineExpression() |
| 1818 | + expression += x * m1 + include_extra * extra - y |
| 1819 | + self.assertEqual(str(expression), "5*include_extra1 + 3*x - y") |
| 1820 | + |
| 1821 | + with self.assertRaises(TypeError): |
| 1822 | + second_expression = LpAffineExpression() |
| 1823 | + second_expression += x * m2 - 6 - y |
| 1824 | + |
| 1825 | + second_expression = LpAffineExpression(constant=Decimal("0")) |
| 1826 | + second_expression += x * m2 - 6 - y |
| 1827 | + self.assertEqual(str(second_expression), "8.1*x - y - 6.0") |
| 1828 | + |
| 1829 | + second_expression_2 = x * m2 - 6 - y |
| 1830 | + self.assertEqual(str(second_expression_2), "8.1*x - y - 6.0") |
| 1831 | + |
1806 | 1832 |
|
1807 | 1833 | class PULP_CBC_CMDTest(BaseSolverTest.PuLPTest): |
1808 | 1834 | solveInst = PULP_CBC_CMD |
@@ -2081,6 +2107,47 @@ def test_issue814_rounding_ipt(self): |
2081 | 2107 | self.solver.options = self.solver.options[:-1] |
2082 | 2108 | assert abs(Q.value() - ub) / ub < 1e-9 |
2083 | 2109 |
|
| 2110 | + def test_decimal_815(self): |
| 2111 | + # See: https://github.com/coin-or/pulp/issues/815 |
| 2112 | + # Will not run on other solvers due to how results are updated |
| 2113 | + m1 = 3 |
| 2114 | + m2 = Decimal("8.1") |
| 2115 | + extra = 5 |
| 2116 | + |
| 2117 | + x = LpVariable("x", lowBound=0, upBound=50, cat=LpContinuous) |
| 2118 | + y = LpVariable("y", lowBound=0, upBound=Decimal("32.24"), cat=LpContinuous) |
| 2119 | + include_extra = LpVariable("include_extra1", cat=LpBinary) |
| 2120 | + |
| 2121 | + prob = LpProblem("graph", LpMaximize) |
| 2122 | + |
| 2123 | + prob += y |
| 2124 | + |
| 2125 | + # y = 3x + 5 | y = 3x |
| 2126 | + e1 = x * m1 + include_extra * extra - y |
| 2127 | + c1 = e1 == 0 |
| 2128 | + prob += c1 |
| 2129 | + |
| 2130 | + # y = 8.1x - 6 |
| 2131 | + e2 = x * m2 - 6 - y |
| 2132 | + c2 = e2 == 0 |
| 2133 | + prob += c2 |
| 2134 | + |
| 2135 | + # This generates two possible systems of equations, |
| 2136 | + # y = 3x + 5 |
| 2137 | + # y = 8.1x - 6 |
| 2138 | + # this intersects at ~(11/5, 58/5) |
| 2139 | + |
| 2140 | + # OR |
| 2141 | + # y = 3x |
| 2142 | + # y = 8.1x-6 |
| 2143 | + # this intersects at ~(6/5, 18/5) |
| 2144 | + pulpTestCheck( |
| 2145 | + prob, |
| 2146 | + self.solver, |
| 2147 | + [const.LpStatusOptimal], |
| 2148 | + {x: 2.15686, y: 11.4706}, |
| 2149 | + ) |
| 2150 | + |
2084 | 2151 |
|
2085 | 2152 | class GUROBITest(BaseSolverTest.PuLPTest): |
2086 | 2153 | solveInst = GUROBI |
|
0 commit comments