I have this simple product mix linear program, Pulp and Gekko results differs a lot but results are both valid.
I wonder why and how should I get exactly the same result using both solvers ?
There is a simple product mix example :
Let's say x1 is the amount of car toy 1, and x2 the amount of car toy 2 ( -> Decision variables).
Car toy 1 price is 2$, Car toy 2 price is 1 $ ( -> Objective function).
Constraint 1 is a worktime limit expressed in hours, Constraint 2 is a parts inventory limit expressed in units.
I want to know which cars to build to maximize my profit subject to both constraints.
# Import
from gekko import GEKKO
# Local server used
m = GEKKO(remote=False)
# Picking solver 1
m.options.SOLVER = 1
# Initialize variables
x1 = m.Var(value=1,lb=0,ub=1000,integer=True)
x2 = m.Var(value=1,lb=0,ub=1000,integer=True)
# Constraints
m.Equation(2 * x1 + 3 * x2 <= 800)
m.Equation(2 * x1 + x2 <= 500)
# Objective
m.Maximize( 2 * x1 + 1 * x2)
# Steady state optimization
m.options.IMODE = 3
# Solve
m.solve(disp=False)
# Display results
print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('Objective: ' + str(m.options.objfcnval))
Results
x1: [184.0]
x2: [132.0]
Objective: -500.0
And, next, this is my Python Pulp code. You will notice that Python Pulp only picks the x1 variable, while Gekko seems to balance between the x1 and the x2 variables, or seems to optimize the decision variables allocation( Don't know if it's true or not); both results are valid, and constraints are not exceeded:
# Import
import pulp
# This is a maximization L.P
model = pulp.LpProblem("Maximize", pulp.LpMaximize)
# Initialize variables
x1 = pulp.LpVariable('x1', lowBound=0, cat='Integer')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Integer')
# Objective
model += 2 * x1 + 1 * x2, "Profit"
# Constraints
model += 2 * x1 + 3 * x2 <= 800
model += 2 * x1 + x2 <= 500
# Solve
model.solve()
# Status
pulp.LpStatus[model.status]
# Display results
# Print our decision variable values
print ("x1 = {}".format(x1.varValue))
print ("x2 = {}".format(x2.varValue))
# Print our objective function value
print (pulp.value(model.objective))
Results
x1 = 250.0
x2 = 0.0
500.0
Gekko tells me to build 184 "car toy 1" and 132 "car toy 2" to maximize my profit , but Pulp tells me to only build 250 "car toy 1" , and to ignore "car toy 2" to maximize my profit.
In the second case, the factory could abandon the plan to build toy car 2 altogether and dismantle parts of the factory to save money ( So it's good), so the result has a lot of consequences.
Can somebody please tell me if that is a normal behavior, and how should I get the same behavior on both solvers ?
Is is due to a different simplex or interior point algorithm used by theses libraries?
( Secondary question : I don't know why the Gekko objective result is negative ... )
