forked from Pyomo/pyomo
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'coramin2' into mindtpy-presolve-coramin
- Loading branch information
Showing
92 changed files
with
19,320 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ defaults: | |
env: | ||
PYTHONWARNINGS: ignore::UserWarning | ||
PYTHON_CORE_PKGS: wheel | ||
PYPI_ONLY: z3-solver | ||
PYPI_ONLY: z3-solver pybnb | ||
PYPY_EXCLUDE: scipy numdifftools seaborn statsmodels | ||
CACHE_VER: v221013.1 | ||
NEOS_EMAIL: [email protected] | ||
|
@@ -94,6 +94,14 @@ jobs: | |
PYENV: conda | ||
PACKAGES: mpi4py | ||
|
||
- os: ubuntu-latest | ||
python: 3.11 | ||
other: /singletest | ||
category: "-m 'neos or importtest'" | ||
skip_doctest: 1 | ||
TARGET: linux | ||
PYENV: pip | ||
|
||
- os: ubuntu-latest | ||
python: '3.10' | ||
other: /cython | ||
|
@@ -149,6 +157,24 @@ jobs: | |
# path: cache/os | ||
# key: pkg-${{env.CACHE_VER}}.0-${{runner.os}} | ||
|
||
- name: install GiNaC | ||
if: matrix.other == '/singletest' | ||
run: | | ||
cd .. | ||
curl https://www.ginac.de/CLN/cln-1.3.7.tar.bz2 >cln-1.3.7.tar.bz2 | ||
tar -xvf cln-1.3.7.tar.bz2 | ||
cd cln-1.3.7 | ||
./configure | ||
make -j 2 | ||
sudo make install | ||
cd .. | ||
curl https://www.ginac.de/ginac-1.8.7.tar.bz2 >ginac-1.8.7.tar.bz2 | ||
tar -xvf ginac-1.8.7.tar.bz2 | ||
cd ginac-1.8.7 | ||
./configure | ||
make -j 2 | ||
sudo make install | ||
- name: TPL package download cache | ||
uses: actions/cache@v4 | ||
if: ${{ ! matrix.slim }} | ||
|
@@ -268,6 +294,8 @@ jobs: | |
|| echo "WARNING: Gurobi is not available" | ||
python -m pip install --cache-dir cache/pip xpress \ | ||
|| echo "WARNING: Xpress Community Edition is not available" | ||
python -m pip install --cache-dir cache/pip pybnb \ | ||
|| echo "WARNING: pybnb is not available" | ||
if [[ ${{matrix.python}} == pypy* ]]; then | ||
echo "skipping wntr for pypy" | ||
else | ||
|
@@ -337,6 +365,8 @@ jobs: | |
echo "*** Install Pyomo dependencies ***" | ||
# Note: this will fail the build if any installation fails (or | ||
# possibly if it outputs messages to stderr) | ||
CONDA_DEPENDENCIES="$CONDA_DEPENDENCIES metis" | ||
PYPI_DEPENDENCIES="$PYPI_DEPENDENCIES metis" | ||
conda install --update-deps -y $CONDA_DEPENDENCIES | ||
if test -z "${{matrix.slim}}"; then | ||
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g') | ||
|
@@ -609,13 +639,26 @@ jobs: | |
echo "" | ||
pyomo build-extensions --parallel 2 | ||
- name: Install GiNaC Interface | ||
if: matrix.other == '/singletest' | ||
run: | | ||
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH | ||
echo "LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV | ||
cd pyomo/contrib/simplification/ | ||
$PYTHON_EXE build.py --inplace | ||
- name: Report pyomo plugin information | ||
run: | | ||
echo "$PATH" | ||
pyomo help --solvers || exit 1 | ||
pyomo help --transformations || exit 1 | ||
pyomo help --writers || exit 1 | ||
- name: Run Simplification Tests | ||
if: matrix.other == '/singletest' | ||
run: | | ||
pytest -v -m 'simplification' pyomo/contrib/simplification/tests/test_simplification.py --junitxml="TEST-pyomo-simplify.xml" | ||
- name: Run Pyomo tests | ||
if: matrix.mpi == 0 | ||
run: | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ defaults: | |
env: | ||
PYTHONWARNINGS: ignore::UserWarning | ||
PYTHON_CORE_PKGS: wheel | ||
PYPI_ONLY: z3-solver | ||
PYPI_ONLY: z3-solver pybnb | ||
PYPY_EXCLUDE: scipy numdifftools seaborn statsmodels | ||
CACHE_VER: v221013.1 | ||
NEOS_EMAIL: [email protected] | ||
|
@@ -179,6 +179,24 @@ jobs: | |
# path: cache/os | ||
# key: pkg-${{env.CACHE_VER}}.0-${{runner.os}} | ||
|
||
- name: install GiNaC | ||
if: matrix.other == '/singletest' | ||
run: | | ||
cd .. | ||
curl https://www.ginac.de/CLN/cln-1.3.7.tar.bz2 >cln-1.3.7.tar.bz2 | ||
tar -xvf cln-1.3.7.tar.bz2 | ||
cd cln-1.3.7 | ||
./configure | ||
make -j 2 | ||
sudo make install | ||
cd .. | ||
curl https://www.ginac.de/ginac-1.8.7.tar.bz2 >ginac-1.8.7.tar.bz2 | ||
tar -xvf ginac-1.8.7.tar.bz2 | ||
cd ginac-1.8.7 | ||
./configure | ||
make -j 2 | ||
sudo make install | ||
- name: TPL package download cache | ||
uses: actions/cache@v4 | ||
if: ${{ ! matrix.slim }} | ||
|
@@ -298,6 +316,8 @@ jobs: | |
|| echo "WARNING: Gurobi is not available" | ||
python -m pip install --cache-dir cache/pip xpress \ | ||
|| echo "WARNING: Xpress Community Edition is not available" | ||
python -m pip install --cache-dir cache/pip pybnb \ | ||
|| echo "WARNING: pybnb is not available" | ||
if [[ ${{matrix.python}} == pypy* ]]; then | ||
echo "skipping wntr for pypy" | ||
else | ||
|
@@ -366,6 +386,8 @@ jobs: | |
echo "*** Install Pyomo dependencies ***" | ||
# Note: this will fail the build if any installation fails (or | ||
# possibly if it outputs messages to stderr) | ||
CONDA_DEPENDENCIES="$CONDA_DEPENDENCIES metis" | ||
PYPI_DEPENDENCIES="$PYPI_DEPENDENCIES metis" | ||
conda install --update-deps -q -y $CONDA_DEPENDENCIES | ||
if test -z "${{matrix.slim}}"; then | ||
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g') | ||
|
@@ -638,13 +660,26 @@ jobs: | |
echo "" | ||
pyomo build-extensions --parallel 2 | ||
- name: Install GiNaC Interface | ||
if: matrix.other == '/singletest' | ||
run: | | ||
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH | ||
echo "LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV | ||
cd pyomo/contrib/simplification/ | ||
$PYTHON_EXE build.py --inplace | ||
- name: Report pyomo plugin information | ||
run: | | ||
echo "$PATH" | ||
pyomo help --solvers || exit 1 | ||
pyomo help --transformations || exit 1 | ||
pyomo help --writers || exit 1 | ||
- name: Run Simplification Tests | ||
if: matrix.other == '/singletest' | ||
run: | | ||
pytest -v -m 'simplification' pyomo/contrib/simplification/tests/test_simplification.py --junitxml="TEST-pyomo-simplify.xml" | ||
- name: Run Pyomo tests | ||
if: matrix.mpi == 0 | ||
run: | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Coramin | ||
|
||
Coramin is a Pyomo-based Python package that provides tools for | ||
developing tailored algorithms for mixed-integer nonlinear programming | ||
problems (MINLP's). This software includes classes for managing and | ||
refining convex relaxations of nonconvex constraints. These classes | ||
provide methods for updating the relaxation based on new variable | ||
bounds, creating and managing piecewise relaxations (for multi-tree | ||
based algorithms), and adding outer-approximation based cuts for | ||
convex or concave constraints. These classes inherit from Pyomo | ||
Blocks, so they can be easily integrated with Pyomo | ||
models. Additionally, Coramin has functions for automatically | ||
generating convex relaxations of general Pyomo models. Coramin also | ||
has tools for domain reduction, including a parallel implementation | ||
of optimization-based bounds tightening (OBBT) and various OBBT | ||
filtering techniques. | ||
|
||
## Primary Contributors | ||
### [Michael Bynum](https://github.com/michaelbynum) | ||
- Relaxation classes | ||
- OBBT | ||
- OBBT Filtering | ||
- Factorable programming approach to generating relaxations | ||
|
||
### [Carl Laird](https://github.com/carldlaird) | ||
- Parallel OBBT | ||
- McCormick and piecewise McCormick relaxations for bilinear terms | ||
- Relaxations for univariate convex/concave functions | ||
|
||
### [Anya Castillo](https://github.com/anyacastillo) | ||
- Relaxation classes | ||
|
||
### [Francesco Ceccon](https://github.com/fracek) | ||
- Alpha-BB relaxation | ||
|
||
## Relevant Packages | ||
|
||
### [Suspect](https://github.com/cog-imperial/suspect) | ||
Use of Coramin can be improved significantly by also utilizing | ||
Suspect's convexity detection and feasibility-based bounds tightening | ||
features. Future development of Coramin will directly use Suspect in | ||
Coramin's factorable programming approach to generating relaxations. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from pyomo.common.dependencies import numpy, numpy_available, attempt_import | ||
from pyomo.common import unittest | ||
|
||
if not numpy_available: | ||
raise unittest.SkipTest('numpy is not available') | ||
|
||
pybnb, pybnb_available = attempt_import('pybnb') | ||
if not pybnb_available: | ||
raise unittest.SkipTest('pybnb is not available') | ||
|
||
from . import utils | ||
from . import domain_reduction | ||
from . import relaxations | ||
from . import algorithms | ||
from . import third_party | ||
from .utils import ( | ||
RelaxationSide, | ||
FunctionShape, | ||
Effort, | ||
EigenValueBounder, | ||
simplify_expr, | ||
get_objective, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .ecp_bounder import ECPBounder | ||
from .multitree.multitree import MultiTree | ||
from .bnb.bnb import BnBSolver |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import pyomo.environ as pe | ||
from pyomo.repn.standard_repn import generate_standard_repn, StandardRepn | ||
from pyomo.contrib.coramin.relaxations.split_expr import split_expr | ||
from pyomo.core.expr.numeric_expr import LinearExpression | ||
from pyomo.core.base.var import _GeneralVarData | ||
from pyomo.core.base.block import _BlockData | ||
from pyomo.common.collections import ComponentSet | ||
from typing import Tuple, List, Sequence | ||
|
||
|
||
def collect_vars(m: _BlockData) -> Tuple[List[_GeneralVarData], List[_GeneralVarData]]: | ||
binary_vars = ComponentSet() | ||
integer_vars = ComponentSet() | ||
for v in m.vars: | ||
if v.is_binary(): | ||
binary_vars.add(v) | ||
elif v.is_integer(): | ||
integer_vars.add(v) | ||
return list(binary_vars), list(integer_vars) | ||
|
||
|
||
def relax_integers( | ||
binary_vars: Sequence[_GeneralVarData], integer_vars: Sequence[_GeneralVarData] | ||
): | ||
for v in list(binary_vars) + list(integer_vars): | ||
lb, ub = v.bounds | ||
v.domain = pe.Reals | ||
v.setlb(lb) | ||
v.setub(ub) | ||
|
||
|
||
def impose_structure(m): | ||
m.aux_vars = pe.VarList() | ||
|
||
for key, c in list(m.nonlinear.cons.items()): | ||
repn: StandardRepn = generate_standard_repn( | ||
c.body, quadratic=False, compute_values=True | ||
) | ||
expr_list = split_expr(repn.nonlinear_expr) | ||
if len(expr_list) == 1: | ||
continue | ||
|
||
linear_coefs = list(repn.linear_coefs) | ||
linear_vars = list(repn.linear_vars) | ||
for term in expr_list: | ||
v = m.aux_vars.add() | ||
linear_coefs.append(1) | ||
linear_vars.append(v) | ||
m.vars.append(v) | ||
if c.equality or (c.lb == c.ub and c.lb is not None): | ||
m.nonlinear.cons.add(v == term) | ||
elif c.ub is None: | ||
m.nonlinear.cons.add(v <= term) | ||
elif c.lb is None: | ||
m.nonlinear.cons.add(v >= term) | ||
else: | ||
m.nonlinear.cons.add(v == term) | ||
new_expr = LinearExpression( | ||
constant=repn.constant, linear_coefs=linear_coefs, linear_vars=linear_vars | ||
) | ||
m.linear.cons.add((c.lb, new_expr, c.ub)) | ||
del m.nonlinear.cons[key] | ||
|
||
if hasattr(m.nonlinear, 'obj'): | ||
obj = m.nonlinear.obj | ||
repn: StandardRepn = generate_standard_repn( | ||
obj.expr, quadratic=False, compute_values=True | ||
) | ||
expr_list = split_expr(repn.nonlinear_expr) | ||
if len(expr_list) > 1: | ||
linear_coefs = list(repn.linear_coefs) | ||
linear_vars = list(repn.linear_vars) | ||
for term in expr_list: | ||
v = m.aux_vars.add() | ||
linear_coefs.append(1) | ||
linear_vars.append(v) | ||
m.vars.append(v) | ||
if obj.sense == pe.minimize: | ||
m.nonlinear.cons.add(v >= term) | ||
else: | ||
assert obj.sense == pe.maximize | ||
m.nonlinear.cons.add(v <= term) | ||
new_expr = LinearExpression( | ||
constant=repn.constant, | ||
linear_coefs=linear_coefs, | ||
linear_vars=linear_vars, | ||
) | ||
m.linear.obj = pe.Objective(expr=new_expr, sense=obj.sense) | ||
del m.nonlinear.obj |
Empty file.
Oops, something went wrong.