I have a complex model and I want to calculate the objective function value for different options (not just the optimal solution).
I created the toy example below:
import gurobipy as gp
from gurobipy import GRB
import numpy as np
m = gp.Model()
X = {}
for i in range(5):
X[i] = m.addVar(vtype= GRB.INTEGER, name=f"x[{i}]")
obj_func = 0
for i in range(5):
np.random.seed(i)
obj_func += np.random.rand() * X[i]
m.setObjective(obj_func, GRB.MINIMIZE)
m.addConstr(2 * X[1] + 5 * X[3] <= 10, name = 'const1')
m.addConstr(X[0] + 3 * X[4] >= 4, name = 'const2')
m.addConstr(3 * X[1] - X[4] <= 3, name = 'const3')
m.optimize()
for x_index, x in X.items():
if round(x.X)>0:
print(x_index, x.X)
# 0 1.0
# 4 1.0
How can I can calculate the objective function for the manual input of X = [0,1,1,0,0]
or X=[1,0,0,0,1]
. I want the output return the objective function value if this input is a feasible solution, otherwise a warning. I can hard-code the problem, but I would rather to extract the objective coefficients directly form m
(model) and multiply them with the new X
input.
A pretty simple idea: You could fix all the variables in the model by setting the lower and upper bounds to your given inputs and then solve the model. Then, the model.objVal
attribute contains the objective value for your given input solution. A straightforward implementation looks like this:
import numpy as np
given_sols = np.array([[0, 1, 1, 0, 0], [1, 0, 0, 0, 1]])
# Evaluate the objective for multiple given solutions
def get_obj_vals(model, given_sols):
obj_vals = np.nan * np.zeros(given_sols.shape[0])
# for each given solution..
for k, x in enumerate(given_sols):
# reset the model
model.reset()
# Fix the lower/upper bounds
for i, var in enumerate(model.getVars()):
var.lb = x[i]
var.ub = x[i]
# solve the problem
model.optimize()
if model.Status == GRB.Status.OPTIMAL:
obj_vals[k] = model.objVal
return obj_vals
Here, nan
in obj_vals[i]
means that given_sols[i]
is not feasible.