Skip to content

Commit

Permalink
Update tests (#48)
Browse files Browse the repository at this point in the history
* Update pyomo construction to work with GurobiCloud

* Refactor current pipeline tests

* Implement tests for objectives

* Move optimizer model tests to new file
  • Loading branch information
TobyBoyne authored Jul 4, 2024
1 parent 61e2928 commit 4057ae3
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 408 deletions.
172 changes: 10 additions & 162 deletions docs/notebooks/multi_obj_with_constraints.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"id": "4c8da843-670c-4f07-bd66-471ec19d3601",
"metadata": {
"tags": []
Expand All @@ -38,7 +38,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "311c88fa-f757-44f3-8ae5-555f715fc1b4",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -77,31 +77,10 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": null,
"id": "c0dc70de-f14f-42a4-9202-0e4777d33bec",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Set parameter WLSAccessID\n",
"Set parameter WLSSecret\n",
"Set parameter LicenseID to value 2512524\n",
"Academic license 2512524 - for non-commercial use only - registered to [email protected]\n"
]
},
{
"data": {
"text/plain": [
"<gurobi.Constr *Awaiting Model Update*>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"# get optimization model\n",
"model_gur = problem_config.get_gurobi_model_core()\n",
Expand All @@ -124,7 +103,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": null,
"id": "61a8e860-92ee-4535-ad73-9b2acf132ad8",
"metadata": {},
"outputs": [],
Expand All @@ -142,7 +121,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"id": "15bc6c5d-011f-4c57-8af0-4da9704af41e",
"metadata": {},
"outputs": [],
Expand All @@ -154,120 +133,20 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"id": "e987e159-d855-4476-b7f8-3a041ab45d5f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Set parameter MIPGap to value 0\n",
"Set parameter NonConvex to value 2\n",
"Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (win64)\n",
"\n",
"CPU model: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz, instruction set [SSE2|AVX|AVX2|AVX512]\n",
"Thread count: 4 physical cores, 8 logical processors, using up to 8 threads\n",
"\n",
"Academic license 2512524 - for non-commercial use only - registered to [email protected]\n",
"Optimize a model with 3172 rows, 1828 columns and 11438 nonzeros\n",
"Model fingerprint: 0xa6d043a3\n",
"Model has 100 SOS constraints\n",
"Variable types: 1803 continuous, 25 integer (24 binary)\n",
"Coefficient statistics:\n",
" Matrix range [5e-08, 2e+04]\n",
" Objective range [1e+00, 2e+00]\n",
" Bounds range [1e+00, 6e+00]\n",
" RHS range [2e-04, 8e+03]\n",
"Presolve removed 367 rows and 248 columns\n",
"Presolve time: 0.12s\n",
"Presolved: 2805 rows, 1580 columns, 9988 nonzeros\n",
"Presolved model has 94 SOS constraint(s)\n",
"Variable types: 1557 continuous, 23 integer (23 binary)\n",
"\n",
"Root relaxation: unbounded, 647 iterations, 0.04 seconds (0.02 work units)\n",
"\n",
" Nodes | Current Node | Objective Bounds | Work\n",
" Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n",
"\n",
" 0 0 postponed 0 - - - - 0s\n",
" 0 0 postponed 0 - - - - 0s\n",
" 0 2 postponed 0 - - - - 0s\n",
"H 32 25 -0.2625355 - - 421 1s\n",
"H 34 25 -0.3766411 - - 397 1s\n",
"\n",
"Explored 145 nodes (22173 simplex iterations) in 1.69 seconds (1.08 work units)\n",
"Thread count was 8 (of 8 available processors)\n",
"\n",
"Solution count 2: -0.376641 -0.262536 \n",
"\n",
"Optimal solution found (tolerance 0.00e+00)\n",
"Best objective -3.766411305508e-01, best bound -3.766411305508e-01, gap 0.0000%\n"
]
}
],
"outputs": [],
"source": [
"res_gur = opt_gur.solve(enting, model_core=model_gur)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": null,
"id": "4ae2f026-dded-4376-866b-6ca34adc5bf9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Set parameter MIPGap to value 0\n",
"Set parameter NonConvex to value 2\n",
"Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (win64)\n",
"\n",
"CPU model: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz, instruction set [SSE2|AVX|AVX2|AVX512]\n",
"Thread count: 4 physical cores, 8 logical processors, using up to 8 threads\n",
"\n",
"Academic license 2512524 - for non-commercial use only - registered to [email protected]\n",
"Optimize a model with 3172 rows, 1828 columns and 11438 nonzeros\n",
"Model fingerprint: 0x7f777cf7\n",
"Model has 100 SOS constraints\n",
"Variable types: 1803 continuous, 25 integer (24 binary)\n",
"Coefficient statistics:\n",
" Matrix range [5e-08, 2e+04]\n",
" Objective range [1e+00, 2e+00]\n",
" Bounds range [1e+00, 6e+00]\n",
" RHS range [2e-04, 8e+03]\n",
"Presolve removed 367 rows and 248 columns\n",
"Presolve time: 0.07s\n",
"Presolved: 2805 rows, 1580 columns, 9984 nonzeros\n",
"Presolved model has 94 SOS constraint(s)\n",
"Variable types: 1557 continuous, 23 integer (23 binary)\n",
"\n",
"Root relaxation: unbounded, 862 iterations, 0.06 seconds (0.05 work units)\n",
"\n",
" Nodes | Current Node | Objective Bounds | Work\n",
" Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n",
"\n",
" 0 0 postponed 0 - - - - 0s\n",
" 0 0 postponed 0 - - - - 0s\n",
" 0 2 postponed 0 - - - - 0s\n",
"H 35 31 -0.1298538 - - 261 0s\n",
"H 42 31 -0.3409819 - - 218 0s\n",
"H 72 30 -0.3462866 - - 138 1s\n",
"H 110 18 -0.3557482 - - 138 1s\n",
"H 125 16 -0.4010824 - - 146 1s\n",
"H 144 7 -0.4035719 -0.79918 98.0% 144 1s\n",
"\n",
"Explored 167 nodes (25805 simplex iterations) in 1.47 seconds (1.03 work units)\n",
"Thread count was 8 (of 8 available processors)\n",
"\n",
"Solution count 6: -0.403572 -0.401082 -0.355748 ... -0.129854\n",
"\n",
"Optimal solution found (tolerance 0.00e+00)\n",
"Best objective -4.035719394214e-01, best bound -4.035719394214e-01, gap 0.0000%\n"
]
}
],
"outputs": [],
"source": [
"# Build GurobiOptimizer object and solve optimization problem\n",
"params_gurobi = {\"MIPGap\": 0}\n",
Expand All @@ -279,29 +158,6 @@
"assert round(x_opt, 5) == round(y_opt, 5) and round(y_opt, 5) == round(z_opt, 5)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "f6e5a95f",
"metadata": {},
"outputs": [
{
"ename": "IndexError",
"evalue": "list index out of range",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[14], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m al \u001b[38;5;241m=\u001b[39m opt_gur\u001b[38;5;241m.\u001b[39m_active_leaves\n\u001b[0;32m 2\u001b[0m \u001b[38;5;66;03m# list[tuple[int, str]]\u001b[39;00m\n\u001b[1;32m----> 3\u001b[0m \u001b[43mal\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m]\u001b[49m\n",
"\u001b[1;31mIndexError\u001b[0m: list index out of range"
]
}
],
"source": [
"al = opt_gur._active_leaves\n",
"# list[tuple[int, str]]\n"
]
},
{
"cell_type": "markdown",
"id": "24b3d335-d601-41c1-ad46-d80949c0cfcc",
Expand Down Expand Up @@ -346,14 +202,6 @@
"source": [
"Note that no model update is required in the Pyomo version in contrast to the Gurobi variant"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6694759-9337-45b1-a39e-b608281cd1da",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
11 changes: 4 additions & 7 deletions entmoot/models/enting.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,16 @@ def fit(self, X: list | np.ndarray, y: np.ndarray) -> None:
X = self._problem_config.encode(X)

# check dims of X and y
if X.ndim == 1:
X = np.atleast_2d(X)
X = np.atleast_2d(X)
y = np.atleast_2d(y)

assert X.shape[-1] == len(self._problem_config.feat_list), (
"Argument 'X' has wrong dimensions. "
f"Expected '(num_samples, {len(self._problem_config.feat_list)})', got '{X.shape}'."
)

if y.ndim == 1:
y = np.atleast_2d(y)

assert (y.shape[-1] == 2 and len(self._problem_config.obj_list) == 1) or (
y.shape[-1] == len(self._problem_config.obj_list)
assert y.shape[-2] == X.shape[-2] and y.shape[-1] == len(
self._problem_config.obj_list
), (
"Argument 'y' has wrong dimensions. "
f"Expected '(num_samples, {len(self._problem_config.obj_list)})', got '{y.shape}'."
Expand Down
7 changes: 6 additions & 1 deletion entmoot/optimizers/pyomo_opt.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from typing import Optional

import numpy as np
Expand Down Expand Up @@ -97,6 +98,7 @@ def solve(
# choose solver
opt = pyo.SolverFactory(
self._params["solver_name"],
solver_io=self._params.get("solver_io", "python"),
manage_env="solver_factory_options" in self._params,
options=self._params.get("solver_factory_options", {}),
)
Expand All @@ -111,7 +113,10 @@ def solve(

# Solve optimization model
verbose = self._params.get("verbose", True)
opt.solve(opt_model, tee=verbose)
with warnings.catch_warnings():
# pyomo<6.7.2 raises a warning when creating a Gurobi model
warnings.simplefilter("ignore", category=DeprecationWarning)
opt.solve(opt_model, tee=verbose)

# update current solution
self._curr_sol, self._active_leaves = self._get_sol(opt_model)
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
numpy<2.0.0
lightgbm>=4.0.0
pyomo==6.7.0
pyomo==6.7.1
gurobipy
pytest-cov
IPython
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
numpy<2.0.0
lightgbm>=4.0.0
gurobipy
pyomo==6.7.0
pyomo==6.7.1
14 changes: 2 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@
version=about["__version__"],
url="https://github.com/cog-imperial/entmoot",
packages=find_packages(exclude=["tests", "docs"]),
install_requires=[
"numpy<=2.0.0",
"lightgbm>=4.0.0",
"gurobipy",
"pyomo==6.7.0"
],
setup_requires=[
"numpy<=2.0.0",
"lightgbm>=4.0.0",
"gurobipy",
"pyomo==6.7.0"
],
install_requires=["numpy<=2.0.0", "lightgbm>=4.0.0", "gurobipy", "pyomo==6.7.1"],
setup_requires=["numpy<=2.0.0", "lightgbm>=4.0.0", "gurobipy", "pyomo==6.7.1"],
)
Loading

0 comments on commit 4057ae3

Please sign in to comment.