Bring your own constraints!
The following example shows how your own constraints can be enforced on the input variables.
[ ]:
from entmoot import Enting, ProblemConfig, GurobiOptimizer, PyomoOptimizer
from entmoot.benchmarks import (
build_multi_obj_categorical_problem,
eval_multi_obj_cat_testfunc,
)
This part is pretty standard.
[ ]:
# define problem
problem_config = ProblemConfig(rnd_seed=73)
# number of objectives
number_objectives = 2
build_multi_obj_categorical_problem(problem_config, n_obj=number_objectives)
# sample data
rnd_sample = problem_config.get_rnd_sample_list(num_samples=20)
testfunc_evals = eval_multi_obj_cat_testfunc(rnd_sample, n_obj=number_objectives)
params = {"unc_params": {"dist_metric": "l1", "acq_sense": "exploration"}}
enting = Enting(problem_config, params=params)
# fit tree ensemble
enting.fit(rnd_sample, testfunc_evals)
How to add constraints depends on wether you are using Gurobi or Pyomo
Gurobi Version
[ ]:
# get optimization model
model_gur = problem_config.get_gurobi_model_core()
# extract decision variables
x = model_gur._all_feat[3]
y = model_gur._all_feat[4]
z = model_gur._all_feat[5]
# add constraint that all variables should coincide
model_gur.addConstr(x == y)
model_gur.addConstr(y == z)
It is important to update the Gurobi model. Otherwise the constraints will not be added to the model!
[ ]:
model_gur.update()
Now you can run the optimization and verify that the variable values indeed equal each other.
[ ]:
# Build GurobiOptimizer object and solve optimization problem
params_gurobi = {"MIPGap": 0}
opt_gur = GurobiOptimizer(problem_config, params=params_gurobi)
[ ]:
res_gur = opt_gur.solve(enting, model_core=model_gur)
[ ]:
# Build GurobiOptimizer object and solve optimization problem
params_gurobi = {"MIPGap": 0}
opt_gur = GurobiOptimizer(problem_config, params=params_gurobi)
res_gur = opt_gur.solve(enting, model_core=model_gur)
x_opt, y_opt, z_opt = res_gur.opt_point[3:]
assert round(x_opt, 5) == round(y_opt, 5) and round(y_opt, 5) == round(z_opt, 5)
Pyomo Version
[ ]:
# Pyomo version
import pyomo.environ as pyo
model_pyo = problem_config.get_pyomo_model_core()
# extract decision variables
x = model_pyo._all_feat[3]
y = model_pyo._all_feat[4]
z = model_pyo._all_feat[5]
# add constraint that all variables should coincide
model_pyo.xy_equal_constr = pyo.Constraint(expr=x == y)
model_pyo.yz_equal_constr = pyo.Constraint(expr=y == z)
# Build GurobiOptimizer object and solve optimization problem
params_pyomo = {"solver_name": "gurobi"}
opt_pyo = PyomoOptimizer(problem_config, params=params_pyomo)
res_pyo = opt_pyo.solve(enting, model_core=model_pyo)
x_opt, y_opt, z_opt = res_pyo.opt_point[3:]
assert round(x_opt, 5) == round(y_opt, 5) and round(y_opt, 5) == round(z_opt, 5)
Note that no model update is required in the Pyomo version in contrast to the Gurobi variant