CyLP
CyLP copied to clipboard
Incorrect calculation of certain objective functions
Version 0.9.0b1 (with af1abbb patch) and Python 3.7.1
For certain objective functions, the solver reports an optimal objective value that doesn't equal evaluating the objective function at the optimal solution.
Code to reproduce the bug:
import numpy as np
from cylp.cy import CyClpSimplex
from cylp.py.modeling.CyLPModel import CyLPArray
s = CyClpSimplex()
# Add variables
x = s.addVariable('x', 3)
y = s.addVariable('y', 2)
# Create coefficients and bounds
A = np.matrix([[1., 2., 0],[1., 0, 1.]])
B = np.matrix([[1., 0, 0], [0, 0, 1.]])
D = np.matrix([[1., 2.],[0, 1]])
a = CyLPArray([5, 2.5])
b = CyLPArray([4.2, 3])
x_u= CyLPArray([2., 3.5])
# Add constraints
s += A * x <= a
s += 2 <= B * x + D * y <= b
s += y >= 0
s += 1.1 <= x[1:3] <= x_u
# Set the objective function
c = CyLPArray([1., -2., 3.])
d = CyLPArray([20, 30, 40])
s.objective = -(c - d) * x # OK
s.primal()
print(s.primalVariableSolution['x'])
x_opt = s.primalVariableSolution['x']
print(-((c-d).dot(x_opt)))
print('\n')
s.objective = -(c * x - d * x) # problematic
s.primal()
print(s.primalVariableSolution['x'])
x_opt = s.primalVariableSolution['x']
print(-(c.dot(x_opt) - d.dot(x_opt)))
Output:
Clp0006I 0 Obj 75.9 Primal inf 2.8999998 (2) Dual inf 5.01e+10 (4) w.o. free dual inf (3)
Clp0006I 4 Obj 41.7 Dual inf 19 (1)
Clp0006I 4 Obj 41.7 Dual inf 19 (1)
Clp0002I Dual infeasible - objective value 41.7
[-1.8 1.1 1.1]
41.70000000000001
Clp0006I 0 Obj -41 Dual inf 170 (4)
Clp0006I 3 Obj -170
Clp0000I Optimal - objective value -170
[-0.5 2. 3. ]
165.5
I have not investigated deeply yet, but I suspect the issue lies with how CyLPExprs are built, and I will need to understand how this works to get to the root cause.
The thing is that in CyLP, in both, objective and constraints definitions, you cannot use one variable twice. Thats why the second statement is not interpreted correctly, as you have x twice there..
check how the objective appears after you assign it..