Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Coramin #3174

Draft
wants to merge 153 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
3121fa1
moving coramin to contrib
michaelbynum Oct 27, 2023
6bf34d5
update imports
michaelbynum Oct 27, 2023
3e8b60f
update imports
michaelbynum Oct 27, 2023
0406fe2
update imports
michaelbynum Oct 27, 2023
4f81ae9
update tests
michaelbynum Oct 27, 2023
0c857d0
fix tests
michaelbynum Oct 27, 2023
2755bac
update tests
michaelbynum Oct 27, 2023
255bc45
run black
michaelbynum Oct 27, 2023
35ac7d4
fix typos
michaelbynum Oct 27, 2023
a54bceb
fix typos
michaelbynum Oct 27, 2023
ccbc0b9
fix typos
michaelbynum Oct 27, 2023
4d97757
fix typos
michaelbynum Oct 27, 2023
8d1e68e
working on simplification contrib package
michaelbynum Nov 8, 2023
8015d7e
working on simplification contrib package
michaelbynum Nov 8, 2023
56e8ac8
working on ginac interface for simplification
michaelbynum Nov 20, 2023
932d3d6
ginac interface improvements
michaelbynum Nov 20, 2023
208a5da
simplification interface
michaelbynum Nov 20, 2023
6ef8914
bugs
michaelbynum Nov 21, 2023
af47ef7
simplification tests
michaelbynum Nov 21, 2023
7262885
Merge branch 'main' into coramin
michaelbynum Dec 7, 2023
a6f0e2a
coramin improvements
michaelbynum Dec 22, 2023
52b6ad3
clean up diving heuristic
michaelbynum Dec 23, 2023
cb09908
revert changes to interval.py
michaelbynum Dec 26, 2023
205811e
working on branch and bound
michaelbynum Dec 26, 2023
2e205a5
working on branch and bound
michaelbynum Dec 26, 2023
9e62469
working on branch and bound
michaelbynum Dec 26, 2023
c803f56
branch and bound improvements
michaelbynum Dec 28, 2023
5840de0
BnB improvements
michaelbynum Jan 9, 2024
475ec06
simplification tests
michaelbynum Jan 10, 2024
491db9f
update GHA to install ginac
michaelbynum Jan 10, 2024
b3a1ff9
run black
michaelbynum Jan 10, 2024
de8743a
syntax
michaelbynum Jan 10, 2024
ee9f830
install ginac in GHA
michaelbynum Jan 10, 2024
36cfd63
install ginac in GHA
michaelbynum Jan 10, 2024
8269539
install ginac in GHA
michaelbynum Jan 10, 2024
7bb0ff5
install ginac in GHA
michaelbynum Jan 10, 2024
546dad1
install ginac in GHA
michaelbynum Jan 10, 2024
37a955b
install ginac in GHA
michaelbynum Jan 10, 2024
05134ce
install ginac in GHA
michaelbynum Jan 10, 2024
1151927
install ginac in GHA
michaelbynum Jan 11, 2024
2c4fdbe
skip tests when dependencies are not available
michaelbynum Jan 11, 2024
9ebd79b
install ginac in GHA
michaelbynum Jan 11, 2024
0bd1563
update simplification tests
michaelbynum Jan 11, 2024
26007ac
run black
michaelbynum Jan 11, 2024
fc36411
add pytest marker for simplification
michaelbynum Jan 11, 2024
2007de4
Merge branch 'main' into ginac
michaelbynum Jan 11, 2024
5ba03e2
update GHA
michaelbynum Jan 11, 2024
90cdeba
update GHA
michaelbynum Jan 11, 2024
17cb11d
debugging GHA
michaelbynum Jan 11, 2024
d1fe244
test simplification with ginac and sympy
michaelbynum Jan 11, 2024
9159c3c
test simplification with ginac and sympy
michaelbynum Jan 11, 2024
457f2b3
fixing simplification tests
michaelbynum Jan 11, 2024
1e7c3f1
fixing simplification tests
michaelbynum Jan 11, 2024
b2d969f
fixing simplification tests
michaelbynum Jan 11, 2024
372487e
Merge branch 'gdp_minlp' into coramin2
michaelbynum Jan 11, 2024
f60271d
Merge branch 'ginac' into coramin2
michaelbynum Jan 11, 2024
da2fe3d
fixing simplification tests
michaelbynum Jan 11, 2024
514e93d
Merge branch 'gdp_minlp' into coramin2
michaelbynum Jan 11, 2024
e525732
Coramin: remove ComponentWeakRef
michaelbynum Jan 12, 2024
b73d0cc
Coramin: allow aux_var to be a float
michaelbynum Jan 12, 2024
0c475f8
Merge branch 'gdp_minlp' into coramin2
michaelbynum Jan 12, 2024
7c17a18
coramin: working on heuristics
michaelbynum Jan 12, 2024
70237d3
coramin: cleanup
michaelbynum Jan 15, 2024
9f7d546
Merge branch 'main' into coramin2
michaelbynum Jan 16, 2024
7bf699f
working on heuristics
michaelbynum Jan 17, 2024
c2067a1
Merge branch 'gdp_minlp' into coramin2
michaelbynum Jan 17, 2024
ee615ea
working on heuristics
michaelbynum Jan 17, 2024
d37b304
Merge remote-tracking branch 'main_fork/main' into ginac
michaelbynum Jan 22, 2024
2b1596b
fixing simplification tests
michaelbynum Jan 22, 2024
d75c5f8
fixing simplification tests
michaelbynum Jan 22, 2024
dae0205
run black
michaelbynum Jan 22, 2024
313108d
fixing simplification tests
michaelbynum Jan 22, 2024
5ff4d4d
fixing simplification tests
michaelbynum Jan 22, 2024
010a997
fixing simplification tests
michaelbynum Jan 22, 2024
2c59b29
fixing simplification tests
michaelbynum Jan 22, 2024
d67d90d
fixing simplification tests
michaelbynum Jan 22, 2024
3fcec35
fixing simplification tests
michaelbynum Jan 22, 2024
b5550fe
fixing simplification tests
michaelbynum Jan 22, 2024
8984389
fixing simplification tests
michaelbynum Jan 22, 2024
6246430
Merge remote-tracking branch 'main_fork/main' into coramin2
michaelbynum Jan 22, 2024
42cd7a9
Merge branch 'ginac' into coramin2
michaelbynum Jan 22, 2024
85fba42
coramin: cleanup
michaelbynum Jan 22, 2024
646bbd7
coramin: B&B
michaelbynum Jan 22, 2024
c204466
coramin: B&B
michaelbynum Jan 22, 2024
b5a1dcf
coramin: B&B
michaelbynum Jan 22, 2024
f74c399
coramin: B&B
michaelbynum Jan 22, 2024
a7349fc
coramin: cleanup
michaelbynum Jan 22, 2024
125b7c7
Merge branch 'main' into ginac
michaelbynum Jan 24, 2024
7b9053a
coramin cut generators
michaelbynum Jan 24, 2024
334b7cb
Merge remote-tracking branch 'main_fork/main' into coramin2
michaelbynum Jan 24, 2024
9836e14
coramin cleanup
michaelbynum Jan 24, 2024
1f28b9f
coramin cleanup
michaelbynum Jan 24, 2024
4b700ba
coramin: update tests
michaelbynum Jan 24, 2024
1e82694
coramin: update tests
michaelbynum Jan 24, 2024
7b9760a
coramin: update tests
michaelbynum Jan 24, 2024
2203c80
coramin: cleanup
michaelbynum Jan 26, 2024
f55fb1a
coramin: update tests
michaelbynum Jan 26, 2024
ee36bd8
coramin: clean up domain reduction
michaelbynum Jan 30, 2024
c7bf0ef
add utility to compare feasible regions of two models
michaelbynum Jan 31, 2024
1dfb506
coramin cleanup
michaelbynum Jan 31, 2024
ac7a40d
coramin: working on tests
michaelbynum Jan 31, 2024
1d0e44d
identify variables cache
michaelbynum Jan 31, 2024
ac48999
coramin: working on tests
michaelbynum Feb 1, 2024
3801016
update tests
michaelbynum Feb 7, 2024
6c4d827
update tests
michaelbynum Feb 7, 2024
26df9b5
coramin: working on tests
michaelbynum Feb 7, 2024
acb2f9d
coramin: working on tests
michaelbynum Feb 8, 2024
92163f2
cleanup
michaelbynum Feb 21, 2024
0dff80f
cleanup
michaelbynum Feb 21, 2024
c49c2df
cleanup
michaelbynum Feb 21, 2024
2c42772
Merge remote-tracking branch 'michaelbynum/ginac' into ginac
michaelbynum Feb 21, 2024
ce308d9
Merge branch 'main' into ginac
michaelbynum Feb 21, 2024
29d6a19
cleanup
michaelbynum Feb 21, 2024
350f3d0
Merge remote-tracking branch 'main_fork/main' into ginac
michaelbynum Feb 21, 2024
f9b039c
Merge branch 'ginac' into coramin2
michaelbynum Feb 21, 2024
f195650
fix division by zero error in linear presolve
michaelbynum Feb 22, 2024
e2f46b2
Merge branch 'zero_presolve' into coramin2
michaelbynum Feb 22, 2024
fd656e0
run black
michaelbynum Feb 22, 2024
8de4b3c
Merge branch 'zero_presolve' into coramin2
michaelbynum Feb 22, 2024
2aae9c5
merge zero_presolve
michaelbynum Feb 25, 2024
8d9926e
merge zero_presolve
michaelbynum Feb 25, 2024
d543fb9
Merge branch 'zero_presolve' into coramin2
michaelbynum Feb 25, 2024
23131ce
run black
michaelbynum Feb 25, 2024
a2a6f2b
fix typo
michaelbynum Feb 25, 2024
19f0c5d
update optional requirements
michaelbynum Feb 25, 2024
b88cfd6
update imports
michaelbynum Feb 25, 2024
7f62934
update GHA
michaelbynum Feb 25, 2024
706b793
fix imports
michaelbynum Feb 25, 2024
e3330de
fix tests
michaelbynum Feb 25, 2024
81684d6
update GHA
michaelbynum Feb 25, 2024
8d51683
fix available
michaelbynum Feb 25, 2024
87637f6
run black
michaelbynum Feb 25, 2024
8781914
Merge remote-tracking branch 'main_fork/main' into coramin2
michaelbynum Mar 3, 2024
9f6afd9
osil parser
michaelbynum Mar 4, 2024
9f7a1f0
use osil parser in tests
michaelbynum Mar 4, 2024
e0e9f34
bugs
michaelbynum Mar 4, 2024
b36459b
update tests
michaelbynum Mar 4, 2024
7e7364a
update tests
michaelbynum Mar 4, 2024
1c3fe3a
update tests
michaelbynum Mar 4, 2024
e07bae8
update tests
michaelbynum Mar 4, 2024
74f751f
run black
michaelbynum Mar 4, 2024
4b86141
typo
michaelbynum Mar 4, 2024
45a27bf
add some __init__ files
michaelbynum Mar 4, 2024
0f3b245
update imports
michaelbynum Mar 4, 2024
4a90f09
update imports
michaelbynum Mar 4, 2024
21ee445
update GHA
michaelbynum Mar 4, 2024
01cc572
update imports
michaelbynum Mar 4, 2024
96e2b03
update imports
michaelbynum Mar 4, 2024
c1d0324
merge main
michaelbynum Mar 6, 2024
01e0658
Merge branch 'main' into coramin2
michaelbynum Apr 8, 2024
e859b78
fix bug
michaelbynum Apr 23, 2024
1261ff9
Merge branch 'main' into coramin2
michaelbynum May 4, 2024
8b2c4e2
Merge remote-tracking branch 'main_fork/main' into coramin2
michaelbynum May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ omit =
setup.py
*/tests/*
*/tmp/*
*/minlplib/*

# The [run] section must be at the end, as the build harness will add a
# "data_file" directive to the end of this file.
Expand All @@ -17,3 +18,4 @@ source =
omit =
# github actions creates a cache directory we don't want measured
cache/*
*/minlplib/*
45 changes: 44 additions & 1 deletion .github/workflows/test_branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -95,6 +95,14 @@ jobs:
PYENV: conda
PACKAGES: openmpi 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
Expand Down Expand Up @@ -150,6 +158,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 }}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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: |
Expand Down
37 changes: 36 additions & 1 deletion .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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]
Expand Down Expand Up @@ -187,6 +187,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 }}
Expand Down Expand Up @@ -305,6 +323,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
Expand Down Expand Up @@ -373,6 +393,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')
Expand Down Expand Up @@ -646,13 +668,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: |
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/appsi/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1637,7 +1637,7 @@ def solve(

return legacy_results

def available(self, exception_flag=True):
def available(self, exception_flag=False):
ans = super(LegacySolverInterface, self).available()
if exception_flag and not ans:
raise ApplicationError(f'Solver {self.__class__} is not available ({ans}).')
Expand Down
6 changes: 4 additions & 2 deletions pyomo/contrib/appsi/fbbt.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ def _add_params(self, params: List[ParamData]):
cparams = cmodel.create_params(len(params))
for ndx, p in enumerate(params):
cp = cparams[ndx]
cp.value = p.value
if p.value is not None:
cp.value = p.value
self._param_map[id(p)] = cp
if self._symbolic_solver_labels:
for ndx, p in enumerate(params):
Expand Down Expand Up @@ -222,7 +223,8 @@ def _update_variables(self, variables: List[VarData]):
def update_params(self):
for p_id, p in self._params.items():
cp = self._param_map[p_id]
cp.value = p.value
if p.value is not None:
cp.value = p.value

def set_objective(self, obj: ObjectiveData):
if self._symbolic_solver_labels:
Expand Down
1 change: 1 addition & 0 deletions pyomo/contrib/appsi/solvers/highs.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ def _remove_constraints(self, cons: List[ConstraintData]):
del self._solver_con_to_pyomo_con_map[con_ndx]
indices_to_remove.append(con_ndx)
self._mutable_helpers.pop(con, None)
indices_to_remove.sort()
self._solver_model.deleteRows(
len(indices_to_remove), np.array(indices_to_remove)
)
Expand Down
43 changes: 43 additions & 0 deletions pyomo/contrib/coramin/README.md
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.

23 changes: 23 additions & 0 deletions pyomo/contrib/coramin/__init__.py
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,
)
3 changes: 3 additions & 0 deletions pyomo/contrib/coramin/algorithms/__init__.py
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
89 changes: 89 additions & 0 deletions pyomo/contrib/coramin/algorithms/alg_utils.py
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.
Loading