├── .coin-or └── projDesc.xml ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── github-ci.yml ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── README.md ├── benchmarks ├── .ycm_extra_conf.py ├── bench.sh ├── bmcp.py ├── bmcp_data.py ├── bmcp_sol.py ├── data │ ├── bmcp │ │ ├── GEOM110.col │ │ ├── GEOM30.col │ │ ├── GEOM50.col │ │ ├── GEOM70.col │ │ ├── GEOM90.col │ │ └── colors.csv │ └── rcpsp │ │ ├── j1201_1.sm │ │ ├── j301_1.sm │ │ └── j601_1.sm ├── queens-gurobi.py ├── queens-jump.csv ├── queens-pulp.py ├── queens.ods ├── queens.py └── rcpsp.py ├── docs ├── Makefile ├── bench.rst ├── bibliography.rst ├── classes.rst ├── coin-or-cup │ ├── Makefile │ ├── c-cup.pdf │ ├── c-cup.tex │ └── references.bib ├── conf.py ├── custom.rst ├── examples.rst ├── extern.rst ├── images │ ├── 2dlp.odg │ ├── 2dlp.pdf │ ├── belgium-tourism-14-opt-547.png │ ├── belgium-tourism-14-subtour.png │ ├── belgium-tourism-14.png │ ├── bmcpsmall.pdf │ ├── bmcpsmall.png │ ├── coin-or-logo.png │ ├── jssp1.pdf │ ├── jssp1.png │ ├── jssp2.pdf │ ├── jssp2.png │ ├── location-sol.pdf │ ├── location-sol.png │ ├── location.pdf │ ├── location.png │ ├── log_cost.pdf │ ├── log_cost.png │ ├── notebooks_transportation-problem_48_0.png │ ├── philadelphia.png │ ├── quadratic_function_discrete.png │ ├── rcpsp-opt.eps │ ├── rcpsp-opt.pdf │ ├── rcpsp-opt.png │ ├── rcpsp.eps │ ├── rcpsp.pdf │ ├── rcpsp.png │ ├── roll.pdf │ ├── roll.png │ ├── tdlpp-instance.pdf │ ├── tdlpp-instance.png │ ├── tspC.pdf │ ├── tspC.png │ ├── tspG.pdf │ ├── tspG.png │ ├── tspNo2Sub.pdf │ ├── tspNo2Sub.png │ ├── tspRoot.pdf │ ├── tspRoot.png │ ├── tspSt1.pdf │ └── tspSt1.png ├── index.rst ├── install.rst ├── intro.rst ├── plot_log.py ├── podes │ ├── Makefile │ ├── belgium-tourism-14-subtour.png │ ├── logoSobrapo.pdf │ ├── pmip-podes.bib │ ├── podes-bibstyle.bst │ ├── podes-template.sty │ └── python-mip-tutorial-podes.tex ├── python-mip_theme │ ├── __init__.py │ ├── layout.html │ ├── static │ │ ├── css │ │ │ ├── alabaster.css_t │ │ │ ├── sphinx.css │ │ │ └── style.css │ │ ├── img │ │ │ └── header-bg.png │ │ ├── js │ │ │ └── main.js │ │ └── lib │ │ │ ├── animate │ │ │ ├── animate.css │ │ │ └── animate.min.css │ │ │ ├── bootstrap │ │ │ ├── css │ │ │ │ ├── bootstrap.css │ │ │ │ └── bootstrap.min.css │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ └── bootstrap.min.js │ │ │ ├── easing │ │ │ ├── easing.js │ │ │ └── easing.min.js │ │ │ ├── font-awesome │ │ │ ├── css │ │ │ │ ├── font-awesome.css │ │ │ │ └── font-awesome.min.css │ │ │ └── fonts │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ ├── ionicons │ │ │ ├── css │ │ │ │ ├── ionicons.css │ │ │ │ └── ionicons.min.css │ │ │ └── fonts │ │ │ │ ├── ionicons.eot │ │ │ │ ├── ionicons.svg │ │ │ │ ├── ionicons.ttf │ │ │ │ └── ionicons.woff │ │ │ ├── isotope │ │ │ ├── isotope.pkgd.js │ │ │ └── isotope.pkgd.min.js │ │ │ ├── jquery │ │ │ ├── jquery-migrate.min.js │ │ │ └── jquery.min.js │ │ │ ├── mobile-nav │ │ │ └── mobile-nav.js │ │ │ └── wow │ │ │ ├── wow.js │ │ │ └── wow.min.js │ └── theme.conf ├── quickstart.rst ├── requirements.txt └── sos.rst ├── examples ├── P1.col ├── apps │ ├── bmcp │ │ ├── bmcp.py │ │ ├── bmcp2.py │ │ ├── bmcp_data.py │ │ ├── bmcp_greedy.py │ │ ├── bmcp_mip.py │ │ └── bmcp_sol.py │ └── tsp │ │ ├── bench.sh │ │ ├── rb-bier127.sh │ │ ├── rb-gr202.sh │ │ ├── rb-lin318.sh │ │ ├── rb.sh │ │ ├── tsp.py │ │ └── tsplibtodist.py ├── belgium-tourism-14.tsp ├── bmcp.py ├── cgraph.py ├── clique_merge.py ├── conflict_finder.py ├── cutting_planes.py ├── cuttingstock_cg.py ├── cuttingstock_kantorovich.py ├── europe-tourism-22.tsp ├── extract_features_mip.py ├── gen_cuts.py ├── gen_cuts_mip.py ├── img │ ├── belgium-tourism-14.gif │ └── europe-tourism-22.gif ├── inplace_linexpr_creation.py ├── jssp.py ├── knapsack.py ├── numpy_tensor.py ├── plant_location.py ├── queens.py ├── rcpsp.py ├── test.sh ├── tsp-compact-ulysses22.py ├── tsp-compact.py ├── tsp-cuts-ulysses22.py ├── tsp-cuts.py ├── tsp-lazy-ulysses22.py ├── tsp-mipstart.py ├── two-dim-pack.py └── ulysses22.tsp ├── mip ├── __init__.py ├── callbacks.py ├── cbc.py ├── conflict.py ├── constants.py ├── entities.py ├── exceptions.py ├── gurobi.py ├── highs.py ├── libraries │ ├── cbc-c-darwin-arm64.dylib │ ├── cbc-c-darwin-x86-64.dylib │ ├── cbc-c-linux-x86-64.so │ └── win64 │ │ ├── cbc-c-windows-x86-64.dll │ │ ├── libbz2-1.dll │ │ ├── libgcc_s_seh-1.dll │ │ ├── libstdc++-6.dll │ │ └── libwinpthread-1.dll ├── lists.py ├── log.py ├── model.py ├── ndarray.py └── solver.py ├── pyproject.toml ├── scripts ├── buildCBCLinux.sh ├── buildCBCLinuxAs.sh ├── buildCBCLinuxDbg.sh ├── buildCBCMac.sh ├── buildCBCMacARM.sh ├── buildCBCWin.sh ├── buildMSV.bat ├── downloadCBC.sh ├── downloadCBConly.sh ├── downloadCBConlysvn.sh ├── downloadCBCsvn.sh ├── patchLibrariesLinux.sh ├── updateDist.sh └── uploadPip.sh └── test ├── conftest.py ├── data ├── 10teams.mps.gz ├── 1443_0-9.lp ├── 2050_3_7.lp ├── air04.mps.gz ├── air05.mps.gz ├── arki001.mps.gz ├── bell3a.mps.gz ├── bell5.mps.gz ├── bft.lp ├── blend2.mps.gz ├── cap6000.mps.gz ├── dano3mip.mps.gz ├── danoint.mps.gz ├── dcmulti.mps.gz ├── egout.mps.gz ├── enigma.mps.gz ├── fast0507.bas ├── fast0507.mps.gz ├── fiber.mps.gz ├── fixnet6.mps.gz ├── flugpl.mps.gz ├── gen.mps.gz ├── gesa2.mps.gz ├── gesa2_o.mps.gz ├── gesa3.mps.gz ├── gesa3_o.mps.gz ├── gt2.mps.gz ├── harp2.mps.gz ├── khb05250.mps.gz ├── l152lav.mps.gz ├── lseu.mps.gz ├── markshare1.mps.gz ├── mas74.mps.gz ├── mas76.mps.gz ├── misc03.mps.gz ├── misc06.mps.gz ├── misc07.mps.gz ├── mkc.mps.gz ├── mod008.mps.gz ├── mod010.mps.gz ├── modglob.mps.gz ├── p0033.mps.gz ├── p0201.mps.gz ├── p0282.mps.gz ├── p0548.mps.gz ├── p2756.mps.gz ├── pk1.mps.gz ├── pmp-iss-157.mps.gz ├── pp08a.mps.gz ├── pp08aCUTS.mps.gz ├── qiu.mps.gz ├── qnet1.mps.gz ├── qnet1_o.mps.gz ├── rcpsp-10-1.json ├── rcpsp-10-2.json ├── rcpsp-10-3.json ├── rcpsp-10-4.json ├── rcpsp-10-5.json ├── rcpsp-11-1.json ├── rcpsp-11-2.json ├── rcpsp-11-3.json ├── rcpsp-11-4.json ├── rcpsp-11-5.json ├── rcpsp-5-1.json ├── rcpsp-5-10.json ├── rcpsp-5-2.json ├── rcpsp-5-3.json ├── rcpsp-5-4.json ├── rcpsp-5-5.json ├── rcpsp-5-6.json ├── rcpsp-5-7.json ├── rcpsp-5-8.json ├── rcpsp-5-9.json ├── rcpsp-6-1.json ├── rcpsp-6-10.json ├── rcpsp-6-2.json ├── rcpsp-6-3.json ├── rcpsp-6-4.json ├── rcpsp-6-5.json ├── rcpsp-6-6.json ├── rcpsp-6-7.json ├── rcpsp-6-8.json ├── rcpsp-6-9.json ├── rcpsp-7-1.json ├── rcpsp-7-10.json ├── rcpsp-7-2.json ├── rcpsp-7-3.json ├── rcpsp-7-4.json ├── rcpsp-7-5.json ├── rcpsp-7-6.json ├── rcpsp-7-7.json ├── rcpsp-7-8.json ├── rcpsp-7-9.json ├── rcpsp-8-1.json ├── rcpsp-8-10.json ├── rcpsp-8-2.json ├── rcpsp-8-3.json ├── rcpsp-8-4.json ├── rcpsp-8-5.json ├── rcpsp-8-6.json ├── rcpsp-8-7.json ├── rcpsp-8-8.json ├── rcpsp-8-9.json ├── rcpsp-9-1.json ├── rcpsp-9-10.json ├── rcpsp-9-2.json ├── rcpsp-9-3.json ├── rcpsp-9-4.json ├── rcpsp-9-5.json ├── rcpsp-9-6.json ├── rcpsp-9-7.json ├── rcpsp-9-8.json ├── rcpsp-9-9.json ├── rgn.mps.gz ├── rout.mps.gz ├── set1ch.mps.gz ├── seymour.mps.gz ├── stein27.mps.gz ├── stein45.mps.gz ├── swath.mps.gz ├── two_dim_pack_100_1000_10.json ├── two_dim_pack_100_1000_20.json ├── two_dim_pack_100_10_10.json ├── two_dim_pack_100_10_20.json ├── two_dim_pack_20_1000_10.json ├── two_dim_pack_20_1000_20.json ├── two_dim_pack_20_10_10.json ├── two_dim_pack_20_10_20.json ├── two_dim_pack_40_1000_10.json ├── two_dim_pack_40_1000_20.json ├── two_dim_pack_40_10_10.json ├── two_dim_pack_40_10_20.json ├── two_dim_pack_60_1000_10.json ├── two_dim_pack_60_1000_20.json ├── two_dim_pack_60_10_10.json ├── two_dim_pack_60_10_20.json ├── two_dim_pack_80_1000_10.json ├── two_dim_pack_80_1000_20.json ├── two_dim_pack_80_10_10.json ├── two_dim_pack_80_10_20.json ├── vpm1.mps.gz └── vpm2.mps.gz ├── dbft_test.py ├── examples_test.py ├── mip_2d_pack.py ├── mip_files_test.py ├── mip_rcpsp.py ├── mip_test.py ├── numpy_test.py ├── rcpsp_test.py ├── test_conflict.py ├── test_gurobi.py ├── test_model.py ├── two_dim_pack_test.py └── util.py /.coin-or/projDesc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Python MIP 6 | python-mip 7 | 8 | Python MIP is a collection of Python tools for the modeling and 9 | solution of Mixed-Integer Linear programs (MIPs). MIP syntax was 10 | inspired by Pulp. Just like CyLP it also provides access to 11 | advanced solver features like cut generation, MIPstarts and 12 | solution Pools. Porting Pulp and Gurobi models should be 13 | quite easy. 14 | 15 | 16 | Python MIP is a collection of Python tools for the modeling and 17 | solution of Mixed-Integer Linear programs (MIPs). 18 | 19 | Haroldo Gambini Santos 20 | https://github.com/coin-or/python-mip 21 | Eclipse Public License 2.0 22 | https://opensource.org/licenses/EPL-2.0 23 | 24 | 25 | Cbc 26 | 27 | 28 | 29 | 30 | Gurobi 31 | https://www.gurobi.com 32 | Optional 33 | 34 | 35 | Python 36 | 37 | Active 38 | 3 39 | 40 | 41 | 42 | 43 | 44 | Interfaces 45 | Modeling systems 46 | Optimization deterministic linear continuous 47 | Optimization deterministic linear discrete 48 | Optimization utility 49 | 50 | 51 | 52 | 53 | https://python-mip.readthedocs.io/en/latest/ 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior **please include attached any files needed to reproduce the error**. We can only help you if we can reproduce the error ourselves and debug. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Desktop (please complete the following information):** 20 | - Operating System, version: 21 | - Python version: 22 | - Python-MIP version (we recommend you to test with the latest version): 23 | 24 | **Additional context** 25 | Add any other context about the problem here. 26 | -------------------------------------------------------------------------------- /.github/workflows/github-ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | 7 | pre-commit: 8 | 9 | runs-on: ubuntu-22.04 10 | 11 | steps: 12 | 13 | - uses: actions/checkout@v4 14 | 15 | - name: Set up Python 16 | uses: actions/setup-python@v5 17 | with: 18 | python-version: 3.11 19 | 20 | - name: Upgrade pip 21 | run: python -m pip install --upgrade pip 22 | 23 | - name: Install pre-commit 24 | run: pip install pre-commit 25 | 26 | - name: Check pre-commit version 27 | run: pre-commit --version 28 | 29 | - name: Set up hooks 30 | run: pre-commit install 31 | 32 | - name: Check style 33 | run: pre-commit run --all-files 34 | 35 | 36 | test: 37 | 38 | runs-on: ${{ matrix.os }} 39 | strategy: 40 | fail-fast: false 41 | matrix: 42 | python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "pypy3.9-v7.3.15"] 43 | os: [macos-11, macos-12, ubuntu-20.04, ubuntu-22.04, windows-2019, windows-2022] 44 | exclude: 45 | # temporarily exclude pypy3 on mac-os as there failing tests caused by bug on cbc side 46 | - os: macos-11 47 | python-version: "pypy3.9-v7.3.15" 48 | - os: macos-12 49 | python-version: "pypy3.9-v7.3.15" 50 | 51 | steps: 52 | 53 | - uses: actions/checkout@v4 54 | 55 | - name: Set up Python ${{ matrix.python-version }} 56 | uses: actions/setup-python@v5 57 | with: 58 | python-version: ${{ matrix.python-version }} 59 | architecture: x64 60 | cache: 'pip' 61 | 62 | - name: Check python version 63 | run: python -c "import sys; import platform; print('Python %s implementation %s on %s' % (sys.version, platform.python_implementation(), sys.platform))" 64 | 65 | - name: Upgrade pip 66 | run: python -m pip install --upgrade pip 67 | 68 | - name: Install test and numpy 69 | run: python -m pip install .[test,numpy] 70 | 71 | - name: Install gurobi 72 | if: ${{ matrix.python-version != 'pypy3.9-v7.3.15' }} 73 | run: python -m pip install .[gurobi] 74 | 75 | - name: Install highs 76 | if: ${{ !contains(matrix.os, 'windows') && !(matrix.os == 'ubuntu-22.04' && matrix.python-version == '3.9') }} 77 | run: python -m pip install .[highs] 78 | 79 | - name: list installed packages 80 | run: python -m pip list 81 | 82 | - name: Run tests 83 | run: python -m pytest test --verbose --color=yes --doctest-modules -Werror 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # Generated by setuptools_scm 7 | mip/_version.py 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache/ 108 | 109 | # Eclipse Core 110 | .project 111 | 112 | # PyDev specific (Python IDE for Eclipse) 113 | *.pydevproject 114 | 115 | # KDevelop4 116 | *.kdev4 117 | .kdev4/ 118 | 119 | # JetBrains Intellij 120 | .idea/ 121 | 122 | # Vscode 123 | .vscode/ 124 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | files: ^mip/ 2 | exclude: ^mip/_version.py 3 | repos: 4 | - repo: https://github.com/psf/black 5 | rev: 22.3.0 6 | hooks: 7 | - id: black 8 | args: [--line-length=89] 9 | - repo: https://github.com/pycqa/flake8 10 | rev: 4.0.1 11 | hooks: 12 | - id: flake8 13 | args: [--select=F401, --exclude=__init__.py] 14 | -------------------------------------------------------------------------------- /benchmarks/bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -f queens-mip-cbc-cpython.csv queens-mip-cbc-pypy.csv queens-mip-grb-cpython.csv \ 4 | queens-mip-grb-pypy.csv 5 | 6 | echo "Benchmarking n-Queens CBC Python-MIP CPYTHON" 7 | python3 queens.py cbc 8 | mv queens-mip-cbc.csv queens-mip-cbc-cpython.csv 9 | 10 | echo "Benchmarking n-Queens Gurobi Python-MIP CPYTHON" 11 | python3 queens.py gurobi 12 | mv queens-mip-gurobi.csv queens-mip-grb-cpython.csv 13 | 14 | echo "Benchmarking n-Queens CBC Python-MIP Pypy" 15 | pypy3 queens.py cbc 16 | mv queens-mip-cbc.csv queens-mip-cbc-pypy.csv 17 | 18 | echo "Benchmarking n-Queens Gurobi Python-MIP Pypy" 19 | pypy3 queens.py gurobi 20 | mv queens-mip-gurobi.csv queens-mip-grb-pypy.csv 21 | 22 | echo "Benchmarking n-Queens Gurobi" 23 | python3 queens-gurobi.py 24 | 25 | echo "Benchmarking n-Queens Pulp CPYTHON" 26 | python3 queens-pulp.py 27 | mv queens-pulp.csv queens-pulp-cpython.csv 28 | 29 | echo "Benchmarking n-Queens Pulp Pypy" 30 | pypy3 queens-pulp.py 31 | mv queens-pulp.csv queens-pulp-pypy.csv 32 | 33 | rm -f rcpsp-mip-cbc-cpython.csv rcpsp-mip-grb-cpython.csv rcpsp-mip-cbc-pypy.csv rcpsp-mip-grb-pypy.csv 34 | for solver in cbc gurobi; 35 | do 36 | echo "Benchmarking RCPSP $solver" 37 | python3 rcpsp.py ./data/rcpsp/j301_1.sm $solver 20 >> rcpsp-mip-$solver-cpython.csv 38 | pypy3 rcpsp.py ./data/rcpsp/j301_1.sm $solver 20 >> rcpsp-mip-$solver-pypy.csv 39 | python3 rcpsp.py ./data/rcpsp/j601_1.sm $solver 2 >> rcpsp-mip-$solver-cpython.csv 40 | pypy3 rcpsp.py ./data/rcpsp/j601_1.sm $solver 2 >> rcpsp-mip-$solver-pypy.csv 41 | python3 rcpsp.py ./data/rcpsp/j1201_1.sm $solver 1 >> rcpsp-mip-$solver-cpython.csv 42 | pypy3 rcpsp.py ./data/rcpsp/j1201_1.sm $solver 1 >> rcpsp-mip-$solver-pypy.csv 43 | done 44 | mv rcpsp-mip-gurobi-cpython.csv rcpsp-mip-grb-cpython.csv 45 | mv rcpsp-mip-gurobi-pypy.csv rcpsp-mip-grb-pypy.csv 46 | 47 | 48 | rm -f bmcp-mip-grb-cpython.csv bmcp-mip-grb-pypy.csv bmcp-mip-cbc-cpython.csv bmcp-mip-cbc-pypy.csv 49 | for inst in ./data/bmcp/*.col; 50 | do 51 | for solver in cbc gurobi; 52 | do 53 | echo "Benchmarking BMCP instance $inst with solver $solver and cpython" 54 | python3 bmcp.py $inst $solver | grep RRR | cut -d ':' -f 2 >> bmcp-mip-$solver-cpython.csv 55 | echo "Benchmarking BMCP instance $inst with solver $solver and pypy" 56 | pypy3 bmcp.py $inst $solver | grep RRR | cut -d ':' -f 2 >> bmcp-mip-$solver-pypy.csv 57 | done 58 | done 59 | mv bmcp-mip-gurobi-pypy.csv mv bmcp-mip-grb-pypy.csv 60 | mv bmcp-mip-gurobi-cpython.csv mv bmcp-mip-grb-cpython.csv 61 | 62 | 63 | pypy3 summarize.py 64 | 65 | txt2tags -t tex bench-results.t2t 66 | txt2tags -t rst bench-results.t2t 67 | 68 | -------------------------------------------------------------------------------- /benchmarks/bmcp.py: -------------------------------------------------------------------------------- 1 | """Bandwidth multi coloring example 2 | Frequency assignment problem as described here: 3 | http://fap.zib.de/problems/Philadelphia/ 4 | 5 | to solve P1 instance (included in the examples) call python bmcp.py P1.col 6 | """ 7 | 8 | from os.path import basename 9 | from itertools import product 10 | from sys import argv 11 | from time import time 12 | import bmcp_data 13 | from mip import Model, xsum, minimize, MINIMIZE, BINARY 14 | 15 | data = bmcp_data.read(argv[1]) 16 | ncol = int(argv[3]) 17 | N, r, d = data.N, data.r, data.d 18 | U = list(range(ncol)) 19 | 20 | st = time() 21 | m = Model(solver_name=argv[2]) 22 | 23 | x = [ 24 | [m.add_var("x({},{})".format(i, c), var_type=BINARY) for c in U] for i in N 25 | ] 26 | 27 | z = m.add_var("z") 28 | m.objective = minimize(z) 29 | 30 | for i in N: 31 | m += xsum(x[i][c] for c in U) == r[i] 32 | 33 | for i, j, c1, c2 in product(N, N, U, U): 34 | if i != j and c1 <= c2 < c1 + d[i][j]: 35 | m += x[i][c1] + x[j][c2] <= 1 36 | 37 | for i, c1, c2 in product(N, U, U): 38 | if c1 < c2 < c1 + d[i][i]: 39 | m += x[i][c1] + x[i][c2] <= 1 40 | 41 | for i, c in product(N, U): 42 | m += z >= (c + 1) * x[i][c] 43 | ed = time() 44 | 45 | inst = basename(argv[1]) 46 | print("RRR:%s,%g" % (inst, ed - st)) 47 | # m.start = [(x[i][c], 1.0) for i in N for c in C[i]] 48 | 49 | # m.optimize(max_seconds=100) 50 | 51 | # C = [[c for c in U if x[i][c] >= 0.99] for i in N] 52 | # print(C) 53 | -------------------------------------------------------------------------------- /benchmarks/bmcp_data.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Reads instance data for the bandwidth multicoloring problem 3 | in the .col format 4 | 5 | Created on May 20, 2019 6 | 7 | @author: haroldo 8 | ''' 9 | 10 | from collections import defaultdict 11 | from typing import Tuple, List, DefaultDict 12 | 13 | 14 | class BMCPData: 15 | def __init__(self, 16 | N: List[int], 17 | r: List[int], 18 | d: List[DefaultDict[int, int]]): 19 | self.N = N # node list 20 | self.r = r # required channels per node 21 | self.d = d # distances matrix, d[i][j] indicates the minimum 22 | # distance between nodes i and j 23 | 24 | 25 | def read(file_name: str) -> \ 26 | BMCPData: 27 | """reads a Bandwidth Multicoloring Problem instance 28 | """ 29 | n, m = 0, 0 30 | f = open(file_name, 'r') 31 | for line in f: 32 | line = line.rstrip().lstrip().lower() 33 | line = ' '.join(line.split()) 34 | lc = line.split(' ') 35 | 36 | if lc[0] == 'p': 37 | n, m = int(lc[2]), int(lc[3]) 38 | d = [defaultdict(int) for i in range(n)] 39 | r = [int(1) for i in range(n)] 40 | elif lc[0] == 'e': 41 | u, v, w = int(lc[1])-1, int(lc[2])-1, int(lc[3]) 42 | d[u][v] = w 43 | d[v][u] = w 44 | elif lc[0] == 'n': 45 | r[int(lc[1])-1] = int(lc[2]) 46 | 47 | f.close() 48 | N = [i for i in range(n)] 49 | data = BMCPData(N, r, d) 50 | return data 51 | -------------------------------------------------------------------------------- /benchmarks/bmcp_sol.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on May 20, 2019 3 | 4 | @author: haroldo 5 | ''' 6 | 7 | from collections import defaultdict 8 | from typing import List, DefaultDict, Tuple 9 | from itertools import product 10 | from bmcp_data import BMCPData 11 | 12 | class BMCPSol(): 13 | """ 14 | Bandwidth Multi Coloring Problem 15 | """ 16 | 17 | def __init__(self, 18 | data: BMCPData): # distance adjacency lists 19 | # instance data 20 | self.data = data 21 | 22 | # solution 23 | self.C = [[] for i in self.data.N] 24 | self.u_max = 0 25 | 26 | def allocate(self, i: int, c: int): 27 | """allocated color c to node i""" 28 | self.C[i].append(c) 29 | self.u_max = max(self.u_max, c) 30 | 31 | def available_color(self, i: int) -> int: 32 | """ returns the next available color for node i """ 33 | ac = 0 34 | available = False 35 | has_conflict = False 36 | d, C = self.data.d, self.C 37 | while available is False: 38 | for (v, dist) in d[i].items(): 39 | for c in C[v]: 40 | if abs(ac-c) < dist: 41 | available = False 42 | ac += 1 43 | has_conflict = True 44 | break 45 | if has_conflict: 46 | break 47 | if has_conflict: 48 | has_conflict = False 49 | continue 50 | 51 | available = True 52 | 53 | return ac 54 | 55 | def __str__(self) -> str: 56 | N, C, u_max = self.data.N, self.C, self.u_max 57 | result = '{} different colors used in the solution:\n'.format(u_max+1) 58 | for node in N: 59 | result += '\t[{}]'.format(node+1) 60 | for color in C[node]: 61 | result += ' {}'.format(color+1) 62 | result += '\n' 63 | 64 | return result 65 | -------------------------------------------------------------------------------- /benchmarks/data/bmcp/GEOM30.col: -------------------------------------------------------------------------------- 1 | c Geometric graph with bandwidth and node weights 2 | c Parameters: Vertices 30, Max node weight 10, Max edge weight 10 3 | c Maximum squared distance for edge (in 10,000 by 10,000 square) 5000000 4 | p band 30 80 5 | e 1 1 10 6 | e 1 2 6 7 | e 1 3 2 8 | e 2 2 10 9 | e 2 3 7 10 | e 2 23 5 11 | e 2 30 5 12 | e 3 3 10 13 | e 3 23 9 14 | e 3 25 3 15 | e 3 30 7 16 | e 4 4 10 17 | e 4 6 9 18 | e 4 7 3 19 | e 4 12 8 20 | e 4 18 7 21 | e 4 27 7 22 | e 5 5 10 23 | e 5 15 9 24 | e 5 21 8 25 | e 6 6 10 26 | e 6 7 4 27 | e 6 12 6 28 | e 6 18 6 29 | e 6 27 6 30 | e 7 7 10 31 | e 7 12 3 32 | e 7 18 5 33 | e 7 27 5 34 | e 8 8 10 35 | e 8 13 4 36 | e 8 21 3 37 | e 8 29 2 38 | e 9 9 10 39 | e 9 10 6 40 | e 10 10 10 41 | e 11 11 10 42 | e 11 22 7 43 | e 11 24 4 44 | e 12 12 10 45 | e 12 18 9 46 | e 12 27 9 47 | e 13 13 10 48 | e 13 17 2 49 | e 13 29 6 50 | e 14 14 10 51 | e 14 19 2 52 | e 14 20 7 53 | e 14 24 1 54 | e 14 25 6 55 | e 14 26 6 56 | e 15 15 10 57 | e 15 21 6 58 | e 16 16 10 59 | e 16 28 8 60 | e 17 17 10 61 | e 17 29 7 62 | e 18 18 10 63 | e 18 27 9 64 | e 19 19 10 65 | e 19 20 5 66 | e 20 20 10 67 | e 20 25 6 68 | e 20 30 3 69 | e 21 21 10 70 | e 22 22 10 71 | e 22 28 3 72 | e 23 23 10 73 | e 23 24 2 74 | e 23 25 5 75 | e 23 30 7 76 | e 24 24 10 77 | e 24 25 6 78 | e 25 25 10 79 | e 25 30 5 80 | e 26 26 10 81 | e 27 27 10 82 | e 28 28 10 83 | e 29 29 10 84 | e 30 30 10 85 | n 1 3 86 | n 2 3 87 | n 3 1 88 | n 4 4 89 | n 5 5 90 | n 6 4 91 | n 7 3 92 | n 8 5 93 | n 9 7 94 | n 10 3 95 | n 11 10 96 | n 12 2 97 | n 13 3 98 | n 14 5 99 | n 15 9 100 | n 16 1 101 | n 17 2 102 | n 18 5 103 | n 19 7 104 | n 20 10 105 | n 21 1 106 | n 22 4 107 | n 23 3 108 | n 24 3 109 | n 25 4 110 | n 26 7 111 | n 27 8 112 | n 28 5 113 | n 29 8 114 | n 30 8 115 | -------------------------------------------------------------------------------- /benchmarks/data/bmcp/colors.csv: -------------------------------------------------------------------------------- 1 | GEOM20.col,199 2 | GEOM30.col,214 3 | GEOM40.col,224 4 | GEOM50.col,271 5 | GEOM60.col,303 6 | GEOM70.col,371 7 | GEOM80.col,523 8 | GEOM90.col,422 9 | GEOM100.col,506 10 | GEOM110.col,505 11 | GEOM120.col,517 12 | -------------------------------------------------------------------------------- /benchmarks/queens-gurobi.py: -------------------------------------------------------------------------------- 1 | from gurobipy import * 2 | from sys import stdout 3 | import time 4 | # from time import process_time 5 | import timeout_decorator 6 | 7 | N = range(100, 1001, 100) 8 | 9 | TIMEOUT = 1000 10 | execTime = TIMEOUT 11 | modelCols = 0 12 | modelRows = 0 13 | modelNz = 0 14 | 15 | 16 | @timeout_decorator.timeout(TIMEOUT) 17 | def gen_model(n): 18 | global execTime 19 | global modelCols 20 | global modelRows 21 | global modelNz 22 | execTime = TIMEOUT 23 | modelCols = 0 24 | modelRows = 0 25 | modelNz = 0 26 | 27 | st = time.time() 28 | queens = Model('queens') 29 | 30 | x = [[queens.addVar(name='x({},{})'.format(i, j), vtype='B', obj=-1) 31 | for j in range(n)] for i in range(n)] 32 | 33 | # one per row 34 | for i in range(n): 35 | queens.addConstr(quicksum(x[i][j] for j in range(n)) == 1, 36 | name='row({})'.format(i)) 37 | 38 | # one per column 39 | for j in range(n): 40 | queens.addConstr(quicksum(x[i][j] for i in range(n)) == 1, 41 | name='col({})'.format(j)) 42 | 43 | # diagonal \ 44 | for p, k in enumerate(range(2 - n, n - 2 + 1)): 45 | queens.addConstr(quicksum(x[i][j] for i in range(n) for j in range(n) 46 | if i - j == k) <= 1, name='diag1({})'.format(p)) 47 | 48 | # diagonal / 49 | for p, k in enumerate(range(3, n + n)): 50 | queens.addConstr(quicksum(x[i][j] for i in range(n) for j in range(n) 51 | if i + j == k) <= 1, name='diag2({})'.format(p)) 52 | 53 | ed = time.time() 54 | 55 | execTime = ed-st 56 | modelCols = queens.NumVars 57 | modelRows = queens.NumConstrs 58 | 59 | 60 | f = open('queens-gurobi-cpython.csv', 'w') 61 | 62 | for n in N: 63 | gen_model(n) 64 | f.write('{},{},{:.4f}\n'.format(n, 'gurobi', execTime)) 65 | f.flush() 66 | 67 | f.close() 68 | -------------------------------------------------------------------------------- /benchmarks/queens-jump.csv: -------------------------------------------------------------------------------- 1 | 10000.0,594.0,0.0,2.38271 2 | 40000.0,1194.0,0.0,0.25211 3 | 90000.0,1794.0,0.0,0.46817 4 | 160000.0,2394.0,0.0,1.11335 5 | 250000.0,2994.0,0.0,2.08544 6 | 360000.0,3594.0,0.0,2.86025 7 | 490000.0,4194.0,0.0,3.6399 8 | 640000.0,4794.0,0.0,5.58317 9 | 810000.0,5394.0,0.0,8.07987 10 | 1.0e6,5994.0,0.0,10.01954 11 | -------------------------------------------------------------------------------- /benchmarks/queens-pulp.py: -------------------------------------------------------------------------------- 1 | from pulp import * 2 | from sys import stdout 3 | from time import process_time 4 | import time 5 | import timeout_decorator 6 | 7 | N = range(100, 1001, 100) 8 | 9 | f = open('queens-pulp.csv', 'w') 10 | 11 | TIMEOUT = 1000 12 | execTime = TIMEOUT 13 | modelCols = 0 14 | modelRows = 0 15 | modelNz = 0 16 | 17 | 18 | @timeout_decorator.timeout(TIMEOUT) 19 | def gen_model(n): 20 | global execTime 21 | global modelCols 22 | global modelRows 23 | global modelNz 24 | execTime = TIMEOUT 25 | modelCols = 0 26 | modelRows = 0 27 | modelNz = 0 28 | st = time.time() 29 | queens = LpProblem('queens', LpMinimize) 30 | 31 | x = [[LpVariable('x({},{})'.format(i, j), 0, 1, 'Binary') 32 | for j in range(n)] for i in range(n)] 33 | 34 | # one per row 35 | for i in range(n): 36 | queens += lpSum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i) 37 | 38 | # one per column 39 | for j in range(n): 40 | queens += lpSum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j) 41 | 42 | # diagonal \ 43 | for p, k in enumerate(range(2 - n, n - 2 + 1)): 44 | queens += lpSum(x[i][j] for i in range(n) for j in range(n) 45 | if i - j == k) <= 1, 'diag1({})'.format(p) 46 | 47 | # diagonal / 48 | for p, k in enumerate(range(3, n + n)): 49 | queens += lpSum(x[i][j] for i in range(n) for j in range(n) 50 | if i + j == k) <= 1, 'diag2({})'.format(p) 51 | 52 | ed = time.time() 53 | execTime = ed-st 54 | modelCols = queens.numVariables() 55 | modelRows = queens.numConstraints() 56 | 57 | 58 | for n in N: 59 | gen_model(n) 60 | f.write('{},{},{:.4f}\n'.format(n, 'pulp', execTime)) 61 | f.flush() 62 | 63 | f.close() 64 | -------------------------------------------------------------------------------- /benchmarks/queens.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/benchmarks/queens.ods -------------------------------------------------------------------------------- /benchmarks/queens.py: -------------------------------------------------------------------------------- 1 | from mip.model import * 2 | from sys import stdout, argv 3 | from time import process_time 4 | import time 5 | import timeout_decorator 6 | import os 7 | 8 | # import vmprof 9 | 10 | N = range(100, 1001, 100) 11 | 12 | TIMEOUT = 1000 13 | execTime = TIMEOUT 14 | modelCols = 0 15 | modelRows = 0 16 | modelNz = 0 17 | 18 | 19 | @timeout_decorator.timeout(TIMEOUT) 20 | def gen_model(n, solver, f): 21 | global execTime 22 | global modelCols 23 | global modelRows 24 | global modelNz 25 | execTime = TIMEOUT 26 | modelCols = 0 27 | modelRows = 0 28 | modelNz = 0 29 | st = time.time() 30 | queens = Model("queens", solver_name=solver) 31 | 32 | x = [ 33 | [ 34 | queens.add_var("x({},{})".format(i, j), var_type="B", obj=-1.0) 35 | for j in range(n) 36 | ] 37 | for i in range(n) 38 | ] 39 | 40 | # one per row 41 | for i in range(n): 42 | queens.add_constr( 43 | xsum(x[i][j] for j in range(n)) == 1, "row({})".format(i) 44 | ) 45 | 46 | # one per column 47 | for j in range(n): 48 | queens.add_constr( 49 | xsum(x[i][j] for i in range(n)) == 1, "col({})".format(j) 50 | ) 51 | 52 | # diagonal \ 53 | for p, k in enumerate(range(2 - n, n - 2 + 1)): 54 | queens.add_constr( 55 | xsum(x[i][j] for i in range(n) for j in range(n) if i - j == k) 56 | <= 1, 57 | "diag1({})".format(p), 58 | ) 59 | 60 | # diagonal / 61 | for p, k in enumerate(range(3, n + n)): 62 | queens.add_constr( 63 | xsum(x[i][j] for i in range(n) for j in range(n) if i + j == k) 64 | <= 1, 65 | "diag2({})".format(p), 66 | ) 67 | 68 | ed = time.time() 69 | execTime = ed - st 70 | modelCols = queens.num_cols 71 | modelRows = queens.num_rows 72 | modelNz = queens.num_nz 73 | 74 | 75 | f = open("queens-mip-{}.csv".format(argv[1]), "w") 76 | 77 | # PROFILE_FILE = 'queens-mip-{}.dat'.format(argv[1]) 78 | # flags = os.O_RDWR | os.O_CREAT | os.O_TRUNC 79 | # outfd = os.open(PROFILE_FILE, flags) 80 | # vmprof.enable(outfd, period=0.01) 81 | 82 | for n in N: 83 | gen_model(n, argv[1], f) 84 | f.write( 85 | "{},{},{},{},{:.4f}\n".format( 86 | n, modelCols, modelRows, modelNz, execTime 87 | ) 88 | ) 89 | f.flush() 90 | f.close() 91 | 92 | # vmprof.disable() 93 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = -n -E 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = . 8 | BUILDDIR = _build 9 | 10 | all: 11 | make latexpdf 12 | 13 | # Put it first so that "make" without argument is like "make help". 14 | help: 15 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 16 | 17 | .PHONY: help Makefile 18 | 19 | # Catch-all target: route all unknown targets to Sphinx using the new 20 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 21 | %: Makefile 22 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 23 | -------------------------------------------------------------------------------- /docs/classes.rst: -------------------------------------------------------------------------------- 1 | Classes 2 | ======= 3 | 4 | .. _chapClasses: 5 | 6 | .. automodule:: mip.callbacks 7 | .. automodule:: mip.model 8 | 9 | Model 10 | ----- 11 | 12 | .. autoclass:: mip.Model 13 | :members: 14 | 15 | LinExpr 16 | ------- 17 | .. autoclass:: mip.LinExpr 18 | :members: 19 | 20 | LinExprTensor 21 | ------------- 22 | .. autoclass:: mip.LinExprTensor 23 | :members: 24 | 25 | Var 26 | --- 27 | .. autoclass:: mip.Var 28 | :members: 29 | 30 | Constr 31 | ------ 32 | .. autoclass:: mip.Constr 33 | :members: 34 | 35 | Column 36 | ------ 37 | .. autoclass:: mip.Column 38 | :members: 39 | 40 | ConflictGraph 41 | ------------- 42 | .. autoclass:: mip.ConflictGraph 43 | :members: 44 | 45 | VarList 46 | ------- 47 | .. autoclass:: mip.VarList 48 | :members: 49 | 50 | ConstrList 51 | ---------- 52 | .. autoclass:: mip.ConstrList 53 | :members: 54 | 55 | ConstrsGenerator 56 | ---------------- 57 | .. autoclass:: mip.ConstrsGenerator 58 | :members: 59 | 60 | IncumbentUpdater 61 | ---------------- 62 | .. autoclass:: mip.IncumbentUpdater 63 | :members: 64 | 65 | CutType 66 | -------- 67 | .. autoclass:: mip.CutType 68 | :members: 69 | 70 | CutPool 71 | ------- 72 | .. autoclass:: mip.CutPool 73 | :members: 74 | 75 | OptimizationStatus 76 | ------------------ 77 | .. autoclass:: mip.OptimizationStatus 78 | :members: 79 | 80 | SearchEmphasis 81 | -------------- 82 | .. autoclass:: mip.SearchEmphasis 83 | :members: 84 | 85 | LP_Method 86 | --------- 87 | .. autoclass:: mip.LP_Method 88 | :members: 89 | 90 | 91 | 92 | ProgressLog 93 | ----------- 94 | .. autoclass:: mip.ProgressLog 95 | :members: 96 | 97 | Exceptions 98 | ----------- 99 | 100 | .. autoclass:: mip.MipBaseException 101 | .. autoclass:: mip.ProgrammingError 102 | .. autoclass:: mip.InterfacingError 103 | .. autoclass:: mip.InvalidLinExpr 104 | .. autoclass:: mip.InvalidParameter 105 | .. autoclass:: mip.ParameterNotAvailable 106 | .. autoclass:: mip.InfeasibleSolution 107 | .. autoclass:: mip.SolutionNotAvailable 108 | 109 | Useful functions 110 | ---------------- 111 | 112 | .. autofunction:: mip.minimize 113 | .. autofunction:: mip.maximize 114 | .. autofunction:: mip.xsum 115 | .. autofunction:: mip.compute_features 116 | .. autofunction:: mip.features 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/coin-or-cup/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # haroldo, 2019-09-19 14:28 4 | # 5 | 6 | all: 7 | pdflatex -shell-escape c-cup 8 | bibtex c-cup 9 | pdflatex -shell-escape c-cup 10 | pdflatex -shell-escape c-cup 11 | 12 | 13 | # vim:ft=make 14 | # 15 | -------------------------------------------------------------------------------- /docs/coin-or-cup/c-cup.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/coin-or-cup/c-cup.pdf -------------------------------------------------------------------------------- /docs/coin-or-cup/references.bib: -------------------------------------------------------------------------------- 1 | @article{Mitchell2009, 2 | author = {Mitchell, Stuart}, 3 | journal = {Python Papers Monograph}, 4 | number = {14}, 5 | title = {{An Introduction to PuLP for Python Programmers}}, 6 | volume = {1}, 7 | year = {2009} 8 | } 9 | 10 | @article{Towhidi2016, 11 | author = {Towhidi, Mehdi and Orban, Dominique}, 12 | journal = {Mathematical Programming Computation}, 13 | number = {4}, 14 | pages = {377--391}, 15 | title = {{Customizing the solution process of COIN-OR's linear solvers with Python}}, 16 | volume = {8}, 17 | year = {2016} 18 | } 19 | 20 | @article{Dunning2015, 21 | author = {Dunning, Iain and Huchette, Joey and Lubin, Miles}, 22 | journal = {SIAM Review}, 23 | number = {2}, 24 | pages = {295--320}, 25 | title = {{JuMP: A Modeling Language for Mathematical Optimization}}, 26 | volume = {59}, 27 | year = {2017} 28 | } 29 | 30 | @book{Fourer1987, 31 | author = {Fourer, Robert and Gay, David and Kernighan, Brian}, 32 | publisher = {AT {\&} T Bell Laboratories}, 33 | title = {{AMPL: A mathematical programming language}}, 34 | year = {1987} 35 | } 36 | 37 | @article{Bixby2002, 38 | author = {Bixby, Robert E.}, 39 | journal = {Operations Research}, 40 | number = {1}, 41 | pages = {3--15}, 42 | title = {{Solving real-world linear programs: A decade and more of progress}}, 43 | volume = {50}, 44 | year = {2002} 45 | } 46 | 47 | @article{Miller1960, 48 | author = {Miller, C. E. and Tucker, A. W. and Zemlin, R. A.}, 49 | file = {:home/haroldo/Documentos/IntegerProgramming/apps/Integer Programming Formulations of Traveling Salesman Problems.pdf:pdf}, 50 | issn = {1557735X}, 51 | journal = {Journal of the ACM (JACM)}, 52 | number = {4}, 53 | pages = {326--329}, 54 | title = {{Integer Programming Formulation of Traveling Salesman Problems}}, 55 | volume = {7}, 56 | year = {1960} 57 | } 58 | 59 | @article{Econ2018, 60 | title = "Python has brought computer programming to a vast new audience", 61 | journal = "The Economist", 62 | month = "July", 63 | year = "2018", 64 | url = "\url{https://www.economist.com/graphic-detail/2018/07/26/python-is-becoming-the-worlds-most-popular-coding-language}" 65 | } 66 | -------------------------------------------------------------------------------- /docs/extern.rst: -------------------------------------------------------------------------------- 1 | .. _chapExternal: 2 | 3 | External Documentation/Examples 4 | =============================== 5 | 6 | This section includes links for external documentation and examples. Some 7 | documents provide information on how to integrate Python-MIP with 8 | other Python tools. 9 | 10 | - `Network-constrained Transportation Problem. `_: provides a notebook for solving a transportation problem and integrating with `Pysal `_, by James D. Gaboardi. 11 | 12 | .. image:: ./images/notebooks_transportation-problem_48_0.png 13 | :width: 60% 14 | :align: center 15 | 16 | - `How to choose stocks to invest in with Python `_, by Khuyen Tran, includes an example of building an optimal multi-year investment plan in Python-MIP. 17 | 18 | - `Solving a Quadratic Problem `_, by `pabloazurduy `_. 19 | 20 | .. image:: ./images/quadratic_function_discrete.png 21 | :width: 40% 22 | :align: center 23 | 24 | - `Formulation for the Vehicle Routing Problem with Time Windows (VRPTW) `__, by Krishnendu Mukherjee, includes a model for the VRPTW coded in Python-MIP. 25 | -------------------------------------------------------------------------------- /docs/images/2dlp.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/2dlp.odg -------------------------------------------------------------------------------- /docs/images/2dlp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/2dlp.pdf -------------------------------------------------------------------------------- /docs/images/belgium-tourism-14-opt-547.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/belgium-tourism-14-opt-547.png -------------------------------------------------------------------------------- /docs/images/belgium-tourism-14-subtour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/belgium-tourism-14-subtour.png -------------------------------------------------------------------------------- /docs/images/belgium-tourism-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/belgium-tourism-14.png -------------------------------------------------------------------------------- /docs/images/bmcpsmall.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/bmcpsmall.pdf -------------------------------------------------------------------------------- /docs/images/bmcpsmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/bmcpsmall.png -------------------------------------------------------------------------------- /docs/images/coin-or-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/coin-or-logo.png -------------------------------------------------------------------------------- /docs/images/jssp1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/jssp1.pdf -------------------------------------------------------------------------------- /docs/images/jssp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/jssp1.png -------------------------------------------------------------------------------- /docs/images/jssp2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/jssp2.pdf -------------------------------------------------------------------------------- /docs/images/jssp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/jssp2.png -------------------------------------------------------------------------------- /docs/images/location-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/location-sol.pdf -------------------------------------------------------------------------------- /docs/images/location-sol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/location-sol.png -------------------------------------------------------------------------------- /docs/images/location.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/location.pdf -------------------------------------------------------------------------------- /docs/images/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/location.png -------------------------------------------------------------------------------- /docs/images/log_cost.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/log_cost.pdf -------------------------------------------------------------------------------- /docs/images/log_cost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/log_cost.png -------------------------------------------------------------------------------- /docs/images/notebooks_transportation-problem_48_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/notebooks_transportation-problem_48_0.png -------------------------------------------------------------------------------- /docs/images/philadelphia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/philadelphia.png -------------------------------------------------------------------------------- /docs/images/quadratic_function_discrete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/quadratic_function_discrete.png -------------------------------------------------------------------------------- /docs/images/rcpsp-opt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/rcpsp-opt.pdf -------------------------------------------------------------------------------- /docs/images/rcpsp-opt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/rcpsp-opt.png -------------------------------------------------------------------------------- /docs/images/rcpsp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/rcpsp.pdf -------------------------------------------------------------------------------- /docs/images/rcpsp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/rcpsp.png -------------------------------------------------------------------------------- /docs/images/roll.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/roll.pdf -------------------------------------------------------------------------------- /docs/images/roll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/roll.png -------------------------------------------------------------------------------- /docs/images/tdlpp-instance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tdlpp-instance.pdf -------------------------------------------------------------------------------- /docs/images/tdlpp-instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tdlpp-instance.png -------------------------------------------------------------------------------- /docs/images/tspC.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspC.pdf -------------------------------------------------------------------------------- /docs/images/tspC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspC.png -------------------------------------------------------------------------------- /docs/images/tspG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspG.pdf -------------------------------------------------------------------------------- /docs/images/tspG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspG.png -------------------------------------------------------------------------------- /docs/images/tspNo2Sub.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspNo2Sub.pdf -------------------------------------------------------------------------------- /docs/images/tspNo2Sub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspNo2Sub.png -------------------------------------------------------------------------------- /docs/images/tspRoot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspRoot.pdf -------------------------------------------------------------------------------- /docs/images/tspRoot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspRoot.png -------------------------------------------------------------------------------- /docs/images/tspSt1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspSt1.pdf -------------------------------------------------------------------------------- /docs/images/tspSt1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/images/tspSt1.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Python MIP Documentation 2 | ============================================================ 3 | 4 | .. toctree:: 5 | :maxdepth: 3 6 | :caption: Contents: 7 | 8 | intro 9 | install 10 | quickstart 11 | examples 12 | sos 13 | custom 14 | bench 15 | extern 16 | classes 17 | bibliography 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/plot_log.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | t = np.arange(0.000001, 150, 0.01) 5 | s = np.log(t) 6 | for i in range(len(s)): 7 | s[i] = max(0, s[i]*1520) 8 | 9 | print('s:') 10 | print(s) 11 | 12 | plt.plot(t, s, color='orange') 13 | 14 | d = [0, 10, 30, 70, 150] 15 | f = [round(1520*np.log(x), 3) if x > 0 else 0 for x in d] 16 | 17 | 18 | print(d) 19 | print(f) 20 | 21 | for x, y in zip(d, f): 22 | plt.scatter(x, y, marker='^', color = 'darkgreen') 23 | print('x {} y {}'.format(x, y)) 24 | plt.plot( [x, x], [0, y], ':', color='gray' ) 25 | 26 | 27 | plt.plot( d, f, color='darkgray' ) 28 | #plt.plot( [0, 10], [0, np.log(10)], color='darkgray' ) 29 | 30 | 31 | #plt.ylim(-0.01,5) 32 | plt.show() 33 | -------------------------------------------------------------------------------- /docs/podes/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # haroldo, 2019-09-20 21:20 4 | # 5 | 6 | all: 7 | pdflatex -shell-escape python-mip-tutorial-podes ; bibtex python-mip-tutorial-podes ; pdflatex -shell-escape python-mip-tutorial-podes ; pdflatex -shell-escape python-mip-tutorial-podes 8 | 9 | 10 | # vim:ft=make 11 | # 12 | -------------------------------------------------------------------------------- /docs/podes/belgium-tourism-14-subtour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/podes/belgium-tourism-14-subtour.png -------------------------------------------------------------------------------- /docs/podes/logoSobrapo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/podes/logoSobrapo.pdf -------------------------------------------------------------------------------- /docs/python-mip_theme/__init__.py: -------------------------------------------------------------------------------- 1 | # import os 2 | # import re 3 | 4 | # from sphinx.util.compat import Directive 5 | 6 | 7 | # HTML_THEME_PATH = [os.path.abspath(os.path.join(os.path.dirname(__file__), 8 | # '..'))] 9 | 10 | 11 | # # Storage for SEO descriptions. 12 | # seo_descriptions = {} 13 | 14 | # class SeoDescription(Directive): 15 | # """ 16 | # This directive merely saves it's contents to the seo_descriptions dict 17 | # under the document name key. 18 | # """ 19 | 20 | # # this enables content in the directive 21 | # has_content = True 22 | 23 | # def run(self): 24 | # # Save the last SEO description for a page. 25 | # seo_descriptions[self.state.document.settings.env.docname] = ' '.join(self.content) 26 | # # Must return a list of nodes. 27 | # return [] 28 | 29 | 30 | # def tt2nav(toctree, klass=None, appendix=None, divider=False): 31 | # """ 32 | # Injects ``has-dropdown`` and ``dropdown`` classes to HTML 33 | # generated by the :func:`toctree` function. 34 | 35 | # :param str toctree: 36 | # HTML generated by the :func:`toctree` function. 37 | # """ 38 | 39 | # tt = toctree 40 | # divider = '
  • ' if divider else '' 41 | 42 | # # Append anything just before the closing . 43 | # if appendix: 44 | # tt = re.sub(r'($)', r'{}\1'.format(appendix), tt) 45 | 46 | # # Add class attribute to all
      elements. 47 | # tt = re.sub(r'
        ', r'
          ', tt) 48 | 49 | # # Add class to first
            tag. 50 | # if klass: 51 | # tt = re.sub(r'(^ tags with "current" class. 54 | # # tt = re.sub(r'( that contains
              . 57 | # pattern = r'(]*>[^<]*]*>[^<]*[^<]* 100) { 16 | $('.back-to-top').fadeIn('slow'); 17 | } else { 18 | $('.back-to-top').fadeOut('slow'); 19 | } 20 | }); 21 | $('.back-to-top').click(function () { 22 | $('html, body').animate({ scrollTop: 0 }, 1500, 'easeInOutExpo'); 23 | return false; 24 | }); 25 | 26 | // Initiate the wowjs animation library 27 | new WOW().init(); 28 | 29 | // Header scroll class 30 | $(window).scroll(function () { 31 | if ($(this).scrollTop() > 100) { 32 | $('#header').addClass('header-scrolled'); 33 | } else { 34 | $('#header').removeClass('header-scrolled'); 35 | } 36 | }); 37 | 38 | if ($(window).scrollTop() > 100) { 39 | $('#header').addClass('header-scrolled'); 40 | } 41 | 42 | // Smooth scroll for the navigation and links with .scrollto classes 43 | $('.main-nav a, .mobile-nav a, .scrollto, .reference, .internal').on('click', function () { 44 | if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { 45 | var target = $(this.hash); 46 | if (target.length) { 47 | var top_space = 0; 48 | 49 | if ($('#header').length) { 50 | top_space = $('#header').outerHeight(); 51 | 52 | if (!$('#header').hasClass('header-scrolled')) { 53 | top_space = top_space; 54 | } 55 | } 56 | 57 | $('html, body').animate({ 58 | scrollTop: target.offset().top - top_space 59 | }, 1000, 'easeInOutExpo'); 60 | 61 | if ($(this).parents('.main-nav, .mobile-nav').length) { 62 | $('.main-nav .active, .mobile-nav .active').removeClass('active'); 63 | $(this).closest('li').addClass('active'); 64 | } 65 | 66 | if ($('body').hasClass('mobile-nav-active')) { 67 | $('body').removeClass('mobile-nav-active'); 68 | $('.mobile-nav-toggle i').toggleClass('fa-times fa-bars'); 69 | $('.mobile-nav-overly').fadeOut(); 70 | } 71 | return false; 72 | } 73 | } 74 | }); 75 | })(jQuery); 76 | 77 | -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/easing/easing.min.js: -------------------------------------------------------------------------------- 1 | !function(n){"function"==typeof define&&define.amd?define(["jquery"],function(e){return n(e)}):"object"==typeof module&&"object"==typeof module.exports?exports=n(require("jquery")):n(jQuery)}(function(n){function e(n){var e=7.5625,t=2.75;return n<1/t?e*n*n:n<2/t?e*(n-=1.5/t)*n+.75:n<2.5/t?e*(n-=2.25/t)*n+.9375:e*(n-=2.625/t)*n+.984375}void 0!==n.easing&&(n.easing.jswing=n.easing.swing);var t=Math.pow,u=Math.sqrt,r=Math.sin,i=Math.cos,a=Math.PI,c=1.70158,o=1.525*c,s=2*a/3,f=2*a/4.5;n.extend(n.easing,{def:"easeOutQuad",swing:function(e){return n.easing[n.easing.def](e)},easeInQuad:function(n){return n*n},easeOutQuad:function(n){return 1-(1-n)*(1-n)},easeInOutQuad:function(n){return n<.5?2*n*n:1-t(-2*n+2,2)/2},easeInCubic:function(n){return n*n*n},easeOutCubic:function(n){return 1-t(1-n,3)},easeInOutCubic:function(n){return n<.5?4*n*n*n:1-t(-2*n+2,3)/2},easeInQuart:function(n){return n*n*n*n},easeOutQuart:function(n){return 1-t(1-n,4)},easeInOutQuart:function(n){return n<.5?8*n*n*n*n:1-t(-2*n+2,4)/2},easeInQuint:function(n){return n*n*n*n*n},easeOutQuint:function(n){return 1-t(1-n,5)},easeInOutQuint:function(n){return n<.5?16*n*n*n*n*n:1-t(-2*n+2,5)/2},easeInSine:function(n){return 1-i(n*a/2)},easeOutSine:function(n){return r(n*a/2)},easeInOutSine:function(n){return-(i(a*n)-1)/2},easeInExpo:function(n){return 0===n?0:t(2,10*n-10)},easeOutExpo:function(n){return 1===n?1:1-t(2,-10*n)},easeInOutExpo:function(n){return 0===n?0:1===n?1:n<.5?t(2,20*n-10)/2:(2-t(2,-20*n+10))/2},easeInCirc:function(n){return 1-u(1-t(n,2))},easeOutCirc:function(n){return u(1-t(n-1,2))},easeInOutCirc:function(n){return n<.5?(1-u(1-t(2*n,2)))/2:(u(1-t(-2*n+2,2))+1)/2},easeInElastic:function(n){return 0===n?0:1===n?1:-t(2,10*n-10)*r((10*n-10.75)*s)},easeOutElastic:function(n){return 0===n?0:1===n?1:t(2,-10*n)*r((10*n-.75)*s)+1},easeInOutElastic:function(n){return 0===n?0:1===n?1:n<.5?-(t(2,20*n-10)*r((20*n-11.125)*f))/2:t(2,-20*n+10)*r((20*n-11.125)*f)/2+1},easeInBack:function(n){return(c+1)*n*n*n-c*n*n},easeOutBack:function(n){return 1+(c+1)*t(n-1,3)+c*t(n-1,2)},easeInOutBack:function(n){return n<.5?t(2*n,2)*(7.189819*n-o)/2:(t(2*n-2,2)*((o+1)*(2*n-2)+o)+2)/2},easeInBounce:function(n){return 1-e(1-n)},easeOutBounce:e,easeInOutBounce:function(n){return n<.5?(1-e(1-2*n))/2:(1+e(2*n-1))/2}})}); 2 | -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.eot -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.ttf -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/docs/python-mip_theme/static/lib/ionicons/fonts/ionicons.woff -------------------------------------------------------------------------------- /docs/python-mip_theme/static/lib/mobile-nav/mobile-nav.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | "use strict"; 3 | 4 | // Mobile Navigation 5 | if ($('.main-nav').length) { 6 | var $mobile_nav = $('.main-nav').clone().prop({ 7 | class: 'mobile-nav d-lg-none' 8 | }); 9 | $('body').append($mobile_nav); 10 | $('body').prepend(''); 11 | $('body').append('
              '); 12 | 13 | $(document).on('click', '.mobile-nav-toggle', function(e) { 14 | $('body').toggleClass('mobile-nav-active'); 15 | $('.mobile-nav-toggle i').toggleClass('fa-times fa-bars'); 16 | $('.mobile-nav-overly').toggle(); 17 | }); 18 | 19 | $(document).on('click', '.mobile-nav .drop-down > a', function(e) { 20 | e.preventDefault(); 21 | $(this).next().slideToggle(300); 22 | $(this).parent().toggleClass('active'); 23 | }); 24 | 25 | $(document).click(function(e) { 26 | var container = $(".mobile-nav, .mobile-nav-toggle"); 27 | if (!container.is(e.target) && container.has(e.target).length === 0) { 28 | if ($('body').hasClass('mobile-nav-active')) { 29 | $('body').removeClass('mobile-nav-active'); 30 | $('.mobile-nav-toggle i').toggleClass('fa-times fa-bars'); 31 | $('.mobile-nav-overly').fadeOut(); 32 | } 33 | } 34 | }); 35 | } else if ($(".mobile-nav, .mobile-nav-toggle").length) { 36 | $(".mobile-nav, .mobile-nav-toggle").hide(); 37 | } 38 | 39 | })(jQuery); 40 | -------------------------------------------------------------------------------- /docs/python-mip_theme/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | pygments_style = sphinx 4 | stylesheet = css/styles.css 5 | 6 | [options] 7 | logo_mobile = 8 | logo_screen = 9 | motto = 10 | base_url = 11 | author = 12 | author_link = 13 | twitter_id = 14 | copyright_year = 15 | favicon = 16 | top_bar_force_fit = 17 | top_bar_content_title = Sections 18 | google_analytics_id = 19 | opengraph_tags = 20 | opengraph_image = 21 | meta_tags = 22 | social_buttons = 23 | facebook_app_id = 24 | google_plus_id = 25 | github_user = 26 | github_repo = 27 | github_ribbon_image = 28 | github_ribbon_position = right 29 | seo_description = 30 | flattr_id = 31 | flattr_title = 32 | flattr_description = 33 | flattr_tags = 34 | 35 | gray_1 = #444 36 | gray_2 = #EEE 37 | gray_3 = #AAA 38 | 39 | pink_1 = #FCC 40 | pink_2 = #FAA 41 | pink_3 = #D52C2C 42 | 43 | base_bg = #fff 44 | base_text = #000 45 | hr_border = #B1B4B6 46 | body_bg = 47 | body_text = #3E4349 48 | body_text_align = justify 49 | footer_text = #888 50 | link = #004B6B 51 | link_hover = #6D4100 52 | sidebar_header = 53 | sidebar_text = #555 54 | sidebar_link = 55 | sidebar_link_underscore = #999 56 | sidebar_search_button = #CCC 57 | sidebar_list = #000 58 | sidebar_hr = 59 | anchor = #DDD 60 | anchor_hover_fg = 61 | anchor_hover_bg = #EAEAEA 62 | table_border = #888 63 | shadow = 64 | 65 | # Admonition options 66 | ## basic level 67 | admonition_bg = 68 | admonition_border = #CCC 69 | note_bg = 70 | note_border = #CCC 71 | seealso_bg = 72 | seealso_border = #CCC 73 | 74 | ## critical level 75 | danger_bg = 76 | danger_border = 77 | danger_shadow = 78 | error_bg = 79 | error_border = 80 | error_shadow = 81 | 82 | ## normal level 83 | tip_bg = 84 | tip_border = #CCC 85 | hint_bg = 86 | hint_border = #CCC 87 | important_bg = 88 | important_border = #CCC 89 | 90 | ## warning level 91 | caution_bg = 92 | caution_border = 93 | attention_bg = 94 | attention_border = 95 | warn_bg = 96 | warn_border = 97 | 98 | topic_bg = 99 | code_highlight_bg = 100 | highlight_bg = #FAF3E8 101 | xref_border = #fff 102 | xref_bg = #FBFBFB 103 | admonition_xref_border = #fafafa 104 | admonition_xref_bg = 105 | footnote_bg = #FDFDFD 106 | footnote_border = 107 | pre_bg = 108 | narrow_sidebar_bg = #333 109 | narrow_sidebar_fg = #FFF 110 | narrow_sidebar_link = 111 | font_size = 16px 112 | caption_font_size = inherit 113 | viewcode_target_bg = #ffd 114 | code_bg = #ecf0f3 115 | code_text = #222 116 | code_hover = #EEE 117 | code_font_size = 0.8em 118 | code_font_family = 119 | font_family = Georgia, serif 120 | head_font_family = 121 | caption_font_family = inherit 122 | code_highlight = #FFC 123 | page_width = 124 | sidebar_width = 125 | relbar_border = 126 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx_autodoc_typehints 2 | cffi 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/sos.rst: -------------------------------------------------------------------------------- 1 | .. _chapSOS: 2 | 3 | Special Ordered Sets 4 | ==================== 5 | 6 | Special Ordered Sets (SOSs) are ordered sets of variables, where only one/two 7 | contiguous variables in this set can assume non-zero values. Introduced in [BeTo70]_, they provide powerful means of modeling nonconvex functions [BeFo76]_ and can improve the performance of the branch-and-bound algorithm. 8 | 9 | Type 1 SOS (S1): 10 | In this case, only one variable of the set can assume a non zero value. This variable may indicate, for example the site where a plant should be build. As the value of this non-zero variable would not have to be necessarily its upper bound, its value may also indicate the size of the plant. 11 | 12 | Type 2 SOS (S2): 13 | In this case, up to two consecutive variables in the set may assume non-zero values. S2 are specially useful to model piecewise linear approximations of non-linear functions. 14 | 15 | Given nonlinear function :math:`f(x)`, a linear approximation can be computed for a set of :math:`k` points :math:`x_1, x_2, \ldots, x_k`, using continuous variables :math:`w_1, w_2, \ldots, w_k`, with the following constraints: 16 | 17 | .. math:: 18 | 19 | \sum_{i=1}^{k} w_i & = 1 \\ 20 | \sum_{i=1}^{k} x_i \ldotp w_i & = x 21 | 22 | 23 | Thus, the result of :math:`f(x)` can be approximate in :math:`z`: 24 | 25 | .. math:: 26 | 27 | z = \sum_{i=1}^{k} f(x_i) \ldotp w_i 28 | 29 | 30 | Provided that at most two of the :math:`w_i` variables are allowed to be non-zero and they are adjacent, which can be ensured by adding the pairs (variables, weight) :math:`\{(w_i, x_i) \forall i \in \{1,\ldots, k\}\}` to the model as a S2 set, using function :meth:`~mip.Model.add_sos`. The approximation is exact at the selected points and is adequately approximated by linear interpolation between them. 31 | 32 | As an example, consider that the production cost of some product that due to some economy of scale phenomenon, is :math:`f(x) = 1520 * \log x`. The graph bellow depicts the growing of :math:`f(x)` for :math:`x \in [0, 150]`. Triangles indicate selected discretization points for :math:`x`. Observe that, in this case, the approximation (straight lines connecting the triangles) remains pretty close to the real curve using only 5 discretization points. Additional discretization points can be included, not necessarily evenly distributed, for an improved precision. 33 | 34 | .. image:: ./images/log_cost.* 35 | :width: 60% 36 | :align: center 37 | 38 | In this example, the approximation of :math:`z = 1520 \log x` for points :math:`x = (0, 10, 30, 70, 150)`, which correspond to :math:`z=(0, 3499.929, 5169.82, 6457.713, 7616.166)` could be computed with the following constraints over :math:`x, z` and :math:`w_1, \ldots, w_5` : 39 | 40 | .. math:: 41 | 42 | w_1 + w_2 + w_3 + w_4 + w_5 = 1 \\ 43 | x = 0 w_1 + 10 w_2 + 30 w_3 + 70 w_4 + 150 w_5 \\ 44 | z = 0 w_1 + 3499.929 w_2 + 5169.82 w_3 + 6457.713 w_4 + 7616.166 w_5 45 | 46 | provided that :math:`\{(w_1, 0), (w_2, 10), (w_3, 30), (w_4, 70), (w_5, 150)\}` is included as S2. 47 | 48 | 49 | For a complete example showing the use of Type 1 and Type 2 SOS see :ref:`this example `. 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp.py: -------------------------------------------------------------------------------- 1 | """Bandwidth multi coloring example 2 | Frequency assignment problem as described here: 3 | http://fap.zib.de/problems/Philadelphia/ 4 | 5 | to solve P1 instance (included in the examples) call python bmcp.py P1.col 6 | """ 7 | 8 | from itertools import product 9 | from sys import argv 10 | from time import time 11 | import bmcp_data 12 | import bmcp_greedy 13 | from mip import Model, xsum, minimize, MINIMIZE, BINARY 14 | 15 | data = bmcp_data.read(argv[1]) 16 | N, r, d = data.N, data.r, data.d 17 | S = bmcp_greedy.build(data) 18 | C, U = S.C, [i for i in range(S.u_max+1)] 19 | 20 | st = time() 21 | m = Model() 22 | 23 | x = [[m.add_var('x({},{})'.format(i, c), var_type=BINARY) 24 | for c in U] for i in N] 25 | 26 | z = m.add_var('z') 27 | m.objective = minimize(z) 28 | 29 | for i in N: 30 | m += xsum(x[i][c] for c in U) == r[i] 31 | 32 | for i, j, c1, c2 in product(N, N, U, U): 33 | if i != j and c1 <= c2 < c1+d[i][j]: 34 | m += x[i][c1] + x[j][c2] <= 1 35 | 36 | for i, c1, c2 in product(N, U, U): 37 | if c1 < c2 < c1+d[i][i]: 38 | m += x[i][c1] + x[i][c2] <= 1 39 | 40 | for i, c in product(N, U): 41 | m += z >= (c+1)*x[i][c] 42 | ed = time() 43 | 44 | print('Model creation time: %.2f' % (ed-st)) 45 | 46 | # m.start = [(x[i][c], 1.0) for i in N for c in C[i]] 47 | 48 | # m.optimize(max_seconds=100) 49 | 50 | # C = [[c for c in U if x[i][c] >= 0.99] for i in N] 51 | # print(C) 52 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp2.py: -------------------------------------------------------------------------------- 1 | """Bandwidth multi coloring example 2 | Frequency assignment problem as described here: 3 | http://fap.zib.de/problems/Philadelphia/ 4 | 5 | to solve P1 instance (included in the examples) call python bmcp.py P1.col 6 | """ 7 | 8 | from itertools import product 9 | from mip import Model, xsum, minimize, BINARY 10 | 11 | # number of channels per node 12 | r = [3, 5, 8, 3, 6, 5, 7, 3] 13 | 14 | # distance between channels in the same node (i, i) and in adjacent nodes 15 | # 0 1 2 3 4 5 6 7 16 | d = [[3, 2, 0, 0, 2, 2, 0, 0], # 0 17 | [2, 3, 2, 0, 0, 2, 2, 0], # 1 18 | [0, 2, 3, 0, 0, 0, 3, 0], # 2 19 | [0, 0, 0, 3, 2, 0, 0, 2], # 3 20 | [2, 0, 0, 2, 3, 2, 0, 0], # 4 21 | [2, 2, 0, 0, 2, 3, 2, 0], # 5 22 | [0, 2, 2, 0, 0, 2, 3, 0], # 6 23 | [0, 0, 0, 2, 0, 0, 0, 3]] # 7 24 | 25 | N = range(len(r)) 26 | 27 | # in complete applications this upper bound should be obtained from a feasible 28 | # solution produced with some heuristic 29 | U = range(sum(d[i][j] for (i, j) in product(N, N)) + sum(el for el in r)) 30 | 31 | m = Model() 32 | 33 | x = [[m.add_var('x({},{})'.format(i, c), var_type=BINARY) 34 | for c in U] for i in N] 35 | 36 | z = m.add_var('z') 37 | m.objective = minimize(z) 38 | 39 | for i in N: 40 | m += xsum(x[i][c] for c in U) == r[i] 41 | 42 | for i, j, c1, c2 in product(N, N, U, U): 43 | if i != j and c1 <= c2 < c1+d[i][j]: 44 | m += x[i][c1] + x[j][c2] <= 1 45 | 46 | for i, c1, c2 in product(N, U, U): 47 | if c1 < c2 < c1+d[i][i]: 48 | m += x[i][c1] + x[i][c2] <= 1 49 | 50 | for i, c in product(N, U): 51 | m += z >= (c+1)*x[i][c] 52 | 53 | m.optimize(max_seconds=100) 54 | 55 | if m.num_solutions: 56 | for i in N: 57 | print('Channels of node %d: %s', i, [c for c in U if x[i][c] >= 0.99]) 58 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp_data.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Reads instance data for the bandwidth multicoloring problem 3 | in the .col format 4 | 5 | Created on May 20, 2019 6 | 7 | @author: haroldo 8 | ''' 9 | 10 | from collections import defaultdict 11 | from typing import Tuple, List, DefaultDict 12 | 13 | 14 | class BMCPData: 15 | def __init__(self, 16 | N: List[int], 17 | r: List[int], 18 | d: List[DefaultDict[int, int]]): 19 | self.N = N # node list 20 | self.r = r # required channels per node 21 | self.d = d # distances matrix, d[i][j] indicates the minimum 22 | # distance between nodes i and j 23 | 24 | 25 | def read(file_name: str) -> \ 26 | BMCPData: 27 | """reads a Bandwidth Multicoloring Problem instance 28 | """ 29 | n, m = 0, 0 30 | f = open(file_name, 'r') 31 | for line in f: 32 | line = line.rstrip().lstrip().lower() 33 | line = ' '.join(line.split()) 34 | lc = line.split(' ') 35 | 36 | if lc[0] == 'p': 37 | n, m = int(lc[2]), int(lc[3]) 38 | d = [defaultdict(int) for i in range(n)] 39 | r = [int(1) for i in range(n)] 40 | elif lc[0] == 'e': 41 | u, v, w = int(lc[1])-1, int(lc[2])-1, int(lc[3]) 42 | d[u][v] = w 43 | d[v][u] = w 44 | elif lc[0] == 'n': 45 | r[int(lc[1])-1] = int(lc[2]) 46 | 47 | f.close() 48 | N = [i for i in range(n)] 49 | data = BMCPData(N, r, d) 50 | return data 51 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp_greedy.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on May 20, 2019 3 | 4 | @author: haroldo 5 | ''' 6 | 7 | from bmcp_data import BMCPData 8 | from bmcp_sol import BMCPSol 9 | 10 | def build(data: BMCPData) -> BMCPSol: 11 | S = BMCPSol(data) 12 | N, r, d = data.N, data.r, data.d 13 | 14 | # list of nodes sorted by conflicts 15 | L = [(sum(1 for v in d[i].values()), i) 16 | for i in N] 17 | L.sort(reverse=True) 18 | for (v, u) in L: 19 | print('allocating node {} which has {} conflicts'.format(u, v)) 20 | 21 | node = u 22 | for i in range(r[node]): 23 | av = S.available_color(u) 24 | S.allocate(node, av) 25 | 26 | return S 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp_mip.py: -------------------------------------------------------------------------------- 1 | from mip.model import Model, xsum 2 | from mip.constants import MINIMIZE, BINARY 3 | from bmcp_data import BMCPData 4 | from typing import List 5 | from itertools import product 6 | 7 | def build_mip(data: BMCPData, 8 | U: List[int] # list of available channels 9 | ) -> Model: 10 | return m 11 | -------------------------------------------------------------------------------- /examples/apps/bmcp/bmcp_sol.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on May 20, 2019 3 | 4 | @author: haroldo 5 | ''' 6 | 7 | from collections import defaultdict 8 | from typing import List, DefaultDict, Tuple 9 | from itertools import product 10 | from bmcp_data import BMCPData 11 | 12 | class BMCPSol(): 13 | """ 14 | Bandwidth Multi Coloring Problem 15 | """ 16 | 17 | def __init__(self, 18 | data: BMCPData): # distance adjacency lists 19 | # instance data 20 | self.data = data 21 | 22 | # solution 23 | self.C = [[] for i in self.data.N] 24 | self.u_max = 0 25 | 26 | def allocate(self, i: int, c: int): 27 | """allocated color c to node i""" 28 | self.C[i].append(c) 29 | self.u_max = max(self.u_max, c) 30 | 31 | def available_color(self, i: int) -> int: 32 | """ returns the next available color for node i """ 33 | ac = 0 34 | available = False 35 | has_conflict = False 36 | d, C = self.data.d, self.C 37 | while available is False: 38 | for (v, dist) in d[i].items(): 39 | for c in C[v]: 40 | if abs(ac-c) < dist: 41 | available = False 42 | ac += 1 43 | has_conflict = True 44 | break 45 | if has_conflict: 46 | break 47 | if has_conflict: 48 | has_conflict = False 49 | continue 50 | 51 | available = True 52 | 53 | return ac 54 | 55 | def __str__(self) -> str: 56 | N, C, u_max = self.data.N, self.C, self.u_max 57 | result = '{} different colors used in the solution:\n'.format(u_max+1) 58 | for node in N: 59 | result += '\t[{}]'.format(node+1) 60 | for color in C[node]: 61 | result += ' {}'.format(color+1) 62 | result += '\n' 63 | 64 | return result 65 | -------------------------------------------------------------------------------- /examples/apps/tsp/bench.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # bench.sh 4 | # Copyright (C) 2019 haroldo 5 | # 6 | # Distributed under terms of the MIT license. 7 | # 8 | 9 | rm -f results.csv 10 | rm -f runbench.sh 11 | idir='/home/haroldo/inst/tsp/' 12 | insts='ulysses16 ulysses22 att48 bier127 gr202 lin318 d493 brg180' 13 | TIMELIMIT=36000 14 | 15 | 16 | for inst in ${insts}; 17 | do 18 | rm -f trunbench-${inst}.sh 19 | done 20 | 21 | for inst in ${insts}; 22 | do 23 | ifile=${idir}/${inst}.tsp 24 | for solver in GUROBI CBC; 25 | do 26 | export SOLVER_NAME=$solver 27 | cut=0 28 | lazy=0 29 | heur=0 30 | flog=${inst}-${solver}-${cut}-${lazy}-${heur}.log 31 | ferror=${inst}-${solver}-${cut}-${lazy}-${heur}.error 32 | echo "export SOLVER_NAME=${solver} ; pypy3 tsp.py $ifile ${TIMELIMIT} 1 ${cut} ${lazy} ${heur} > $flog 2> $ferror" >> trunbench-${inst}.sh 33 | 34 | cut=1 35 | lazy=0 36 | heur=0 37 | flog=${inst}-${solver}-${cut}-${lazy}-${heur}.log 38 | ferror=${inst}-${solver}-${cut}-${lazy}-${heur}.error 39 | echo "export SOLVER_NAME=${solver} ; pypy3 tsp.py $ifile ${TIMELIMIT} 1 ${cut} ${lazy} ${heur} > $flog 2> $ferror" >> trunbench-${inst}.sh 40 | 41 | cut=0 42 | lazy=1 43 | heur=0 44 | flog=${inst}-${solver}-${cut}-${lazy}-${heur}.log 45 | ferror=${inst}-${solver}-${cut}-${lazy}-${heur}.error 46 | echo "export SOLVER_NAME=${solver} ; pypy3 tsp.py $ifile ${TIMELIMIT} 1 ${cut} ${lazy} ${heur} > $flog 2> $ferror" >> trunbench-${inst}.sh 47 | 48 | cut=0 49 | lazy=0 50 | heur=1 51 | flog=${inst}-${solver}-${cut}-${lazy}-${heur}.log 52 | ferror=${inst}-${solver}-${cut}-${lazy}-${heur}.error 53 | echo "export SOLVER_NAME=${solver} ; pypy3 tsp.py $ifile ${TIMELIMIT} 1 ${cut} ${lazy} ${heur} > $flog 2> $ferror" >> trunbench-${inst}.sh 54 | 55 | cut=1 56 | lazy=1 57 | heur=1 58 | flog=${inst}-${solver}-${cut}-${lazy}-${heur}.log 59 | ferror=${inst}-${solver}-${cut}-${lazy}-${heur}.error 60 | echo "export SOLVER_NAME=${solver} ; pypy3 tsp.py $ifile ${TIMELIMIT} 1 ${cut} ${lazy} ${heur} > $flog 2> $ferror" >> trunbench-${inst}.sh 61 | done 62 | done 63 | 64 | for inst in ${insts}; 65 | do 66 | cat trunbench-${inst}.sh | sort -R > rb-${inst}.sh 67 | rm -f trunbench-${inst}.sh 68 | chmod u+x rb-${inst}.sh 69 | done 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/apps/tsp/rb-bier127.sh: -------------------------------------------------------------------------------- 1 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 0 1 > bier127-GUROBI-0-0-1.log 2> bier127-GUROBI-0-0-1.error 2 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 1 1 1 > bier127-CBC-1-1-1.log 2> bier127-CBC-1-1-1.error 3 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 1 0 0 > bier127-CBC-1-0-0.log 2> bier127-CBC-1-0-0.error 4 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 0 0 > bier127-GUROBI-0-0-0.log 2> bier127-GUROBI-0-0-0.error 5 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 1 0 > bier127-CBC-0-1-0.log 2> bier127-CBC-0-1-0.error 6 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 0 0 > bier127-CBC-0-0-0.log 2> bier127-CBC-0-0-0.error 7 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 1 0 0 > bier127-GUROBI-1-0-0.log 2> bier127-GUROBI-1-0-0.error 8 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 1 1 1 > bier127-GUROBI-1-1-1.log 2> bier127-GUROBI-1-1-1.error 9 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 1 0 > bier127-GUROBI-0-1-0.log 2> bier127-GUROBI-0-1-0.error 10 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//bier127.tsp 36000 1 0 0 1 > bier127-CBC-0-0-1.log 2> bier127-CBC-0-0-1.error 11 | -------------------------------------------------------------------------------- /examples/apps/tsp/rb-gr202.sh: -------------------------------------------------------------------------------- 1 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 0 0 > gr202-CBC-0-0-0.log 2> gr202-CBC-0-0-0.error 2 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 1 0 > gr202-GUROBI-0-1-0.log 2> gr202-GUROBI-0-1-0.error 3 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 1 1 1 > gr202-CBC-1-1-1.log 2> gr202-CBC-1-1-1.error 4 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 0 1 > gr202-CBC-0-0-1.log 2> gr202-CBC-0-0-1.error 5 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 0 0 > gr202-GUROBI-0-0-0.log 2> gr202-GUROBI-0-0-0.error 6 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 1 0 > gr202-CBC-0-1-0.log 2> gr202-CBC-0-1-0.error 7 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 0 0 1 > gr202-GUROBI-0-0-1.log 2> gr202-GUROBI-0-0-1.error 8 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 1 0 0 > gr202-GUROBI-1-0-0.log 2> gr202-GUROBI-1-0-0.error 9 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 1 1 1 > gr202-GUROBI-1-1-1.log 2> gr202-GUROBI-1-1-1.error 10 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//gr202.tsp 36000 1 1 0 0 > gr202-CBC-1-0-0.log 2> gr202-CBC-1-0-0.error 11 | -------------------------------------------------------------------------------- /examples/apps/tsp/rb-lin318.sh: -------------------------------------------------------------------------------- 1 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 1 0 0 > lin318-CBC-1-0-0.log 2> lin318-CBC-1-0-0.error 2 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 1 0 0 > lin318-GUROBI-1-0-0.log 2> lin318-GUROBI-1-0-0.error 3 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 0 1 > lin318-GUROBI-0-0-1.log 2> lin318-GUROBI-0-0-1.error 4 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 1 1 1 > lin318-CBC-1-1-1.log 2> lin318-CBC-1-1-1.error 5 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 1 0 > lin318-CBC-0-1-0.log 2> lin318-CBC-0-1-0.error 6 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 0 0 > lin318-GUROBI-0-0-0.log 2> lin318-GUROBI-0-0-0.error 7 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 0 1 > lin318-CBC-0-0-1.log 2> lin318-CBC-0-0-1.error 8 | export SOLVER_NAME=CBC ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 0 0 > lin318-CBC-0-0-0.log 2> lin318-CBC-0-0-0.error 9 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 0 1 0 > lin318-GUROBI-0-1-0.log 2> lin318-GUROBI-0-1-0.error 10 | export SOLVER_NAME=GUROBI ; pypy3 tsp.py /home/haroldo/inst/tsp//lin318.tsp 36000 1 1 1 1 > lin318-GUROBI-1-1-1.log 2> lin318-GUROBI-1-1-1.error 11 | -------------------------------------------------------------------------------- /examples/apps/tsp/tsplibtodist.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2019 haroldo 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | from sys import argv 10 | from os.path import basename 11 | import tsplib95 as tsp_data 12 | 13 | P = tsp_data.load_problem(argv[1]) 14 | 15 | iname = basename(argv[1]) 16 | 17 | if iname.endswith('.tsp'): 18 | iname = iname.split('.tsp')[0] 19 | 20 | N = set([i for i in P.get_nodes()]) 21 | 22 | fo = open('%s.dist' % iname, 'w') 23 | fo.write('%d\n' % len(P)) 24 | for i in N: 25 | for j in N: 26 | fo.write('%d\n' % P.wfunc(i, j)) 27 | fo.close() 28 | -------------------------------------------------------------------------------- /examples/belgium-tourism-14.tsp: -------------------------------------------------------------------------------- 1 | NAME: belgium-tourism-14 2 | TYPE: TSP 3 | COMMENT: Belgium tourist attractions 4 | DIMENSION: 14 5 | EDGE_WEIGHT_TYPE: GEO 6 | DISPLAY_DATA_TYPE: COORD_DISPLAY 7 | NODE_COORD_SECTION 8 | 1 51.21944 4.40246 496 196 Antwerp 9 | 2 51.20934 3.22469 273 199 Bruges 10 | 3 50.98121 5.48662 702 269 C-Mine 11 | 4 50.26049 4.91274 593 484 Dinant 12 | 5 51.05434 3.71742 366 246 Ghent 13 | 6 50.84673 4.35241 487 309 Grand-Place de Bruxelles 14 | 7 50.93069 5.33248 672 284 Hasselt 15 | 8 50.87984 4.70051 552 299 Leuven 16 | 9 51.02587 4.47753 510 255 Mechelen 17 | 10 50.45424 3.95665 411 426 Mons 18 | 11 50.64812 5.57735 719 369 Montagne de Bueren 19 | 12 50.46738 4.87198 585 422 Namur 20 | 13 50.47987 5.71185 743 418 Remouchamps 21 | 14 50.71469 4.39909 494 348 Waterloo 22 | EOF 23 | -------------------------------------------------------------------------------- /examples/bmcp.py: -------------------------------------------------------------------------------- 1 | """Bandwidth multi coloring problem, more specificially the Frequency 2 | assignment problem as described here: http://fap.zib.de/problems/Philadelphia/ 3 | """ 4 | 5 | from itertools import product 6 | from mip import Model, xsum, minimize, BINARY 7 | 8 | # number of channels per node 9 | r = [3, 5, 8, 3, 6, 5, 7, 3] 10 | 11 | # distance between channels in the same node (i, i) and in adjacent nodes 12 | # 0 1 2 3 4 5 6 7 13 | d = [[3, 2, 0, 0, 2, 2, 0, 0], # 0 14 | [2, 3, 2, 0, 0, 2, 2, 0], # 1 15 | [0, 2, 3, 0, 0, 0, 3, 0], # 2 16 | [0, 0, 0, 3, 2, 0, 0, 2], # 3 17 | [2, 0, 0, 2, 3, 2, 0, 0], # 4 18 | [2, 2, 0, 0, 2, 3, 2, 0], # 5 19 | [0, 2, 2, 0, 0, 2, 3, 0], # 6 20 | [0, 0, 0, 2, 0, 0, 0, 3]] # 7 21 | 22 | N = range(len(r)) 23 | 24 | # in complete applications this upper bound should be obtained from a feasible 25 | # solution produced with some heuristic 26 | U = range(sum(d[i][j] for (i, j) in product(N, N)) + sum(el for el in r)) 27 | 28 | m = Model() 29 | 30 | x = [[m.add_var('x({},{})'.format(i, c), var_type=BINARY) 31 | for c in U] for i in N] 32 | 33 | z = m.add_var('z') 34 | m.objective = minimize(z) 35 | 36 | for i in N: 37 | m += xsum(x[i][c] for c in U) == r[i] 38 | 39 | for i, j, c1, c2 in product(N, N, U, U): 40 | if i != j and c1 <= c2 < c1+d[i][j]: 41 | m += x[i][c1] + x[j][c2] <= 1 42 | 43 | for i, c1, c2 in product(N, U, U): 44 | if c1 < c2 < c1+d[i][i]: 45 | m += x[i][c1] + x[i][c2] <= 1 46 | 47 | for i, c in product(N, U): 48 | m += z >= (c+1)*x[i][c] 49 | 50 | m.optimize(max_nodes=30) 51 | 52 | if m.num_solutions: 53 | for i in N: 54 | print('Channels of node %d: %s' % (i, [c for c in U if x[i][c].x >= 55 | 0.99])) 56 | 57 | # sanity tests 58 | from mip import OptimizationStatus 59 | 60 | assert m.objective_bound <= 41 + 1e-10 61 | if m.status == OptimizationStatus.OPTIMAL: 62 | assert round(m.objective_value) == 41 63 | elif m.status == OptimizationStatus.FEASIBLE: 64 | assert m.objective_value >= 41 - 1e-10 65 | m.check_optimization_results() 66 | -------------------------------------------------------------------------------- /examples/cgraph.py: -------------------------------------------------------------------------------- 1 | """Example where a binary program is created and the conflict graph 2 | is inspected. 3 | """ 4 | from itertools import product 5 | from sys import stdout as out 6 | from mip import Model, BINARY 7 | 8 | 9 | m = m = Model(solver_name="cbc") 10 | 11 | N = range(1, 7) 12 | 13 | x = {i: m.add_var(var_type=BINARY, name="x(%d)" % i) for i in N} 14 | 15 | m += -3 * x[1] + 4 * x[2] - 5 * x[3] + 6 * x[4] + 7 * x[5] + 8 * x[6] <= 2 16 | m += x[1] + x[2] + x[4] >= 1 17 | 18 | cg = m.conflict_graph 19 | 20 | for i, v in product(N, range(2)): 21 | out.write("conflicts for x[%d] == %g : " % (i, v)) 22 | ca = cg.conflicting_assignments(x[i] == v) 23 | for j in ca[0]: 24 | out.write("%s == 1 " % j.name) 25 | for j in ca[1]: 26 | out.write("%s == 0 " % j.name) 27 | 28 | out.write("\n") 29 | 30 | # sanity checks 31 | confs = { 32 | (i, v): cg.conflicting_assignments(x[i] == v) 33 | for (i, v) in product(N, range(2)) 34 | } 35 | # conflicts with complement 36 | for i in N: 37 | assert cg.conflicting(x[i] == 1, x[i] == 0) 38 | assert x[i] in confs[i, 1][1] 39 | assert x[i] in confs[i, 0][0] 40 | # other conflicts to test 41 | test_conf = [((2, 1), (5, 1)), ((2, 1), (6, 1)), ((2, 1), (2, 0))] 42 | for c in test_conf: 43 | assert cg.conflicting(x[c[0][0]] == c[0][1], x[c[1][0]] == c[1][1]) 44 | 45 | test_no_conf = [((2, 1), (4, 1))] 46 | for c in test_no_conf: 47 | assert not cg.conflicting(x[c[0][0]] == c[0][1], x[c[1][0]] == c[1][1]) 48 | -------------------------------------------------------------------------------- /examples/clique_merge.py: -------------------------------------------------------------------------------- 1 | """Example with clique merge: a formulation of a knapsack problem 2 | with conflicting items where clique merge can improve it""" 3 | 4 | from mip import Model, xsum, maximize, BINARY 5 | 6 | I = set(range(1, 7)) 7 | 8 | # weigths 9 | w = {1: -4, 2: 4, 3: 5, 4: 6, 5: 7, 6: 10} 10 | 11 | # profits 12 | p = {1: -2, 2: 8, 3: 10, 4: 12, 5: 13, 6: 13} 13 | 14 | # capacity 15 | c = 6 16 | 17 | # conflicting items 18 | C = ((2, 3), (2, 4), (3, 4), (2, 5)) 19 | 20 | m = Model() 21 | 22 | x = {i: m.add_var("x({})".format(i), var_type=BINARY) for i in I} 23 | 24 | m.objective = maximize(xsum(p[i] * x[i] for i in I)) 25 | 26 | m += xsum(w[i] * x[i] for i in I) <= c 27 | 28 | for (i, j) in C: 29 | m += x[i] + x[j] <= 1 30 | 31 | m.verbose = 0 32 | m.write("b.lp") 33 | m.optimize(relax=True) 34 | 35 | print( 36 | "constraints before clique merging: {}. lower bound:" 37 | "{}.".format(len(m.constrs), m.objective_value) 38 | ) 39 | 40 | m.clique_merge() 41 | 42 | m.optimize(relax=True) 43 | 44 | print( 45 | "constraints after clique merging: {}. lower bound:" 46 | "{}.".format(len(m.constrs), m.objective_value) 47 | ) 48 | 49 | m.optimize() 50 | 51 | print("optimal: {}".format(m.objective_value)) 52 | 53 | 54 | # sanity tests 55 | from mip import OptimizationStatus 56 | 57 | assert m.status == OptimizationStatus.OPTIMAL 58 | if m.solver_name.upper() == "CBC": 59 | assert m.num_rows == 2 60 | assert abs(m.objective_value - 12) <= 1e-4 61 | -------------------------------------------------------------------------------- /examples/conflict_finder.py: -------------------------------------------------------------------------------- 1 | 2 | import logging 3 | import numpy as np 4 | import sys 5 | import random 6 | from mip.conflict import ConflictFinder, ConflictRelaxer 7 | import mip 8 | 9 | # logger = logging.getLogger(__name__) 10 | logger = logging.getLogger("conflict") 11 | 12 | 13 | def build_infeasible_cont_model( 14 | num_constraints: int = 10, num_infeasible_sets: int = 20 15 | ) -> mip.Model: 16 | # build an infeasible model, based on many redundant constraints 17 | mdl = mip.Model(name="infeasible_model_continuous") 18 | var = mdl.add_var(name="x", var_type=mip.CONTINUOUS, lb=-1000, ub=1000) 19 | 20 | for idx, rand_constraint in enumerate(np.linspace(1, 1000, num_constraints)): 21 | crt = mdl.add_constr( 22 | var >= rand_constraint, 23 | name="lower_bound_{0}".format(idx), 24 | ) 25 | crt.priority = random.choice(list(mip.constants.ConstraintPriority)[1:]) 26 | print(crt.priority) 27 | logger.debug("added {} to the model".format(crt)) 28 | 29 | num_constraint_inf = int(num_infeasible_sets / num_constraints) 30 | for idx, rand_constraint in enumerate(np.linspace(-1000, -1, num_constraint_inf)): 31 | crt = mdl.add_constr( 32 | var <= rand_constraint, 33 | name="upper_bound_{0}".format(idx) 34 | ) 35 | crt.priority = random.choice(list(mip.constants.ConstraintPriority)[:1]) 36 | logger.debug("added {} to the model".format(crt)) 37 | 38 | mdl.emphasis = 1 # feasibility 39 | mdl.preprocess = 1 # -1 automatic, 0 off, 1 on. 40 | # mdl.pump_passes TODO configure to feasibility emphasis 41 | return mdl 42 | 43 | 44 | def main(): 45 | # logger config 46 | handler = logging.StreamHandler(sys.stdout) 47 | logger.setLevel(logging.DEBUG) 48 | logger.addHandler(handler) 49 | 50 | # create an infeasible model 51 | model = build_infeasible_cont_model() 52 | logger.debug(model.status) 53 | model.optimize() 54 | logger.debug(model.status) 55 | 56 | # find one IIS 57 | cf = ConflictFinder(model) 58 | iis = cf.find_iis() 59 | logger.debug([crt.__str__() for crt in iis]) 60 | 61 | # resolve a conflict 62 | cr = ConflictRelaxer(model) 63 | relaxed_model = cr.hierarchy_relaxer(relaxer_objective="min_abs_slack_val") 64 | print(cr.slack_by_crt) 65 | 66 | 67 | if __name__ == "__main__": 68 | main() -------------------------------------------------------------------------------- /examples/cutting_planes.py: -------------------------------------------------------------------------------- 1 | """Python-MIP example of a pure cutting plane algorithm for the Traveling 2 | Salesman Problem.""" 3 | 4 | from itertools import product 5 | from networkx import minimum_cut, DiGraph 6 | from mip import Model, xsum, BINARY, OptimizationStatus, CutType 7 | 8 | N = ["a", "b", "c", "d", "e", "f", "g"] 9 | A = { ("a", "d"): 56, ("d", "a"): 67, ("a", "b"): 49, ("b", "a"): 50, 10 | ("f", "c"): 35, ("g", "b"): 35, ("g", "b"): 35, ("b", "g"): 25, 11 | ("a", "c"): 80, ("c", "a"): 99, ("e", "f"): 20, ("f", "e"): 20, 12 | ("g", "e"): 38, ("e", "g"): 49, ("g", "f"): 37, ("f", "g"): 32, 13 | ("b", "e"): 21, ("e", "b"): 30, ("a", "g"): 47, ("g", "a"): 68, 14 | ("d", "c"): 37, ("c", "d"): 52, ("d", "e"): 15, ("e", "d"): 20, 15 | ("d", "b"): 39, ("b", "d"): 37, ("c", "f"): 35, } 16 | Aout = {n: [a for a in A if a[0] == n] for n in N} 17 | Ain = {n: [a for a in A if a[1] == n] for n in N} 18 | 19 | m = Model() 20 | x = {a: m.add_var(name="x({},{})".format(a[0], a[1]), var_type=BINARY) for a in A} 21 | 22 | m.objective = xsum(c * x[a] for a, c in A.items()) 23 | 24 | for n in N: 25 | m += xsum(x[a] for a in Aout[n]) == 1, "out({})".format(n) 26 | m += xsum(x[a] for a in Ain[n]) == 1, "in({})".format(n) 27 | 28 | newConstraints = True 29 | 30 | while newConstraints: 31 | m.optimize(relax=True) 32 | print("status: {} objective value : {}".format(m.status, m.objective_value)) 33 | 34 | G = DiGraph() 35 | for a in A: 36 | G.add_edge(a[0], a[1], capacity=x[a].x) 37 | 38 | newConstraints = False 39 | for (n1, n2) in [(i, j) for (i, j) in product(N, N) if i != j]: 40 | cut_value, (S, NS) = minimum_cut(G, n1, n2) 41 | if cut_value <= 0.99: 42 | m += (xsum(x[a] for a in A if (a[0] in S and a[1] in S)) <= len(S) - 1) 43 | newConstraints = True 44 | if not newConstraints and m.solver_name.lower() == "cbc": 45 | cp = m.generate_cuts([CutType.GOMORY, CutType.MIR, 46 | CutType.ZERO_HALF, CutType.KNAPSACK_COVER]) 47 | if cp.cuts: 48 | m += cp 49 | newConstraints = True 50 | 51 | # sanity checks 52 | assert m.status == OptimizationStatus.OPTIMAL 53 | assert 260.99 <= m.objective_value <= 262.000001 54 | -------------------------------------------------------------------------------- /examples/cuttingstock_cg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Simple column generation implementation for a Cutting Stock Problem 6 | """ 7 | 8 | from mip import Model, xsum, Column, CONTINUOUS, INTEGER 9 | 10 | L = 250 # bar length 11 | m = 4 # number of requests 12 | w = [187, 119, 74, 90] # size of each item 13 | b = [1, 2, 2, 1] # demand for each item 14 | 15 | # creating master model 16 | master = Model() 17 | 18 | # creating an initial set of patterns which cut one item per bar 19 | # to provide the restricted master problem with a feasible solution 20 | lambdas = [master.add_var(obj=1, name='lambda_%d' % (j + 1)) 21 | for j in range(m)] 22 | 23 | # creating constraints 24 | constraints = [] 25 | for i in range(m): 26 | constraints.append(master.add_constr(lambdas[i] >= b[i], name='i_%d' % (i + 1))) 27 | 28 | # creating the pricing problem 29 | pricing = Model() 30 | 31 | # creating pricing variables 32 | a = [pricing.add_var(obj=0, var_type=INTEGER, name='a_%d' % (i + 1)) for i in range(m)] 33 | 34 | # creating pricing constraint 35 | pricing += xsum(w[i] * a[i] for i in range(m)) <= L, 'bar_length' 36 | 37 | new_vars = True 38 | while new_vars: 39 | 40 | ########## 41 | # STEP 1: solving restricted master problem 42 | ########## 43 | 44 | master.optimize() 45 | 46 | ########## 47 | # STEP 2: updating pricing objective with dual values from master 48 | ########## 49 | 50 | pricing += 1 - xsum(constraints[i].pi * a[i] for i in range(m)) 51 | 52 | # solving pricing problem 53 | pricing.optimize() 54 | 55 | # printing pricing solution 56 | z_val = pricing.objective_value 57 | print('Pricing solution:') 58 | print(' z = {z_val}'.format(**locals())) 59 | print(' a = ', end='') 60 | print([v.x for v in pricing.vars]) 61 | print('') 62 | 63 | ########## 64 | # STEP 3: adding the new columns (if any is obtained with negative reduced cost) 65 | ########## 66 | 67 | # checking if columns with negative reduced cost were produced and 68 | # adding them into the restricted master problem 69 | if pricing.objective_value < - 1e-5: 70 | pattern = [a[i].x for i in range(m)] 71 | column = Column(constraints, pattern) 72 | lambdas.append(master.add_var(obj=1, column=column, 73 | name='lambda_%d' % (len(lambdas) + 1))) 74 | 75 | print('new pattern = {pattern}'.format(**locals())) 76 | 77 | # if no column with negative reduced cost was produced, then linear 78 | # relaxation of the restricted master problem is solved 79 | else: 80 | new_vars = False 81 | 82 | pricing.write('pricing.lp') 83 | 84 | # printing the solution 85 | print('') 86 | print('Objective value: {master.objective_value:.3}'.format(**locals())) 87 | print('Solution: ', end='') 88 | for v in lambdas: 89 | if v.x > 1e-6: 90 | print('{v.name} = {v.x:.3} {v.column}'.format(**locals())) 91 | print(' ', end='') 92 | 93 | # sanity checks 94 | master.check_optimization_results() 95 | -------------------------------------------------------------------------------- /examples/cuttingstock_kantorovich.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from mip import Model, xsum, BINARY, INTEGER 5 | 6 | n = 10 # maximum number of bars 7 | L = 250 # bar length 8 | m = 4 # number of requests 9 | w = [187, 119, 74, 90] # size of each item 10 | b = [1, 2, 2, 1] # demand for each item 11 | 12 | # creating the model 13 | model = Model() 14 | x = {(i, j): model.add_var(obj=0, var_type=INTEGER, name="x[%d,%d]" % (i, j)) 15 | for i in range(m) for j in range(n)} 16 | y = {j: model.add_var(obj=1, var_type=BINARY, name="y[%d]" % j) 17 | for j in range(n)} 18 | 19 | # constraints 20 | for i in range(m): 21 | model.add_constr(xsum(x[i, j] for j in range(n)) >= b[i]) 22 | for j in range(n): 23 | model.add_constr(xsum(w[i] * x[i, j] for i in range(m)) <= L * y[j]) 24 | 25 | # additional constraints to reduce symmetry 26 | for j in range(1, n): 27 | model.add_constr(y[j - 1] >= y[j]) 28 | 29 | # optimizing the model 30 | model.optimize() 31 | 32 | # printing the solution 33 | print('') 34 | print('Objective value: {model.objective_value:.3}'.format(**locals())) 35 | print('Solution: ', end='') 36 | for v in model.vars: 37 | if v.x > 1e-5: 38 | print('{v.name} = {v.x}'.format(**locals())) 39 | print(' ', end='') 40 | 41 | # sanity tests 42 | from mip import OptimizationStatus 43 | assert abs(model.objective_value - 3) <= 1e-4 44 | assert sum(x.x for x in model.vars) >= 5 45 | -------------------------------------------------------------------------------- /examples/europe-tourism-22.tsp: -------------------------------------------------------------------------------- 1 | NAME: europe-tourism-22 2 | TYPE: TSP 3 | COMMENT: Europe tourist attractions 4 | DIMENSION: 22 5 | EDGE_WEIGHT_TYPE: GEO 6 | DISPLAY_DATA_TYPE: COORD_DISPLAY 7 | NODE_COORD_SECTION 8 | 1 50.07553 14.4378 750 219 Prague Czech Republic 9 | 2 41.40362 2.17435 250 727 Barcelona Spain 10 | 3 45.43731 12.32563 618 483 Grande Canal de Veneza 11 | 4 43.76135 6.37883 422 597 579 Verdon Gorge 12 | 5 46.68081 9.67629 556 428 Landwasser Viaduct 13 | 6 47.56223 13.64926 718 375 Hallstatt Village Austria 14 | 7 52.37073 4.89195 362 70 Keizersgracht Amsterdam 15 | 8 44.13492 9.68499 664 500 Venice 16 | 9 47.55757 10.7498 600 375 Neuschwanstein Castle 17 | 10 48.85904 2.29329 255 296 Paris 18 | 11 44.86539 15.58201 796 533 Plitvice Park Croatia 19 | 12 48.63606 -1.51145 100 309 Mont Saint Michel France 20 | 13 44.83778 -0.57917 139 535 Bordeaux France 21 | 14 51.75202 -1.25772 110 111 Oxford UK 22 | 15 51.0504 13.73726 722 156 Dresten Germany 23 | 16 50.93753 6.96027 446 165 Cologne Germany 24 | 17 46.00367 8.95105 526 467 Lugano Swiss 25 | 18 48.57482 7.7535 478 312 Strassbourg France 26 | 19 43.59123 3.25836 294 606 Languedoc-Roussillon France 27 | 20 49.61162 6.13193 412 248 Luxembourg 28 | 21 52.52 13.40495 708 60 Berlin 29 | 22 51.75 10.63333 595 110 Harz Germany 30 | EOF 31 | -------------------------------------------------------------------------------- /examples/extract_features_mip.py: -------------------------------------------------------------------------------- 1 | """This example reads a MIP (in .lp or .mps), solves its linear programming 2 | relaxation and then tests the impact of adding different types of cutting 3 | planes.""" 4 | 5 | import sys 6 | from mip import Model, features, compute_features 7 | import mip 8 | 9 | lp_path = "" 10 | 11 | # using test data, replace with your instance 12 | lp_path = mip.__file__.replace("mip/__init__.py", "test/data/1443_0-9.lp").replace( 13 | "mip\\__init__.py", "test\\data\\1443_0-9.lp" 14 | ) 15 | 16 | m = Model() 17 | if m.solver_name.upper() in ["GRB", "GUROBI"]: 18 | print("This feature is only supported in CBC.") 19 | else: 20 | m.read(lp_path) 21 | 22 | print("instance features:") 23 | X = compute_features(m) 24 | for i, fn in enumerate(features()): 25 | print("%s: %g" % (fn, X[i])) 26 | -------------------------------------------------------------------------------- /examples/gen_cuts.py: -------------------------------------------------------------------------------- 1 | """Example of use of general cutting planes in a small MIP.""" 2 | 3 | import sys 4 | from mip import Model, INTEGER, maximize, CutType, OptimizationStatus 5 | 6 | larger_diff = -1 7 | best_cut = None 8 | 9 | for ct in CutType: 10 | print("Trying cut type: {}".format(ct.name)) 11 | 12 | m = Model() 13 | if m.solver_name.upper() in ["GRB", "GUROBI"]: 14 | print("This feature is currently not supported in Gurobi.") 15 | else: 16 | m.verbose = 0 17 | 18 | x = m.add_var_tensor(shape=(2, 1), name="x", var_type=INTEGER) 19 | 20 | m.objective = maximize(2 * x[0] + x[1]) 21 | 22 | m += 7 * x[0] + x[1] <= 28 23 | m += -x[0] + 3 * x[1] <= 7 24 | m += -8 * x[0] - 9 * x[1] <= -32 25 | 26 | m.optimize(relax=True) 27 | olr = m.objective_value 28 | 29 | cp = m.generate_cuts([ct]) 30 | if cp and cp.cuts: 31 | print("{} cuts generated:".format(len(cp.cuts))) 32 | for c in cp.cuts: 33 | print(" " + str(c)) 34 | 35 | if cp.cuts: 36 | m += cp 37 | m.optimize(relax=True) 38 | 39 | print("Dual bound now: {}".format(m.objective_value)) 40 | assert m.status == OptimizationStatus.OPTIMAL 41 | diff = m.objective_value - olr 42 | if diff > larger_diff: 43 | larger_diff = diff 44 | best_cut = ct 45 | 46 | print("Best cut: {}".format(best_cut)) 47 | -------------------------------------------------------------------------------- /examples/gen_cuts_mip.py: -------------------------------------------------------------------------------- 1 | """This example reads a MIP (in .lp or .mps), solves its linear programming 2 | relaxation and then tests the impact of adding different types of cutting 3 | planes. In the end, it informs which cut generator produced the best bound 4 | improvement. 5 | """ 6 | 7 | from textwrap import shorten 8 | from mip import Model, CutType, OptimizationStatus 9 | import mip 10 | 11 | # using test data 12 | lp_path = mip.__file__.replace("mip/__init__.py", "test/data/1443_0-9.lp").replace( 13 | "mip\\__init__.py", "test\\data\\1443_0-9.lp" 14 | ) 15 | 16 | m = Model() 17 | if m.solver_name.upper() != mip.CBC: 18 | print("This feature is currently supported only in CBC.") 19 | else: 20 | m.read(lp_path) 21 | 22 | m.verbose = 0 23 | m.optimize(relax=True) 24 | print("Original LP bound: {}".format(m.objective_value)) 25 | 26 | best_impr = -1 27 | best_cut = "" 28 | 29 | for ct in CutType: 30 | print() 31 | m2 = m.copy() 32 | m2.verbose = 0 33 | m2.optimize(relax=True) 34 | assert ( 35 | m2.status == OptimizationStatus.OPTIMAL 36 | and abs(m2.objective_value - m.objective_value) <= 1e-4 37 | ) 38 | print("Searching for violated {} inequalities ...".format(ct.name)) 39 | cp = m2.generate_cuts([ct]) 40 | if cp and cp.cuts: 41 | print("{} cuts found:".format(len(cp.cuts))) 42 | for c in cp.cuts[0 : min(10, len(cp.cuts))]: 43 | print(" {}".format(shorten(str(c), width=90, placeholder="..."))) 44 | m2 += cp 45 | m2.optimize(relax=True) 46 | perc_impr = ( 47 | abs(m2.objective_value - m.objective_value) 48 | / max(abs(m2.objective_value), abs(m.objective_value)) 49 | ) * 100 50 | 51 | if perc_impr > best_impr: 52 | best_impr = perc_impr 53 | best_cut = ct 54 | 55 | print( 56 | f"Linear programming relaxation bound now: " 57 | f"{m2.objective_value:.2f}, improvement of {perc_impr:.2f}" 58 | ) 59 | else: 60 | continue 61 | 62 | print("Best cut: {} improved dual bound: {:.2f} ".format(best_cut, best_impr)) 63 | -------------------------------------------------------------------------------- /examples/img/belgium-tourism-14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/examples/img/belgium-tourism-14.gif -------------------------------------------------------------------------------- /examples/img/europe-tourism-22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/examples/img/europe-tourism-22.gif -------------------------------------------------------------------------------- /examples/jssp.py: -------------------------------------------------------------------------------- 1 | """Job Shop Scheduling Problem Python-MIP example 2 | To execute it on the example instance ft03.jssp call 3 | python jssp.py ft03.jssp 4 | by Victor Silva""" 5 | 6 | from itertools import product 7 | from mip import Model, BINARY 8 | 9 | n = m = 3 10 | 11 | times = [[2, 1, 2], 12 | [1, 2, 2], 13 | [1, 2, 1]] 14 | 15 | M = sum(times[i][j] for i in range(n) for j in range(m)) 16 | 17 | machines = [[2, 0, 1], 18 | [1, 2, 0], 19 | [2, 1, 0]] 20 | 21 | model = Model('JSSP') 22 | 23 | c = model.add_var(name="C") 24 | x = [[model.add_var(name='x({},{})'.format(j+1, i+1)) 25 | for i in range(m)] for j in range(n)] 26 | y = [[[model.add_var(var_type=BINARY, name='y({},{},{})'.format(j+1, k+1, i+1)) 27 | for i in range(m)] for k in range(n)] for j in range(n)] 28 | 29 | model.objective = c 30 | 31 | for (j, i) in product(range(n), range(1, m)): 32 | model += x[j][machines[j][i]] - x[j][machines[j][i-1]] >= \ 33 | times[j][machines[j][i-1]] 34 | 35 | for (j, k) in product(range(n), range(n)): 36 | if k != j: 37 | for i in range(m): 38 | model += x[j][i] - x[k][i] + M*y[j][k][i] >= times[k][i] 39 | model += -x[j][i] + x[k][i] - M*y[j][k][i] >= times[j][i] - M 40 | 41 | for j in range(n): 42 | model += c - x[j][machines[j][m - 1]] >= times[j][machines[j][m - 1]] 43 | 44 | model.optimize() 45 | 46 | print("Completion time: ", c.x) 47 | for (j, i) in product(range(n), range(m)): 48 | print("task %d starts on machine %d at time %g " % (j+1, i+1, x[j][i].x)) 49 | 50 | # sanity tests 51 | from mip import OptimizationStatus 52 | assert model.status == OptimizationStatus.OPTIMAL 53 | assert round(c.x) == 7 54 | -------------------------------------------------------------------------------- /examples/knapsack.py: -------------------------------------------------------------------------------- 1 | """0/1 Knapsack example""" 2 | 3 | from mip import Model, xsum, maximize, BINARY 4 | 5 | p = [10, 13, 18, 31, 7, 15] 6 | w = [11, 15, 20, 35, 10, 33] 7 | c, I = 47, range(len(w)) 8 | 9 | m = Model("knapsack") 10 | 11 | x = [m.add_var(var_type=BINARY) for i in I] 12 | 13 | m.objective = maximize(xsum(p[i] * x[i] for i in I)) 14 | 15 | m += xsum(w[i] * x[i] for i in I) <= c 16 | 17 | m.optimize() 18 | 19 | selected = [i for i in I if x[i].x >= 0.99] 20 | print("selected items: {}".format(selected)) 21 | 22 | # sanity tests 23 | from mip import OptimizationStatus 24 | 25 | assert m.status == OptimizationStatus.OPTIMAL 26 | assert round(m.objective_value) == 41 27 | assert round(m.constrs[0].slack) == 1 28 | -------------------------------------------------------------------------------- /examples/numpy_tensor.py: -------------------------------------------------------------------------------- 1 | """Example of a solver using numpy tensors. 2 | The problem solves a basic coin change problem, where a given sum must 3 | be achieved as the sum of coin values, minimizing the number of coins. 4 | This is a purely integer problem well suited to showcase numpy matrices. 5 | """ 6 | 7 | from mip import Model, MINIMIZE, INTEGER 8 | import numpy as np 9 | 10 | model = Model(sense=MINIMIZE) 11 | 12 | # we have coins for 1 cent, 2 cents, 5 cents, 10 cents, 20 cents, 50 cents, 1 euro, 2 euros 13 | vals = np.array([0.01, 0.02, 0.05, 0.10, 0.20, 0.50, 1, 2], dtype=float) 14 | 15 | # we have a limited amount of coins for each type 16 | available = np.array([5, 5, 5, 5, 5, 5, 2, 0], dtype=int) 17 | 18 | # 8 types of coins in total 19 | x = model.add_var_tensor(shape=vals.shape, name="x", var_type=INTEGER) 20 | 21 | # objective: minimize number of coins 22 | model.objective = x.sum() 23 | 24 | # boundary: amount must be equal to required change, within rouding errors 25 | required_change = 3.74 26 | eps = 0.005 27 | 28 | # total value of the coins 29 | amount = x.dot(vals) 30 | print("Value of the coins: %s" % amount) 31 | 32 | # these are 2 separate scalar constraints computed with tensor notation 33 | model += (required_change - eps) <= amount 34 | model += amount <= (required_change + eps) 35 | 36 | # coins availability 37 | # these are 8 different scalar constraints expressed with tensor notation 38 | model += x <= available, "availability" 39 | 40 | # go and see how the constraint lable was expanded 41 | model.write("numpy_tensor_example.lp") 42 | 43 | model.optimize() 44 | 45 | x_val = np.vectorize(lambda var: var.x)(x) 46 | print("Solution vector: %s" % x_val) 47 | 48 | print("Coins:") 49 | for coin_value, pieces in zip(vals, x_val): 50 | print("%0.2f euro coin: %d" % (coin_value, pieces)) 51 | -------------------------------------------------------------------------------- /examples/queens.py: -------------------------------------------------------------------------------- 1 | """Example of a solver to the n-queens problem: n chess queens should be 2 | placed in a n x n chess board so that no queen can attack another, i.e., just 3 | one queen per line, column and diagonal. """ 4 | 5 | from sys import stdout 6 | from mip import Model, xsum, BINARY 7 | 8 | # number of queens 9 | n = 40 10 | 11 | queens = Model() 12 | 13 | x = [[queens.add_var('x({},{})'.format(i, j), var_type=BINARY) 14 | for j in range(n)] for i in range(n)] 15 | 16 | # one per row 17 | for i in range(n): 18 | queens += xsum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i) 19 | 20 | # one per column 21 | for j in range(n): 22 | queens += xsum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j) 23 | 24 | # diagonal \ 25 | for p, k in enumerate(range(2 - n, n - 2 + 1)): 26 | queens += xsum(x[i][i - k] for i in range(n) 27 | if 0 <= i - k < n) <= 1, 'diag1({})'.format(p) 28 | 29 | # diagonal / 30 | for p, k in enumerate(range(3, n + n)): 31 | queens += xsum(x[i][k - i] for i in range(n) 32 | if 0 <= k - i < n) <= 1, 'diag2({})'.format(p) 33 | 34 | queens.optimize() 35 | 36 | if queens.num_solutions: 37 | stdout.write('\n') 38 | for i, v in enumerate(queens.vars): 39 | stdout.write('O ' if v.x >= 0.99 else '. ') 40 | if i % n == n-1: 41 | stdout.write('\n') 42 | -------------------------------------------------------------------------------- /examples/rcpsp.py: -------------------------------------------------------------------------------- 1 | """Resource Constrained Project Scheduling Problem solver""" 2 | 3 | from itertools import product 4 | from mip import Model, xsum, BINARY 5 | 6 | n = 10 # note there will be exactly 12 jobs (n=10 jobs plus the two 'dummy' ones) 7 | 8 | p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0] 9 | 10 | u = [[0, 0], [5, 1], [0, 4], [1, 4], [1, 3], [3, 2], [3, 1], [2, 4], 11 | [4, 0], [5, 2], [2, 5], [0, 0]] 12 | 13 | c = [6, 8] 14 | 15 | S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6], 16 | [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]] 17 | 18 | (R, J, T) = (range(len(c)), range(len(p)), range(sum(p))) 19 | 20 | model = Model() 21 | 22 | x = [[model.add_var(name="x({},{})".format(j, t), var_type=BINARY) for t in T] for j in J] 23 | 24 | model.objective = xsum(t * x[n + 1][t] for t in T) 25 | 26 | for j in J: 27 | model += xsum(x[j][t] for t in T) == 1 28 | 29 | for (r, t) in product(R, T): 30 | model += ( 31 | xsum(u[j][r] * x[j][t2] for j in J for t2 in range(max(0, t - p[j] + 1), t + 1)) 32 | <= c[r]) 33 | 34 | for (j, s) in S: 35 | model += xsum(t * x[s][t] - t * x[j][t] for t in T) >= p[j] 36 | 37 | model.optimize() 38 | 39 | print("Schedule: ") 40 | for (j, t) in product(J, T): 41 | if x[j][t].x >= 0.99: 42 | print("Job {}: begins at t={} and finishes at t={}".format(j, t, t+p[j])) 43 | print("Makespan = {}".format(model.objective_value)) 44 | 45 | 46 | # sanity tests 47 | from mip import OptimizationStatus 48 | 49 | assert model.status == OptimizationStatus.OPTIMAL 50 | assert abs(model.objective_value - 21) <= 1e-4 51 | model.check_optimization_results() 52 | -------------------------------------------------------------------------------- /examples/test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | for solver in cbc gurobi; 4 | do 5 | for file in knapsack.py jssp.py tsp-compact.py queens.py bmcp.py rcpsp.py cuttingstock_kantorovich.py tsp-cuts.py; 6 | do 7 | export SOLVER_NAME="$solver" 8 | pypy3 $file 9 | done 10 | done 11 | 12 | -------------------------------------------------------------------------------- /examples/tsp-compact.py: -------------------------------------------------------------------------------- 1 | """Example that solves the Traveling Salesman Problem using the simple compact 2 | formulation presented in Miller, C.E., Tucker, A.W and Zemlin, R.A. "Integer 3 | Programming Formulation of Traveling Salesman Problems". Journal of the ACM 4 | 7(4). 1960.""" 5 | 6 | from itertools import product 7 | from sys import stdout as out 8 | from mip import Model, xsum, minimize, BINARY 9 | 10 | # names of places to visit 11 | places = ['Antwerp', 'Bruges', 'C-Mine', 'Dinant', 'Ghent', 12 | 'Grand-Place de Bruxelles', 'Hasselt', 'Leuven', 13 | 'Mechelen', 'Mons', 'Montagne de Bueren', 'Namur', 14 | 'Remouchamps', 'Waterloo'] 15 | 16 | # distances in an upper triangular matrix 17 | dists = [[83, 81, 113, 52, 42, 73, 44, 23, 91, 105, 90, 124, 57], 18 | [161, 160, 39, 89, 151, 110, 90, 99, 177, 143, 193, 100], 19 | [90, 125, 82, 13, 57, 71, 123, 38, 72, 59, 82], 20 | [123, 77, 81, 71, 91, 72, 64, 24, 62, 63], 21 | [51, 114, 72, 54, 69, 139, 105, 155, 62], 22 | [70, 25, 22, 52, 90, 56, 105, 16], 23 | [45, 61, 111, 36, 61, 57, 70], 24 | [23, 71, 67, 48, 85, 29], 25 | [74, 89, 69, 107, 36], 26 | [117, 65, 125, 43], 27 | [54, 22, 84], 28 | [60, 44], 29 | [97], 30 | []] 31 | 32 | # number of nodes and list of vertices 33 | n, V = len(dists), set(range(len(dists))) 34 | 35 | # distances matrix 36 | c = [[0 if i == j 37 | else dists[i][j-i-1] if j > i 38 | else dists[j][i-j-1] 39 | for j in V] for i in V] 40 | 41 | model = Model() 42 | 43 | # binary variables indicating if arc (i,j) is used on the route or not 44 | x = [[model.add_var(var_type=BINARY) for j in V] for i in V] 45 | 46 | # continuous variable to prevent subtours: each city will have a 47 | # different sequential id in the planned route except the first one 48 | y = [model.add_var() for i in V] 49 | 50 | # objective function: minimize the distance 51 | model.objective = minimize(xsum(c[i][j]*x[i][j] for i in V for j in V)) 52 | 53 | # constraint : leave each city only once 54 | for i in V: 55 | model += xsum(x[i][j] for j in V - {i}) == 1 56 | 57 | # constraint : enter each city only once 58 | for i in V: 59 | model += xsum(x[j][i] for j in V - {i}) == 1 60 | 61 | # subtour elimination 62 | for (i, j) in product(V - {0}, V - {0}): 63 | if i != j: 64 | model += y[i] - (n+1)*x[i][j] >= y[j]-n 65 | 66 | # optimizing 67 | model.optimize() 68 | 69 | # checking if a solution was found 70 | if model.num_solutions: 71 | out.write('route with total distance %g found: %s' 72 | % (model.objective_value, places[0])) 73 | nc = 0 74 | while True: 75 | nc = [i for i in V if x[nc][i].x >= 0.99][0] 76 | out.write(' -> %s' % places[nc]) 77 | if nc == 0: 78 | break 79 | out.write('\n') 80 | 81 | # sanity tests 82 | from mip import OptimizationStatus 83 | assert model.status == OptimizationStatus.OPTIMAL 84 | assert round(model.objective_value) == 547 85 | model.check_optimization_results() 86 | -------------------------------------------------------------------------------- /examples/two-dim-pack.py: -------------------------------------------------------------------------------- 1 | """Example of modeling and solving the two dimensional level 2 | packing problem in Python-MIP. 3 | """ 4 | from mip import Model, BINARY, minimize, xsum 5 | 6 | # 0 1 2 3 4 5 6 7 7 | w = [4, 3, 5, 2, 1, 4, 7, 3] # widths 8 | h = [2, 4, 1, 5, 6, 3, 5, 4] # heights 9 | n = len(w) 10 | I = set(range(n)) 11 | S = [[j for j in I if h[j] <= h[i]] for i in I] 12 | G = [[j for j in I if h[j] >= h[i]] for i in I] 13 | 14 | # raw material width 15 | W = 10 16 | 17 | m = Model() 18 | 19 | x = [{j: m.add_var(var_type=BINARY) for j in S[i]} for i in I] 20 | 21 | m.objective = minimize(xsum(h[i] * x[i][i] for i in I)) 22 | 23 | # each item should appear as larger item of the level 24 | # or as an item which belongs to the level of another item 25 | for i in I: 26 | m += xsum(x[j][i] for j in G[i]) == 1 27 | 28 | # represented items should respect remaining width 29 | for i in I: 30 | m += xsum(w[j] * x[i][j] for j in S[i] if j != i) <= (W - w[i]) * x[i][i] 31 | 32 | m.optimize() 33 | 34 | for i in [j for j in I if x[j][j].x >= 0.99]: 35 | print( 36 | "Items grouped with {} : {}".format( 37 | i, [j for j in S[i] if i != j and x[i][j].x >= 0.99] 38 | ) 39 | ) 40 | 41 | # sanity tests 42 | from mip import OptimizationStatus 43 | 44 | assert m.status == OptimizationStatus.OPTIMAL 45 | assert round(m.objective_value) == 12 46 | -------------------------------------------------------------------------------- /examples/ulysses22.tsp: -------------------------------------------------------------------------------- 1 | NAME: ulysses22.tsp 2 | TYPE: TSP 3 | COMMENT: Odyssey of Ulysses (Groetschel/Padberg) 4 | DIMENSION: 22 5 | EDGE_WEIGHT_TYPE: GEO 6 | DISPLAY_DATA_TYPE: COORD_DISPLAY 7 | NODE_COORD_SECTION 8 | 1 38.24 20.42 9 | 2 39.57 26.15 10 | 3 40.56 25.32 11 | 4 36.26 23.12 12 | 5 33.48 10.54 13 | 6 37.56 12.19 14 | 7 38.42 13.11 15 | 8 37.52 20.44 16 | 9 41.23 9.10 17 | 10 41.17 13.05 18 | 11 36.08 -5.21 19 | 12 38.47 15.13 20 | 13 38.15 15.35 21 | 14 37.51 15.17 22 | 15 35.49 14.32 23 | 16 39.36 19.56 24 | 17 38.09 24.36 25 | 18 36.09 23.00 26 | 19 40.44 13.57 27 | 20 40.33 14.15 28 | 21 40.37 14.23 29 | 22 37.57 22.56 30 | EOF 31 | -------------------------------------------------------------------------------- /mip/__init__.py: -------------------------------------------------------------------------------- 1 | from mip.constants import * 2 | from mip.solver import Solver 3 | from mip.callbacks import * 4 | from mip.log import ProgressLog 5 | from mip.lists import ConstrList, VarList, VConstrList, VVarList 6 | from mip.exceptions import * 7 | from mip.ndarray import LinExprTensor 8 | from mip.entities import Column, Constr, LinExpr, Var, ConflictGraph 9 | from mip.model import * 10 | 11 | try: 12 | from ._version import __version__ 13 | except ImportError: 14 | __version__ = "unknown" 15 | 16 | name = "mip" 17 | -------------------------------------------------------------------------------- /mip/exceptions.py: -------------------------------------------------------------------------------- 1 | """Python-MIP Exceptions""" 2 | 3 | 4 | class MipBaseException(Exception): 5 | """Base class for all exceptions specific to Python MIP. Only sub-classes 6 | of this exception are raised. 7 | Inherits from the Python builtin ``Exception``.""" 8 | 9 | 10 | class ProgrammingError(MipBaseException): 11 | """Exception that is raised when the calling program performs an invalid 12 | or nonsensical operation. 13 | Inherits from :attr:`mip.MipBaseException`.""" 14 | 15 | 16 | class InterfacingError(MipBaseException): 17 | """Exception that is raised when an unknown error occurs while interfacing 18 | with a solver. 19 | Inherits from :attr:`mip.MipBaseException`.""" 20 | 21 | 22 | class InvalidLinExpr(MipBaseException): 23 | """Exception that is raised when an invalid 24 | linear expression is created. 25 | Inherits from :attr:`mip.MipBaseException`.""" 26 | 27 | 28 | class InvalidParameter(MipBaseException): 29 | """Exception that is raised when an invalid/non-existent 30 | parameter is used or set. 31 | Inherits from :attr:`mip.MipBaseException`.""" 32 | 33 | 34 | class ParameterNotAvailable(MipBaseException): 35 | """Exception that is raised when some parameter is not 36 | available or can not be set. 37 | Inherits from :attr:`mip.MipBaseException`.""" 38 | 39 | 40 | class InfeasibleSolution(MipBaseException): 41 | """Exception that is raised the produced solution 42 | is unfeasible. 43 | Inherits from :attr:`mip.MipBaseException`.""" 44 | 45 | 46 | class SolutionNotAvailable(MipBaseException): 47 | """Exception that is raised when a method that requires 48 | a solution is queried but the solution is not available. 49 | Inherits from :attr:`mip.MipBaseException`.""" 50 | -------------------------------------------------------------------------------- /mip/libraries/cbc-c-darwin-arm64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/cbc-c-darwin-arm64.dylib -------------------------------------------------------------------------------- /mip/libraries/cbc-c-darwin-x86-64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/cbc-c-darwin-x86-64.dylib -------------------------------------------------------------------------------- /mip/libraries/cbc-c-linux-x86-64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/cbc-c-linux-x86-64.so -------------------------------------------------------------------------------- /mip/libraries/win64/cbc-c-windows-x86-64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/win64/cbc-c-windows-x86-64.dll -------------------------------------------------------------------------------- /mip/libraries/win64/libbz2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/win64/libbz2-1.dll -------------------------------------------------------------------------------- /mip/libraries/win64/libgcc_s_seh-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/win64/libgcc_s_seh-1.dll -------------------------------------------------------------------------------- /mip/libraries/win64/libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/win64/libstdc++-6.dll -------------------------------------------------------------------------------- /mip/libraries/win64/libwinpthread-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/mip/libraries/win64/libwinpthread-1.dll -------------------------------------------------------------------------------- /mip/log.py: -------------------------------------------------------------------------------- 1 | class ProgressLog: 2 | """Class to store the improvement of lower 3 | and upper bounds over time during the search. 4 | Results stored here are useful to analyze the 5 | performance of a given formulation/parameter setting 6 | for solving a instance. To be able to automatically 7 | generate summarized experimental results, fill the 8 | :attr:`~mip.ProgressLog.instance` and 9 | :attr:`~mip.ProgressLog.settings` of this object with the instance 10 | name and formulation/parameter setting details, respectively. 11 | 12 | Attributes: 13 | 14 | log(List[Tuple[float, Tuple[float, float]]]): List of tuples in the format 15 | :math:`(time, (lb, ub))`, where :math:`time` is the processing time 16 | in seconds and :math:`lb` and :math:`ub` are the lower and upper bounds, 17 | respectively 18 | 19 | instance(str): instance name 20 | 21 | settings(str): identification of the formulation/parameter 22 | settings used in the optimization (whatever is relevant to 23 | identify a given computational experiment) 24 | """ 25 | 26 | def __init__(self): 27 | self.log = [] 28 | 29 | self.instance = "" 30 | 31 | self.settings = "" 32 | 33 | def write(self, file_name: str = ""): 34 | """Saves the progress log. If no extension is informed, 35 | the :code:`.plog` extension will be used. If only a directory is 36 | informed then the name will be built considering the 37 | :attr:`~mip.ProgressLog.instance` and 38 | :attr:`~mip.ProgressLog.settings` attributes""" 39 | if not self.instance: 40 | raise ValueError( 41 | "Enter model name (instance name) to save experimental data." 42 | ) 43 | if not file_name: 44 | file_name = "{}-{}.plog".format(self.instance, self.settings) 45 | else: 46 | if file_name.endswith("/") or file_name.endswith("\\"): 47 | file_name += "{}-{}.plog".format(self.instance, self.settings) 48 | 49 | if not file_name.endswith(".plog"): 50 | file_name += ".plog" 51 | 52 | f = open(file_name, "w") 53 | f.write("instance: {}".format(self.instance)) 54 | f.write("settings: {}".format(self.settings)) 55 | for (s, (l, b)) in self.log: 56 | f.write("{},{},{}".format(s, l, b)) 57 | f.close() 58 | 59 | def read(self, file_name: str): 60 | """Reads a progress log stored in a file""" 61 | f = open(file_name, "r") 62 | lin = f.next() 63 | self.instance = lin.split(":")[1].lstrip() 64 | self.settings = lin.split(":")[1].lstrip() 65 | for lin in f: 66 | cols = lin.split(",") 67 | (s, (l, b)) = (float(cols[0]), (float(cols[1]), float(cols[2]))) 68 | self.log.append((s, (l, b))) 69 | f.close() 70 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "setuptools-scm"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "mip" 7 | description = "Python tools for Modeling and Solving Mixed-Integer Linear Programs (MIPs)" 8 | readme = "README.md" 9 | requires-python = ">=3.7,<3.13" 10 | license = {file = "LICENSE"} 11 | authors = [ 12 | {name="Tulio A.M. Toffolo", email="tulio@toffolo.com.br"}, 13 | {name="Haroldo G. Santos", email="haroldo.santos@gmail.com"} 14 | ] 15 | keywords = [ 16 | "Optimization", 17 | "Linear Programming", 18 | "Integer Programming", 19 | "Operations Research", 20 | ] 21 | classifiers = [ 22 | "Development Status :: 5 - Production/Stable", 23 | "License :: OSI Approved :: Eclipse Public License 2.0 (EPL-2.0)", 24 | "Operating System :: OS Independent", 25 | "Programming Language :: Python :: 3", 26 | "Programming Language :: Python :: Implementation :: CPython", 27 | "Programming Language :: Python :: Implementation :: PyPy", 28 | "Topic :: Scientific/Engineering :: Mathematics" 29 | ] 30 | dynamic = ["version"] 31 | 32 | dependencies = ["cffi>=1.15"] 33 | 34 | [project.optional-dependencies] 35 | numpy = [ 36 | "numpy>=1.25; python_version>='3.9'", 37 | "numpy==1.24.*; python_version=='3.8'", 38 | "numpy==1.21.*; python_version=='3.7'" 39 | ] 40 | gurobi = ["gurobipy>=8"] 41 | highs = ["highspy>=1.5.3; python_version<='3.11'"] 42 | test = [ 43 | "pytest>=7.4", 44 | "networkx==2.8.8; python_version>='3.8'", 45 | "networkx==2.6.3; python_version=='3.7'", 46 | "matplotlib>=3.7; python_version>='3.9'", 47 | "matplotlib==3.6.2; python_version=='3.8'", 48 | "matplotlib==3.5.3; python_version=='3.7'" 49 | ] 50 | 51 | [project.urls] 52 | "Homepage" = "https://www.python-mip.com" 53 | "Repository" = "https://github.com/coin-or/python-mip" 54 | 55 | [tool.setuptools] 56 | packages = ["mip"] 57 | 58 | [tool.setuptools.package-data] 59 | "mip.libraries" = ["*.so", "*.dylib", "*.dll"] 60 | 61 | [tool.setuptools_scm] 62 | write_to = "mip/_version.py" 63 | -------------------------------------------------------------------------------- /scripts/buildCBCLinux.sh: -------------------------------------------------------------------------------- 1 | export CFLAGS="-Ofast -fPIC -flto -DNDEBUG -fprefetch-loop-arrays -I/opt/gcc/include/" 2 | export FFLAGS="-Ofast -fPIC -flto -DNDEBUG -I/opt/gcc/include/" 3 | export CXXFLAGS="-Ofast -fPIC -flto -fprefetch-loop-arrays -DNDEBUG -I/opt/gcc/include/" 4 | export LDFLAGS="-Ofast -fPIC -L/opt/gcc/lib -flto -static-libgcc -static-libstdc++ -static-libgfortran" 5 | 6 | dir=`pwd` 7 | mkdir -p ~/prog 8 | cd ~/prog 9 | IDIR=`pwd` 10 | export PKG_CONFIG_PATH=${IDIR}/lib/pkgconfig/:${PKG_CONFIG_PATH} 11 | 12 | #cd $dir/ThirdParty-Metis 13 | #./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 14 | #make -j 6 15 | #make -j 6 install 16 | 17 | cd $dir/ThirdParty-Blas 18 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 19 | make -j 6 20 | make -j 6 install 21 | 22 | cd $dir/ThirdParty-Lapack 23 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 24 | make -j 6 25 | make -j 6 install 26 | 27 | #cd $dir/ThirdParty-Mumps 28 | #./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 29 | #make -j 6 30 | #make -j 6 install 31 | 32 | cd $dir/ThirdParty-Glpk 33 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 34 | make -j 6 35 | make -j 6 install 36 | 37 | 38 | cd $dir/CoinUtils 39 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 40 | make -j 6 41 | make -j 6 install 42 | 43 | cd $dir/Osi 44 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 45 | make -j 6 46 | make -j 6 install 47 | 48 | cd $dir/Clp 49 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 50 | make -j 6 51 | make -j 6 install 52 | 53 | cd $dir/Cgl 54 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 55 | make -j 6 56 | make -j 6 install 57 | 58 | 59 | cd $dir/Cbc 60 | ./configure --prefix=$IDIR --enable-cbc-parallel --enable-static --disable-shared --enable-gnu-packages 61 | make -j 6 62 | make -j 6 install 63 | 64 | cd $dir 65 | 66 | g++ -shared -Ofast -fPIC -o ../mip/libraries/cbc-c-linux-x86-64.so \ 67 | -I${IDIR}/include/coin-or/ \ 68 | -DCBC_THREAD \ 69 | ./Cbc/src/Cbc_C_Interface.cpp \ 70 | -L/opt/gcc/lib64/ -L${IDIR}/lib/ \ 71 | -lCbcSolver -lCbc -lpthread -lrt -lCgl -lOsiClp -lClpSolver -lClp -lOsi -lCoinUtils \ 72 | -lcoinlapack -lcoinblas -lgfortran -lquadmath -lm -static-libgcc -static-libstdc++ -static-libgfortran -lcoinglpk 73 | -------------------------------------------------------------------------------- /scripts/buildCBCLinuxAs.sh: -------------------------------------------------------------------------------- 1 | export CFLAGS="-Og -fPIC -g -fsanitize=address" 2 | export FFLAGS="-Og -fPIC -g -fsanitize=address" 3 | export CXXFLAGS="-Og -fPIC -g -fsanitize=address" 4 | export LDFLAGS="-Og -fPIC -g -static-libgcc -static-libstdc++ -fsanitize=address" 5 | 6 | dir=`pwd` 7 | mkdir -p ~/prog 8 | cd ~/prog 9 | IDIR=`pwd` 10 | export PKG_CONFIG_PATH=${IDIR}/lib/pkgconfig/:${PKG_CONFIG_PATH} 11 | 12 | cd $dir/CoinUtils 13 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 14 | make -j 6 15 | make -j 6 install 16 | 17 | cd $dir/Osi 18 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 19 | make -j 6 20 | make -j 6 install 21 | 22 | cd $dir/Clp 23 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 24 | make -j 6 25 | make -j 6 install 26 | 27 | cd $dir/Cgl 28 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 29 | make -j 6 30 | make -j 6 install 31 | 32 | 33 | cd $dir/Cbc 34 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 35 | make -j 6 36 | make -j 6 install 37 | 38 | cd $dir 39 | 40 | -------------------------------------------------------------------------------- /scripts/buildCBCLinuxDbg.sh: -------------------------------------------------------------------------------- 1 | export CFLAGS="-Og -fPIC -g3 -DDEBUG" 2 | export FFLAGS="-Og -fPIC -g3" 3 | export CXXFLAGS="-Og -fPIC -g3 -DDEBUG" 4 | export LDFLAGS="-Og -fPIC -g" 5 | 6 | dir=`pwd` 7 | mkdir -p ~/prog 8 | cd ~/prog 9 | IDIR=`pwd` 10 | export PKG_CONFIG_PATH=${IDIR}/lib/pkgconfig/:${PKG_CONFIG_PATH} 11 | 12 | #cd $dir/ThirdParty-Glpk 13 | #make clean ; make distclean 14 | #./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 15 | #make -j 6 16 | #make -j 6 install 17 | 18 | 19 | #cd $dir/ThirdParty-Lapack 20 | #make clean ; make distclean 21 | #./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --disable-shared 22 | #make -j 6 23 | #make -j 6 install 24 | 25 | #cd $dir/ThirdParty-Blas 26 | #make clean ; make distclean 27 | #./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-static --enable-shared 28 | #make -j 6 29 | #make -j 6 install 30 | 31 | cd $dir/CoinUtils 32 | make clean ; make distclean 33 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-shared 34 | make -j 6 35 | make -j 6 install 36 | 37 | cd $dir/Osi 38 | make clean ; make distclean 39 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-shared 40 | make -j 6 41 | make -j 6 install 42 | 43 | cd $dir/Clp 44 | make clean ; make distclean 45 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-shared 46 | make -j 6 47 | make -j 6 install 48 | 49 | cd $dir/Cgl 50 | make clean ; make distclean 51 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-shared 52 | make -j 6 53 | make -j 6 install 54 | 55 | cd $dir/Cbc 56 | make clean ; make distclean 57 | ./configure --prefix=$IDIR --without-lapack --without-glpk --without-blas --enable-shared 58 | make -j 6 59 | make -j 6 install 60 | 61 | exit 62 | 63 | 64 | for libfile in $IDIR/lib/*.so*; 65 | do 66 | chrpath -r ./ $libfile 67 | done 68 | 69 | chrpath -r \$\ORIGIN/../lib/ $IDIR/bin/cbc 70 | chrpath -r \$\ORIGIN/../lib/ $IDIR/bin/clp 71 | 72 | cd $dir 73 | -------------------------------------------------------------------------------- /scripts/buildCBCMac.sh: -------------------------------------------------------------------------------- 1 | export MACOSX_DEPLOYMENT_TARGET="10.7" 2 | export CFLAGS="-fPIC -Ofast -DNDEBUG -ffast-math -mmacosx-version-min=10.7" 3 | export CXXFLAGS="-fPIC -Og -DNDEBUG -ffast-math -std=c++11 -stdlib=libc++ -mmacosx-version-min=10.7" 4 | export F77FLAGS="-fPIC -Ofast -DNDEBUG -ffast-math" 5 | export LDFLAGS="-fPIC -Ofast -DNDEBUG -ffast-math" 6 | 7 | DIR=`pwd` 8 | OUTDIR="/opt/cbc/bin" 9 | export PKG_CONFIG_PATH="${OUTDIR}/lib/pkgconfig/:${PKG_CONFIG_PATH}" 10 | 11 | echo 12 | echo "Making and installing Glpk" 13 | cd ${DIR}/ThirdParty-Glpk 14 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 15 | git pull 16 | make 17 | make install 18 | 19 | echo 20 | echo "Making and installing Lapack" 21 | cd ${DIR}/ThirdParty-Lapack 22 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 23 | git pull 24 | make 25 | make install 26 | 27 | echo 28 | echo "Making and installing Blas" 29 | cd ${DIR}/ThirdParty-Blas 30 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 31 | git pull 32 | make 33 | make install 34 | 35 | echo 36 | echo "Making and installing CoinUtils" 37 | cd ${DIR}/CoinUtils 38 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 39 | git pull 40 | make 41 | make install 42 | 43 | echo 44 | echo "Making and installing Osi" 45 | cd ${DIR}/Osi 46 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 47 | git pull 48 | make 49 | make install 50 | 51 | echo 52 | echo "Making and installing Clp" 53 | cd ${DIR}/Clp 54 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 55 | git pull 56 | make 57 | make install 58 | 59 | echo 60 | echo "Making and installing Cgl" 61 | cd ${DIR}/Cgl 62 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared --without-glpk 63 | git pull 64 | make 65 | make install 66 | 67 | echo 68 | echo "Making and installing Cbc" 69 | cd ${DIR}/Cbc 70 | ./configure --prefix=${OUTDIR}/ --enable-cbc-parallel --enable-static --disable-shared --without-glpk 71 | git pull 72 | make 73 | make install 74 | 75 | echo 76 | echo "Compiling dynamic library" 77 | cd ${DIR} 78 | clang++ -shared -Ofast -fPIC -o cbc-c-darwin-x86-64.dylib \ 79 | -I${OUTDIR}/include/coin-or/ -I${OUTDIR}/include/coin -L${OUTDIR}/lib \ 80 | ./Cbc/src/Cbc_C_Interface.cpp \ 81 | -lCbcSolver -lCbc -lCgl -lOsiClp -lClpSolver -lClp -lOsi -lCoinUtils \ 82 | -lbz2 -lz -llapack ${CXXFLAGS} -stdlib=libc++ -lreadline 83 | echo "Done!" 84 | -------------------------------------------------------------------------------- /scripts/buildCBCMacARM.sh: -------------------------------------------------------------------------------- 1 | export MACOSX_DEPLOYMENT_TARGET="10.9" 2 | export CFLAGS="-fPIC -Ofast -DNDEBUG -ffast-math -mmacosx-version-min=10.9" 3 | export CXXFLAGS="-fPIC -Og -DNDEBUG -ffast-math -std=c++11 -stdlib=libc++ -mmacosx-version-min=10.9" 4 | export F77FLAGS="-fPIC -Ofast -DNDEBUG -ffast-math" 5 | export LDFLAGS="-fPIC -Ofast -DNDEBUG -ffast-math" 6 | 7 | DIR=`pwd` 8 | OUTDIR="/opt/cbc/bin" 9 | export PKG_CONFIG_PATH="${OUTDIR}/lib/pkgconfig/:${PKG_CONFIG_PATH}" 10 | 11 | echo 12 | echo "Making and installing Glpk" 13 | cd ${DIR}/ThirdParty-Glpk 14 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 15 | git pull 16 | make 17 | make install 18 | 19 | echo 20 | echo "Making and installing Lapack" 21 | cd ${DIR}/ThirdParty-Lapack 22 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 23 | git pull 24 | make 25 | make install 26 | 27 | echo 28 | echo "Making and installing Blas" 29 | cd ${DIR}/ThirdParty-Blas 30 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 31 | git pull 32 | make 33 | make install 34 | 35 | echo 36 | echo "Making and installing CoinUtils" 37 | cd ${DIR}/CoinUtils 38 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 39 | git pull 40 | make 41 | make install 42 | 43 | echo 44 | echo "Making and installing Osi" 45 | cd ${DIR}/Osi 46 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 47 | git pull 48 | make 49 | make install 50 | 51 | echo 52 | echo "Making and installing Clp" 53 | cd ${DIR}/Clp 54 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 55 | git pull 56 | make 57 | make install 58 | 59 | echo 60 | echo "Making and installing Cgl" 61 | cd ${DIR}/Cgl 62 | ./configure --prefix=${OUTDIR}/ --enable-static --disable-shared 63 | git pull 64 | make 65 | make install 66 | 67 | echo 68 | echo "Making and installing Cbc" 69 | cd ${DIR}/Cbc 70 | ./configure --prefix=${OUTDIR}/ --enable-cbc-parallel --enable-static --disable-shared 71 | git pull 72 | make 73 | make install 74 | 75 | echo 76 | echo "Compiling dynamic library" 77 | cd ${DIR} 78 | clang++ -shared -Ofast -fPIC -o cbc-c-darwin-arm64.dylib \ 79 | -I${OUTDIR}/include/coin-or/ -I${OUTDIR}/include/coin-or/glpk -I${OUTDIR}/include/coin \ 80 | -L${OUTDIR}/lib \ 81 | ./Cbc/src/Cbc_C_Interface.cpp \ 82 | -lCbc -lCgl -lClp -lCoinUtils -lOsi -lOsiCbc -lOsiClp -lOsiGlpk \ 83 | -lcoinblas -lcoinglpk -lcoinlapack \ 84 | -lbz2 -lz -llapack ${CXXFLAGS} -stdlib=libc++ -lreadline 85 | echo "Done!" 86 | -------------------------------------------------------------------------------- /scripts/buildMSV.bat: -------------------------------------------------------------------------------- 1 | msbuild Cbc\MSVisualStudio\v16\Cbc.sln -t:Build -p:Configuration=Release;Platform=x64 -target:cbcCInterfaceDll 2 | -------------------------------------------------------------------------------- /scripts/downloadCBC.sh: -------------------------------------------------------------------------------- 1 | echo "Checking CoinUtils" 2 | if [[ -d CoinUtils ]] 3 | then 4 | cd CoinUtils 5 | git pull 6 | cd .. 7 | else 8 | git clone https://github.com/coin-or/CoinUtils 9 | fi 10 | 11 | echo "Checking Osi" 12 | if [[ -d Osi ]] 13 | then 14 | cd Osi 15 | git pull 16 | cd .. 17 | else 18 | git clone https://github.com/coin-or/Osi 19 | fi 20 | 21 | echo "Checking Clp" 22 | if [[ -d Clp ]] 23 | then 24 | cd Clp 25 | git pull 26 | cd .. 27 | else 28 | git clone https://github.com/coin-or/Clp 29 | fi 30 | 31 | echo "Checking Cgl" 32 | if [[ -d Cgl ]] 33 | then 34 | cd Cgl 35 | git pull 36 | cd .. 37 | else 38 | git clone https://github.com/coin-or/Cgl 39 | fi 40 | 41 | echo "Checking Cbc" 42 | if [[ -d Cbc ]] 43 | then 44 | cd Cbc 45 | git pull 46 | cd .. 47 | else 48 | git clone https://github.com/coin-or/Cbc 49 | fi 50 | 51 | echo "Checking Glpk" 52 | if [[ -d ThirdParty-Glpk ]] 53 | then 54 | cd ThirdParty-Glpk 55 | git pull 56 | ./get.Glpk 57 | cd .. 58 | else 59 | git clone https://github.com/coin-or-tools/ThirdParty-Glpk.git 60 | cd ThirdParty-Glpk 61 | ./get.Glpk 62 | cd ../ 63 | fi 64 | 65 | echo "Checking Lapack" 66 | if [[ -d ThirdParty-Lapack ]] 67 | then 68 | cd ThirdParty-Lapack 69 | git pull 70 | ./get.Lapack 71 | cd .. 72 | else 73 | git clone https://github.com/coin-or-tools/ThirdParty-Lapack.git 74 | cd ThirdParty-Lapack 75 | ./get.Lapack 76 | cd ../ 77 | fi 78 | 79 | echo "Checking Blas" 80 | if [[ -d ThirdParty-Blas ]] 81 | then 82 | cd ThirdParty-Blas 83 | git pull 84 | ./get.Blas 85 | cd .. 86 | else 87 | git clone https://github.com/coin-or-tools/ThirdParty-Blas.git 88 | cd ThirdParty-Blas 89 | ./get.Blas 90 | cd ../ 91 | fi 92 | -------------------------------------------------------------------------------- /scripts/downloadCBConly.sh: -------------------------------------------------------------------------------- 1 | echo "Checking CoinUtils" 2 | if [[ -d CoinUtils ]] 3 | then 4 | cd CoinUtils 5 | git pull 6 | cd .. 7 | else 8 | git clone https://github.com/coin-or/CoinUtils 9 | fi 10 | 11 | echo "Checking Osi" 12 | if [[ -d Osi ]] 13 | then 14 | cd Osi 15 | git pull 16 | cd .. 17 | else 18 | git clone https://github.com/coin-or/Osi 19 | fi 20 | 21 | echo "Checking Clp" 22 | if [[ -d Clp ]] 23 | then 24 | cd Clp 25 | git pull 26 | cd .. 27 | else 28 | git clone https://github.com/coin-or/Clp 29 | fi 30 | 31 | echo "Checking Cgl" 32 | if [[ -d Cgl ]] 33 | then 34 | cd Cgl 35 | git pull 36 | cd .. 37 | else 38 | git clone https://github.com/coin-or/Cgl 39 | fi 40 | 41 | echo "Checking Cbc" 42 | if [[ -d Cbc ]] 43 | then 44 | cd Cbc 45 | git pull 46 | cd .. 47 | else 48 | git clone https://github.com/coin-or/Cbc 49 | fi 50 | 51 | -------------------------------------------------------------------------------- /scripts/downloadCBConlysvn.sh: -------------------------------------------------------------------------------- 1 | echo "Checking CoinUtils" 2 | if [[ -d CoinUtils ]] 3 | then 4 | cd CoinUtils 5 | svn up 6 | cd .. 7 | else 8 | svn co https://projects.coin-or.org/svn/CoinUtils/trunk/ CoinUtils 9 | fi 10 | 11 | echo "Checking Osi" 12 | if [[ -d Osi ]] 13 | then 14 | cd Osi 15 | svn up 16 | cd .. 17 | else 18 | svn co https://projects.coin-or.org/svn/Osi/trunk/ Osi 19 | fi 20 | 21 | echo "Checking Clp" 22 | if [[ -d Clp ]] 23 | then 24 | cd Clp 25 | svn up 26 | cd .. 27 | else 28 | svn co https://projects.coin-or.org/svn/Clp/trunk/ Clp 29 | fi 30 | 31 | echo "Checking Cgl" 32 | if [[ -d Cgl ]] 33 | then 34 | cd Cgl 35 | svn up 36 | cd .. 37 | else 38 | svn co https://projects.coin-or.org/svn/Cgl/trunk/ Cgl 39 | fi 40 | 41 | echo "Checking Cbc" 42 | if [[ -d Cbc ]] 43 | then 44 | cd Cbc 45 | svn up 46 | cd .. 47 | else 48 | svn co https://projects.coin-or.org/svn/Cbc/trunk/ Cbc 49 | fi 50 | 51 | -------------------------------------------------------------------------------- /scripts/downloadCBCsvn.sh: -------------------------------------------------------------------------------- 1 | echo "Checking CoinUtils" 2 | if [[ -d CoinUtils ]] 3 | then 4 | cd CoinUtils 5 | svn up 6 | cd .. 7 | else 8 | svn co https://projects.coin-or.org/svn/CoinUtils/trunk/ CoinUtils 9 | fi 10 | 11 | echo "Checking Osi" 12 | if [[ -d Osi ]] 13 | then 14 | cd Osi 15 | svn up 16 | cd .. 17 | else 18 | svn co https://projects.coin-or.org/svn/Osi/trunk/ Osi 19 | fi 20 | 21 | echo "Checking Clp" 22 | if [[ -d Clp ]] 23 | then 24 | cd Clp 25 | svn up 26 | cd .. 27 | else 28 | svn co https://projects.coin-or.org/svn/Clp/trunk/ Clp 29 | fi 30 | 31 | echo "Checking Cgl" 32 | if [[ -d Cgl ]] 33 | then 34 | cd Cgl 35 | svn up 36 | cd .. 37 | else 38 | svn co https://projects.coin-or.org/svn/Cgl/trunk/ Cgl 39 | fi 40 | 41 | echo "Checking Cbc" 42 | if [[ -d Cbc ]] 43 | then 44 | cd Cbc 45 | svn up 46 | cd .. 47 | else 48 | svn co https://projects.coin-or.org/svn/Cbc/trunk/ Cbc 49 | fi 50 | 51 | echo "Checking Glpk" 52 | if [[ -d ThirdParty-Glpk ]] 53 | then 54 | cd ThirdParty-Glpk 55 | git pull 56 | ./get.Glpk 57 | cd .. 58 | else 59 | git clone https://github.com/coin-or-tools/ThirdParty-Glpk.git 60 | cd ThirdParty-Glpk 61 | ./get.Glpk 62 | cd ../ 63 | fi 64 | 65 | echo "Checking Lapack" 66 | if [[ -d ThirdParty-Lapack ]] 67 | then 68 | cd ThirdParty-Lapack 69 | git pull 70 | ./get.Lapack 71 | cd .. 72 | else 73 | git clone https://github.com/coin-or-tools/ThirdParty-Lapack.git 74 | cd ThirdParty-Lapack 75 | ./get.Lapack 76 | cd ../ 77 | fi 78 | 79 | echo "Checking Blas" 80 | if [[ -d ThirdParty-Blas ]] 81 | then 82 | cd ThirdParty-Blas 83 | git pull 84 | ./get.Blas 85 | cd .. 86 | else 87 | git clone https://github.com/coin-or-tools/ThirdParty-Blas.git 88 | cd ThirdParty-Blas 89 | ./get.Blas 90 | cd ../ 91 | fi 92 | 93 | echo "Checking Mumps" 94 | if [[ -d ThirdParty-Mumps ]] 95 | then 96 | cd ThirdParty-Mumps 97 | git pull 98 | ./get.Mumps 99 | cd .. 100 | else 101 | git clone https://github.com/coin-or-tools/ThirdParty-Mumps.git 102 | cd ThirdParty-Mumps 103 | ./get.Mumps 104 | cd ../ 105 | fi 106 | 107 | echo "Checking Metis" 108 | if [[ -d ThirdParty-Metis ]] 109 | then 110 | cd ThirdParty-Metis 111 | git pull 112 | ./get.Metis 113 | cd .. 114 | else 115 | git clone https://github.com/coin-or-tools/ThirdParty-Metis.git 116 | cd ThirdParty-Metis 117 | ./get.Metis 118 | cd ../ 119 | fi 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /scripts/patchLibrariesLinux.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # patchLibraries.sh 4 | # Copyright (C) 2020 haroldo 5 | # 6 | # Distributed under terms of the MIT license. 7 | # 8 | 9 | 10 | for lib in libCbcSolver.so libcholmod.so.1.7.1 libClp.so libCoinUtils.so libOsi.so libOsiClp.so libCbc.so libCgl.so libClpSolver.so libamd.so.2.2.0 libcholmod.so.1.7.1 libblas.so.3gf libamd.so.2.2.0 libcoinmumps.so libcoinglpk.so libcoinasl.so libreadline.so.6 liblapack.so.3gf libblas.so.3gf; 11 | do 12 | echo patching "$lib" 13 | #patchelf --set-rpath ./ ../mip/libraries/lin64/$lib 14 | echo $lib 15 | chrpath -r $lib 16 | done 17 | 18 | if [ -f ../mip/libraries/lin64/cbc.bin ]; 19 | then 20 | chrpath -r ./ ../mip/libraries/lin64/cbc.bin 21 | 22 | #patchelf --set-rpath ./ ../mip/libraries/lin64/cbc.bin 23 | fi 24 | -------------------------------------------------------------------------------- /scripts/updateDist.sh: -------------------------------------------------------------------------------- 1 | rm dist/* 2 | python -m pip install build 3 | python -m build 4 | -------------------------------------------------------------------------------- /scripts/uploadPip.sh: -------------------------------------------------------------------------------- 1 | python3 -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/* 2 | -------------------------------------------------------------------------------- /test/conftest.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def pytest_configure(config): 5 | import sys 6 | sys._called_from_test = True 7 | 8 | 9 | def pytest_unconfigure(config): 10 | if hasattr(sys, '_called_from_test'): 11 | del sys._called_from_test 12 | -------------------------------------------------------------------------------- /test/data/10teams.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/10teams.mps.gz -------------------------------------------------------------------------------- /test/data/air04.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/air04.mps.gz -------------------------------------------------------------------------------- /test/data/air05.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/air05.mps.gz -------------------------------------------------------------------------------- /test/data/arki001.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/arki001.mps.gz -------------------------------------------------------------------------------- /test/data/bell3a.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/bell3a.mps.gz -------------------------------------------------------------------------------- /test/data/bell5.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/bell5.mps.gz -------------------------------------------------------------------------------- /test/data/blend2.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/blend2.mps.gz -------------------------------------------------------------------------------- /test/data/cap6000.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/cap6000.mps.gz -------------------------------------------------------------------------------- /test/data/dano3mip.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/dano3mip.mps.gz -------------------------------------------------------------------------------- /test/data/danoint.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/danoint.mps.gz -------------------------------------------------------------------------------- /test/data/dcmulti.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/dcmulti.mps.gz -------------------------------------------------------------------------------- /test/data/egout.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/egout.mps.gz -------------------------------------------------------------------------------- /test/data/enigma.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/enigma.mps.gz -------------------------------------------------------------------------------- /test/data/fast0507.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/fast0507.mps.gz -------------------------------------------------------------------------------- /test/data/fiber.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/fiber.mps.gz -------------------------------------------------------------------------------- /test/data/fixnet6.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/fixnet6.mps.gz -------------------------------------------------------------------------------- /test/data/flugpl.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/flugpl.mps.gz -------------------------------------------------------------------------------- /test/data/gen.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gen.mps.gz -------------------------------------------------------------------------------- /test/data/gesa2.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gesa2.mps.gz -------------------------------------------------------------------------------- /test/data/gesa2_o.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gesa2_o.mps.gz -------------------------------------------------------------------------------- /test/data/gesa3.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gesa3.mps.gz -------------------------------------------------------------------------------- /test/data/gesa3_o.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gesa3_o.mps.gz -------------------------------------------------------------------------------- /test/data/gt2.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/gt2.mps.gz -------------------------------------------------------------------------------- /test/data/harp2.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/harp2.mps.gz -------------------------------------------------------------------------------- /test/data/khb05250.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/khb05250.mps.gz -------------------------------------------------------------------------------- /test/data/l152lav.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/l152lav.mps.gz -------------------------------------------------------------------------------- /test/data/lseu.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/lseu.mps.gz -------------------------------------------------------------------------------- /test/data/markshare1.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/markshare1.mps.gz -------------------------------------------------------------------------------- /test/data/mas74.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/mas74.mps.gz -------------------------------------------------------------------------------- /test/data/mas76.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/mas76.mps.gz -------------------------------------------------------------------------------- /test/data/misc03.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/misc03.mps.gz -------------------------------------------------------------------------------- /test/data/misc06.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/misc06.mps.gz -------------------------------------------------------------------------------- /test/data/misc07.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/misc07.mps.gz -------------------------------------------------------------------------------- /test/data/mkc.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/mkc.mps.gz -------------------------------------------------------------------------------- /test/data/mod008.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/mod008.mps.gz -------------------------------------------------------------------------------- /test/data/mod010.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/mod010.mps.gz -------------------------------------------------------------------------------- /test/data/modglob.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/modglob.mps.gz -------------------------------------------------------------------------------- /test/data/p0033.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/p0033.mps.gz -------------------------------------------------------------------------------- /test/data/p0201.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/p0201.mps.gz -------------------------------------------------------------------------------- /test/data/p0282.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/p0282.mps.gz -------------------------------------------------------------------------------- /test/data/p0548.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/p0548.mps.gz -------------------------------------------------------------------------------- /test/data/p2756.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/p2756.mps.gz -------------------------------------------------------------------------------- /test/data/pk1.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/pk1.mps.gz -------------------------------------------------------------------------------- /test/data/pmp-iss-157.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/pmp-iss-157.mps.gz -------------------------------------------------------------------------------- /test/data/pp08a.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/pp08a.mps.gz -------------------------------------------------------------------------------- /test/data/pp08aCUTS.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/pp08aCUTS.mps.gz -------------------------------------------------------------------------------- /test/data/qiu.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/qiu.mps.gz -------------------------------------------------------------------------------- /test/data/qnet1.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/qnet1.mps.gz -------------------------------------------------------------------------------- /test/data/qnet1_o.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/qnet1_o.mps.gz -------------------------------------------------------------------------------- /test/data/rcpsp-5-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 9, 14 | 9, 15 | 9, 16 | 7, 17 | 2, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 3, 63 | 4 64 | ], 65 | [ 66 | 4, 67 | 5 68 | ], 69 | [ 70 | 2, 71 | 5 72 | ], 73 | [ 74 | 3, 75 | 5 76 | ] 77 | ], 78 | "c": [ 79 | 19, 80 | 18, 81 | 20 82 | ], 83 | "r": [ 84 | [ 85 | 0, 86 | 5, 87 | 10, 88 | 8, 89 | 14, 90 | 2, 91 | 0 92 | ], 93 | [ 94 | 0, 95 | 12, 96 | 3, 97 | 12, 98 | 9, 99 | 6, 100 | 0 101 | ], 102 | [ 103 | 0, 104 | 7, 105 | 15, 106 | 6, 107 | 11, 108 | 1, 109 | 0 110 | ] 111 | ], 112 | "EST": [ 113 | 0, 114 | 0, 115 | 0, 116 | 0, 117 | 9, 118 | 16, 119 | 18 120 | ], 121 | "z_relax": 18.0, 122 | "rc_limits": [ 123 | 0.0, 124 | 18.0 125 | ], 126 | "pi_limits": [ 127 | 0.0, 128 | 18.0 129 | ], 130 | "z_relax_max": 36.0, 131 | "z_lb": 34.0, 132 | "z_ub": 34.0, 133 | "mipstart": [ 134 | [ 135 | "x(0,0)", 136 | 1.0 137 | ], 138 | [ 139 | "x(1,25)", 140 | 1.0 141 | ], 142 | [ 143 | "x(2,16)", 144 | 1.0 145 | ], 146 | [ 147 | "x(3,0)", 148 | 1.0 149 | ], 150 | [ 151 | "x(4,9)", 152 | 1.0 153 | ], 154 | [ 155 | "x(5,25)", 156 | 1.0 157 | ], 158 | [ 159 | "x(6,34)", 160 | 1.0 161 | ] 162 | ] 163 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 8, 14 | 9, 15 | 10, 16 | 9, 17 | 4, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 4, 63 | 5 64 | ], 65 | [ 66 | 3, 67 | 5 68 | ] 69 | ], 70 | "c": [ 71 | 20, 72 | 21, 73 | 19 74 | ], 75 | "r": [ 76 | [ 77 | 0, 78 | 10, 79 | 2, 80 | 5, 81 | 15, 82 | 8, 83 | 0 84 | ], 85 | [ 86 | 0, 87 | 2, 88 | 13, 89 | 12, 90 | 11, 91 | 13, 92 | 0 93 | ], 94 | [ 95 | 0, 96 | 14, 97 | 13, 98 | 9, 99 | 2, 100 | 1, 101 | 0 102 | ] 103 | ], 104 | "EST": [ 105 | 0, 106 | 0, 107 | 0, 108 | 0, 109 | 0, 110 | 10, 111 | 14 112 | ], 113 | "z_relax": 16.181237969810557, 114 | "rc_limits": [ 115 | -3.552713678800501e-15, 116 | 7.215479687974879 117 | ], 118 | "pi_limits": [ 119 | -0.18522270624387938, 120 | 4.598926147300173 121 | ], 122 | "z_relax_max": 40.0, 123 | "z_lb": 36.0, 124 | "z_ub": 36.0, 125 | "mipstart": [ 126 | [ 127 | "x(0,0)", 128 | 1.0 129 | ], 130 | [ 131 | "x(1,19)", 132 | 1.0 133 | ], 134 | [ 135 | "x(2,27)", 136 | 1.0 137 | ], 138 | [ 139 | "x(3,9)", 140 | 1.0 141 | ], 142 | [ 143 | "x(4,0)", 144 | 1.0 145 | ], 146 | [ 147 | "x(5,23)", 148 | 1.0 149 | ], 150 | [ 151 | "x(6,36)", 152 | 1.0 153 | ] 154 | ] 155 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 10, 14 | 6, 15 | 9, 16 | 1, 17 | 11, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 4, 63 | 5 64 | ] 65 | ], 66 | "c": [ 67 | 12, 68 | 16, 69 | 25 70 | ], 71 | "r": [ 72 | [ 73 | 0, 74 | 6, 75 | 9, 76 | 4, 77 | 3, 78 | 1, 79 | 0 80 | ], 81 | [ 82 | 0, 83 | 8, 84 | 4, 85 | 10, 86 | 9, 87 | 6, 88 | 0 89 | ], 90 | [ 91 | 0, 92 | 14, 93 | 9, 94 | 15, 95 | 12, 96 | 14, 97 | 0 98 | ] 99 | ], 100 | "EST": [ 101 | 0, 102 | 0, 103 | 0, 104 | 0, 105 | 0, 106 | 1, 107 | 12 108 | ], 109 | "z_relax": 14.884353516525898, 110 | "rc_limits": [ 111 | -3.552713678800501e-15, 112 | 7.57743106856533 113 | ], 114 | "pi_limits": [ 115 | -0.04889618410780861, 116 | 4.425462849967114 117 | ], 118 | "z_relax_max": 37.0, 119 | "z_lb": 31.0, 120 | "z_ub": 31.0, 121 | "mipstart": [ 122 | [ 123 | "x(0,0)", 124 | 1.0 125 | ], 126 | [ 127 | "x(1,10)", 128 | 1.0 129 | ], 130 | [ 131 | "x(2,20)", 132 | 1.0 133 | ], 134 | [ 135 | "x(3,1)", 136 | 1.0 137 | ], 138 | [ 139 | "x(4,0)", 140 | 1.0 141 | ], 142 | [ 143 | "x(5,20)", 144 | 1.0 145 | ], 146 | [ 147 | "x(6,31)", 148 | 1.0 149 | ] 150 | ] 151 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 8, 14 | 11, 15 | 7, 16 | 10, 17 | 1, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 4, 63 | 5 64 | ], 65 | [ 66 | 2, 67 | 5 68 | ], 69 | [ 70 | 3, 71 | 5 72 | ] 73 | ], 74 | "c": [ 75 | 19, 76 | 17, 77 | 20 78 | ], 79 | "r": [ 80 | [ 81 | 0, 82 | 11, 83 | 8, 84 | 12, 85 | 12, 86 | 3, 87 | 0 88 | ], 89 | [ 90 | 0, 91 | 7, 92 | 11, 93 | 10, 94 | 6, 95 | 7, 96 | 0 97 | ], 98 | [ 99 | 0, 100 | 4, 101 | 10, 102 | 13, 103 | 6, 104 | 13, 105 | 0 106 | ] 107 | ], 108 | "EST": [ 109 | 0, 110 | 0, 111 | 0, 112 | 0, 113 | 0, 114 | 11, 115 | 12 116 | ], 117 | "z_relax": 15.394996871190695, 118 | "rc_limits": [ 119 | -3.552713678800501e-15, 120 | 7.121710622124107 121 | ], 122 | "pi_limits": [ 123 | -0.25584844664376294, 124 | 4.592850135486627 125 | ], 126 | "z_relax_max": 37.0, 127 | "z_lb": 36.0, 128 | "z_ub": 36.0, 129 | "mipstart": [ 130 | [ 131 | "x(0,0)", 132 | 1.0 133 | ], 134 | [ 135 | "x(1,28)", 136 | 1.0 137 | ], 138 | [ 139 | "x(2,17)", 140 | 1.0 141 | ], 142 | [ 143 | "x(3,0)", 144 | 1.0 145 | ], 146 | [ 147 | "x(4,7)", 148 | 1.0 149 | ], 150 | [ 151 | "x(5,35)", 152 | 1.0 153 | ], 154 | [ 155 | "x(6,36)", 156 | 1.0 157 | ] 158 | ] 159 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 10, 14 | 10, 15 | 8, 16 | 9, 17 | 3, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 2, 63 | 4 64 | ], 65 | [ 66 | 2, 67 | 3 68 | ] 69 | ], 70 | "c": [ 71 | 23, 72 | 24, 73 | 19 74 | ], 75 | "r": [ 76 | [ 77 | 0, 78 | 11, 79 | 2, 80 | 12, 81 | 11, 82 | 15, 83 | 0 84 | ], 85 | [ 86 | 0, 87 | 14, 88 | 13, 89 | 8, 90 | 15, 91 | 10, 92 | 0 93 | ], 94 | [ 95 | 0, 96 | 8, 97 | 3, 98 | 14, 99 | 11, 100 | 3, 101 | 0 102 | ] 103 | ], 104 | "EST": [ 105 | 0, 106 | 0, 107 | 0, 108 | 10, 109 | 10, 110 | 0, 111 | 19 112 | ], 113 | "z_relax": 20.36, 114 | "rc_limits": [ 115 | -1.7763568394002505e-15, 116 | 12.32 117 | ], 118 | "pi_limits": [ 119 | -0.08000000000000006, 120 | 10.079999999999998 121 | ], 122 | "z_relax_max": 40.0, 123 | "z_lb": 37.0, 124 | "z_ub": 37.0, 125 | "mipstart": [ 126 | [ 127 | "x(0,0)", 128 | 1.0 129 | ], 130 | [ 131 | "x(1,27)", 132 | 1.0 133 | ], 134 | [ 135 | "x(2,0)", 136 | 1.0 137 | ], 138 | [ 139 | "x(3,10)", 140 | 1.0 141 | ], 142 | [ 143 | "x(4,18)", 144 | 1.0 145 | ], 146 | [ 147 | "x(5,0)", 148 | 1.0 149 | ], 150 | [ 151 | "x(6,37)", 152 | 1.0 153 | ] 154 | ] 155 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 10, 14 | 10, 15 | 11, 16 | 2, 17 | 10, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 4, 63 | 5 64 | ], 65 | [ 66 | 3, 67 | 4 68 | ], 69 | [ 70 | 3, 71 | 5 72 | ] 73 | ], 74 | "c": [ 75 | 21, 76 | 20, 77 | 23 78 | ], 79 | "r": [ 80 | [ 81 | 0, 82 | 13, 83 | 15, 84 | 2, 85 | 13, 86 | 1, 87 | 0 88 | ], 89 | [ 90 | 0, 91 | 13, 92 | 13, 93 | 4, 94 | 4, 95 | 11, 96 | 0 97 | ], 98 | [ 99 | 0, 100 | 12, 101 | 11, 102 | 13, 103 | 7, 104 | 14, 105 | 0 106 | ] 107 | ], 108 | "EST": [ 109 | 0, 110 | 0, 111 | 0, 112 | 0, 113 | 11, 114 | 13, 115 | 23 116 | ], 117 | "z_relax": 23.0, 118 | "rc_limits": [ 119 | 0.0, 120 | 20.0 121 | ], 122 | "pi_limits": [ 123 | 0.0, 124 | 23.0 125 | ], 126 | "z_relax_max": 43.0, 127 | "z_lb": 43.0, 128 | "z_ub": 43.0, 129 | "mipstart": [ 130 | [ 131 | "x(0,0)", 132 | 1.0 133 | ], 134 | [ 135 | "x(1,33)", 136 | 1.0 137 | ], 138 | [ 139 | "x(2,23)", 140 | 1.0 141 | ], 142 | [ 143 | "x(3,0)", 144 | 1.0 145 | ], 146 | [ 147 | "x(4,11)", 148 | 1.0 149 | ], 150 | [ 151 | "x(5,13)", 152 | 1.0 153 | ], 154 | [ 155 | "x(6,43)", 156 | 1.0 157 | ] 158 | ] 159 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-6.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 11, 14 | 8, 15 | 11, 16 | 5, 17 | 10, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 3, 63 | 5 64 | ], 65 | [ 66 | 3, 67 | 4 68 | ] 69 | ], 70 | "c": [ 71 | 19, 72 | 8, 73 | 25 74 | ], 75 | "r": [ 76 | [ 77 | 0, 78 | 4, 79 | 9, 80 | 4, 81 | 13, 82 | 10, 83 | 0 84 | ], 85 | [ 86 | 0, 87 | 5, 88 | 2, 89 | 5, 90 | 4, 91 | 4, 92 | 0 93 | ], 94 | [ 95 | 0, 96 | 13, 97 | 13, 98 | 14, 99 | 8, 100 | 15, 101 | 0 102 | ] 103 | ], 104 | "EST": [ 105 | 0, 106 | 0, 107 | 0, 108 | 0, 109 | 11, 110 | 11, 111 | 21 112 | ], 113 | "z_relax": 21.0, 114 | "rc_limits": [ 115 | 0.0, 116 | 24.0 117 | ], 118 | "pi_limits": [ 119 | 0.0, 120 | 21.0 121 | ], 122 | "z_relax_max": 45.0, 123 | "z_lb": 45.0, 124 | "z_ub": 45.0, 125 | "mipstart": [ 126 | [ 127 | "x(0,0)", 128 | 1.0 129 | ], 130 | [ 131 | "x(1,34)", 132 | 1.0 133 | ], 134 | [ 135 | "x(2,26)", 136 | 1.0 137 | ], 138 | [ 139 | "x(3,0)", 140 | 1.0 141 | ], 142 | [ 143 | "x(4,21)", 144 | 1.0 145 | ], 146 | [ 147 | "x(5,11)", 148 | 1.0 149 | ], 150 | [ 151 | "x(6,45)", 152 | 1.0 153 | ] 154 | ] 155 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-7.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 11, 14 | 7, 15 | 8, 16 | 7, 17 | 10, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 2, 63 | 4 64 | ], 65 | [ 66 | 3, 67 | 4 68 | ] 69 | ], 70 | "c": [ 71 | 11, 72 | 23, 73 | 24 74 | ], 75 | "r": [ 76 | [ 77 | 0, 78 | 1, 79 | 6, 80 | 8, 81 | 4, 82 | 3, 83 | 0 84 | ], 85 | [ 86 | 0, 87 | 12, 88 | 15, 89 | 3, 90 | 9, 91 | 14, 92 | 0 93 | ], 94 | [ 95 | 0, 96 | 13, 97 | 4, 98 | 12, 99 | 15, 100 | 14, 101 | 0 102 | ] 103 | ], 104 | "EST": [ 105 | 0, 106 | 0, 107 | 0, 108 | 0, 109 | 8, 110 | 0, 111 | 15 112 | ], 113 | "z_relax": 17.176760035046144, 114 | "rc_limits": [ 115 | -3.552713678800501e-15, 116 | 6.786547121995761 117 | ], 118 | "pi_limits": [ 119 | -0.08260256217055384, 120 | 3.5548989255033834 121 | ], 122 | "z_relax_max": 43.0, 123 | "z_lb": 43.0, 124 | "z_ub": 43.0, 125 | "mipstart": [ 126 | [ 127 | "x(0,0)", 128 | 1.0 129 | ], 130 | [ 131 | "x(1,18)", 132 | 1.0 133 | ], 134 | [ 135 | "x(2,29)", 136 | 1.0 137 | ], 138 | [ 139 | "x(3,0)", 140 | 1.0 141 | ], 142 | [ 143 | "x(4,36)", 144 | 1.0 145 | ], 146 | [ 147 | "x(5,8)", 148 | 1.0 149 | ], 150 | [ 151 | "x(6,43)", 152 | 1.0 153 | ] 154 | ] 155 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-8.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 11, 14 | 11, 15 | 9, 16 | 10, 17 | 10, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 2, 63 | 5 64 | ], 65 | [ 66 | 3, 67 | 5 68 | ] 69 | ], 70 | "c": [ 71 | 16, 72 | 20, 73 | 17 74 | ], 75 | "r": [ 76 | [ 77 | 0, 78 | 8, 79 | 2, 80 | 10, 81 | 9, 82 | 10, 83 | 0 84 | ], 85 | [ 86 | 0, 87 | 12, 88 | 12, 89 | 6, 90 | 9, 91 | 11, 92 | 0 93 | ], 94 | [ 95 | 0, 96 | 4, 97 | 7, 98 | 10, 99 | 12, 100 | 2, 101 | 0 102 | ] 103 | ], 104 | "EST": [ 105 | 0, 106 | 0, 107 | 0, 108 | 0, 109 | 0, 110 | 11, 111 | 21 112 | ], 113 | "z_relax": 22.234082726066802, 114 | "rc_limits": [ 115 | -7.105427357601002e-15, 116 | 12.198211793891167 117 | ], 118 | "pi_limits": [ 119 | -0.15186116161877206, 120 | 4.518113482752482 121 | ], 122 | "z_relax_max": 51.0, 123 | "z_lb": 42.0, 124 | "z_ub": 42.0, 125 | "mipstart": [ 126 | [ 127 | "x(0,0)", 128 | 1.0 129 | ], 130 | [ 131 | "x(1,0)", 132 | 1.0 133 | ], 134 | [ 135 | "x(2,21)", 136 | 1.0 137 | ], 138 | [ 139 | "x(3,22)", 140 | 1.0 141 | ], 142 | [ 143 | "x(4,11)", 144 | 1.0 145 | ], 146 | [ 147 | "x(5,32)", 148 | 1.0 149 | ], 150 | [ 151 | "x(6,42)", 152 | 1.0 153 | ] 154 | ] 155 | } -------------------------------------------------------------------------------- /test/data/rcpsp-5-9.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6 10 | ], 11 | "d": [ 12 | 0, 13 | 10, 14 | 11, 15 | 11, 16 | 11, 17 | 9, 18 | 0 19 | ], 20 | "S": [ 21 | [ 22 | 0, 23 | 1 24 | ], 25 | [ 26 | 0, 27 | 2 28 | ], 29 | [ 30 | 0, 31 | 3 32 | ], 33 | [ 34 | 0, 35 | 4 36 | ], 37 | [ 38 | 0, 39 | 5 40 | ], 41 | [ 42 | 1, 43 | 6 44 | ], 45 | [ 46 | 2, 47 | 6 48 | ], 49 | [ 50 | 3, 51 | 6 52 | ], 53 | [ 54 | 4, 55 | 6 56 | ], 57 | [ 58 | 5, 59 | 6 60 | ], 61 | [ 62 | 2, 63 | 5 64 | ] 65 | ], 66 | "c": [ 67 | 18, 68 | 22, 69 | 22 70 | ], 71 | "r": [ 72 | [ 73 | 0, 74 | 1, 75 | 2, 76 | 2, 77 | 12, 78 | 14, 79 | 0 80 | ], 81 | [ 82 | 0, 83 | 12, 84 | 3, 85 | 15, 86 | 6, 87 | 11, 88 | 0 89 | ], 90 | [ 91 | 0, 92 | 11, 93 | 14, 94 | 10, 95 | 14, 96 | 1, 97 | 0 98 | ] 99 | ], 100 | "EST": [ 101 | 0, 102 | 0, 103 | 0, 104 | 0, 105 | 0, 106 | 11, 107 | 20 108 | ], 109 | "z_relax": 21.38386292436545, 110 | "rc_limits": [ 111 | -1.0658141036401503e-14, 112 | 11.458730260213542 113 | ], 114 | "pi_limits": [ 115 | -0.2526576422107398, 116 | 5.1100952624512495 117 | ], 118 | "z_relax_max": 52.0, 119 | "z_lb": 52.0, 120 | "z_ub": 52.0, 121 | "mipstart": [ 122 | [ 123 | "x(0,0)", 124 | 1.0 125 | ], 126 | [ 127 | "x(1,42)", 128 | 1.0 129 | ], 130 | [ 131 | "x(2,0)", 132 | 1.0 133 | ], 134 | [ 135 | "x(3,31)", 136 | 1.0 137 | ], 138 | [ 139 | "x(4,20)", 140 | 1.0 141 | ], 142 | [ 143 | "x(5,11)", 144 | 1.0 145 | ], 146 | [ 147 | "x(6,52)", 148 | 1.0 149 | ] 150 | ] 151 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 10, 15 | 4, 16 | 7, 17 | 8, 18 | 7, 19 | 10, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 4, 73 | 6 74 | ], 75 | [ 76 | 3, 77 | 5 78 | ], 79 | [ 80 | 3, 81 | 6 82 | ], 83 | [ 84 | 2, 85 | 3 86 | ] 87 | ], 88 | "c": [ 89 | 25, 90 | 12, 91 | 24 92 | ], 93 | "r": [ 94 | [ 95 | 0, 96 | 12, 97 | 14, 98 | 11, 99 | 14, 100 | 13, 101 | 1, 102 | 0 103 | ], 104 | [ 105 | 0, 106 | 8, 107 | 7, 108 | 6, 109 | 1, 110 | 1, 111 | 5, 112 | 0 113 | ], 114 | [ 115 | 0, 116 | 2, 117 | 10, 118 | 14, 119 | 15, 120 | 14, 121 | 1, 122 | 0 123 | ] 124 | ], 125 | "EST": [ 126 | 0, 127 | 0, 128 | 0, 129 | 4, 130 | 0, 131 | 11, 132 | 11, 133 | 21 134 | ], 135 | "z_relax": 21.0, 136 | "rc_limits": [ 137 | 0.0, 138 | 25.0 139 | ], 140 | "pi_limits": [ 141 | 0.0, 142 | 21.0 143 | ], 144 | "z_relax_max": 46.0, 145 | "z_lb": 39.0, 146 | "z_ub": 39.0, 147 | "mipstart": [ 148 | [ 149 | "x(0,0)", 150 | 1.0 151 | ], 152 | [ 153 | "x(1,29)", 154 | 1.0 155 | ], 156 | [ 157 | "x(2,0)", 158 | 1.0 159 | ], 160 | [ 161 | "x(3,4)", 162 | 1.0 163 | ], 164 | [ 165 | "x(4,11)", 166 | 1.0 167 | ], 168 | [ 169 | "x(5,20)", 170 | 1.0 171 | ], 172 | [ 173 | "x(6,19)", 174 | 1.0 175 | ], 176 | [ 177 | "x(7,39)", 178 | 1.0 179 | ] 180 | ] 181 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 5, 15 | 8, 16 | 11, 17 | 10, 18 | 9, 19 | 5, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 2, 73 | 3 74 | ], 75 | [ 76 | 2, 77 | 5 78 | ], 79 | [ 80 | 5, 81 | 6 82 | ] 83 | ], 84 | "c": [ 85 | 21, 86 | 24, 87 | 26 88 | ], 89 | "r": [ 90 | [ 91 | 0, 92 | 6, 93 | 1, 94 | 14, 95 | 9, 96 | 13, 97 | 4, 98 | 0 99 | ], 100 | [ 101 | 0, 102 | 10, 103 | 5, 104 | 15, 105 | 4, 106 | 15, 107 | 7, 108 | 0 109 | ], 110 | [ 111 | 0, 112 | 13, 113 | 14, 114 | 7, 115 | 15, 116 | 5, 117 | 13, 118 | 0 119 | ] 120 | ], 121 | "EST": [ 122 | 0, 123 | 0, 124 | 0, 125 | 8, 126 | 0, 127 | 8, 128 | 17, 129 | 22 130 | ], 131 | "z_relax": 22.64577521074935, 132 | "rc_limits": [ 133 | 0.0, 134 | 15.370210070727332 135 | ], 136 | "pi_limits": [ 137 | -0.07139087029301323, 138 | 8.617122347725115 139 | ], 140 | "z_relax_max": 48.0, 141 | "z_lb": 43.0, 142 | "z_ub": 43.0, 143 | "mipstart": [ 144 | [ 145 | "x(0,0)", 146 | 1.0 147 | ], 148 | [ 149 | "x(1,17)", 150 | 1.0 151 | ], 152 | [ 153 | "x(2,0)", 154 | 1.0 155 | ], 156 | [ 157 | "x(3,32)", 158 | 1.0 159 | ], 160 | [ 161 | "x(4,22)", 162 | 1.0 163 | ], 164 | [ 165 | "x(5,8)", 166 | 1.0 167 | ], 168 | [ 169 | "x(6,17)", 170 | 1.0 171 | ], 172 | [ 173 | "x(7,43)", 174 | 1.0 175 | ] 176 | ] 177 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 5, 15 | 8, 16 | 11, 17 | 10, 18 | 10, 19 | 2, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 3, 73 | 5 74 | ], 75 | [ 76 | 4, 77 | 5 78 | ], 79 | [ 80 | 4, 81 | 6 82 | ] 83 | ], 84 | "c": [ 85 | 24, 86 | 21, 87 | 24 88 | ], 89 | "r": [ 90 | [ 91 | 0, 92 | 14, 93 | 12, 94 | 11, 95 | 9, 96 | 14, 97 | 3, 98 | 0 99 | ], 100 | [ 101 | 0, 102 | 10, 103 | 8, 104 | 14, 105 | 8, 106 | 4, 107 | 4, 108 | 0 109 | ], 110 | [ 111 | 0, 112 | 11, 113 | 15, 114 | 15, 115 | 13, 116 | 3, 117 | 2, 118 | 0 119 | ] 120 | ], 121 | "EST": [ 122 | 0, 123 | 0, 124 | 0, 125 | 0, 126 | 0, 127 | 11, 128 | 10, 129 | 21 130 | ], 131 | "z_relax": 22.016281044253986, 132 | "rc_limits": [ 133 | -6.772360450213455e-15, 134 | 10.59840802693345 135 | ], 136 | "pi_limits": [ 137 | -0.10430334488267018, 138 | 4.7034544695818425 139 | ], 140 | "z_relax_max": 46.0, 141 | "z_lb": 39.0, 142 | "z_ub": 39.0, 143 | "mipstart": [ 144 | [ 145 | "x(0,0)", 146 | 1.0 147 | ], 148 | [ 149 | "x(1,13)", 150 | 1.0 151 | ], 152 | [ 153 | "x(2,21)", 154 | 1.0 155 | ], 156 | [ 157 | "x(3,0)", 158 | 1.0 159 | ], 160 | [ 161 | "x(4,11)", 162 | 1.0 163 | ], 164 | [ 165 | "x(5,29)", 166 | 1.0 167 | ], 168 | [ 169 | "x(6,36)", 170 | 1.0 171 | ], 172 | [ 173 | "x(7,39)", 174 | 1.0 175 | ] 176 | ] 177 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 8, 15 | 11, 16 | 10, 17 | 9, 18 | 8, 19 | 3, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 3, 73 | 6 74 | ], 75 | [ 76 | 3, 77 | 5 78 | ] 79 | ], 80 | "c": [ 81 | 21, 82 | 23, 83 | 22 84 | ], 85 | "r": [ 86 | [ 87 | 0, 88 | 15, 89 | 1, 90 | 3, 91 | 3, 92 | 9, 93 | 10, 94 | 0 95 | ], 96 | [ 97 | 0, 98 | 13, 99 | 3, 100 | 12, 101 | 12, 102 | 14, 103 | 3, 104 | 0 105 | ], 106 | [ 107 | 0, 108 | 12, 109 | 8, 110 | 12, 111 | 14, 112 | 1, 113 | 7, 114 | 0 115 | ] 116 | ], 117 | "EST": [ 118 | 0, 119 | 0, 120 | 0, 121 | 0, 122 | 0, 123 | 10, 124 | 10, 125 | 18 126 | ], 127 | "z_relax": 18.0828753498095, 128 | "rc_limits": [ 129 | -2.7755575615628914e-15, 130 | 7.363194982973118 131 | ], 132 | "pi_limits": [ 133 | -0.1967362352068513, 134 | 4.279240702653491 135 | ], 136 | "z_relax_max": 49.0, 137 | "z_lb": 35.0, 138 | "z_ub": 35.0, 139 | "mipstart": [ 140 | [ 141 | "x(0,0)", 142 | 1.0 143 | ], 144 | [ 145 | "x(1,19)", 146 | 1.0 147 | ], 148 | [ 149 | "x(2,14)", 150 | 1.0 151 | ], 152 | [ 153 | "x(3,0)", 154 | 1.0 155 | ], 156 | [ 157 | "x(4,10)", 158 | 1.0 159 | ], 160 | [ 161 | "x(5,27)", 162 | 1.0 163 | ], 164 | [ 165 | "x(6,10)", 166 | 1.0 167 | ], 168 | [ 169 | "x(7,35)", 170 | 1.0 171 | ] 172 | ] 173 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-6.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 8, 15 | 11, 16 | 6, 17 | 2, 18 | 11, 19 | 3, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 4, 73 | 6 74 | ], 75 | [ 76 | 3, 77 | 5 78 | ], 79 | [ 80 | 3, 81 | 4 82 | ] 83 | ], 84 | "c": [ 85 | 25, 86 | 20, 87 | 21 88 | ], 89 | "r": [ 90 | [ 91 | 0, 92 | 14, 93 | 14, 94 | 13, 95 | 4, 96 | 15, 97 | 4, 98 | 0 99 | ], 100 | [ 101 | 0, 102 | 5, 103 | 6, 104 | 4, 105 | 8, 106 | 5, 107 | 14, 108 | 0 109 | ], 110 | [ 111 | 0, 112 | 11, 113 | 2, 114 | 7, 115 | 6, 116 | 10, 117 | 13, 118 | 0 119 | ] 120 | ], 121 | "EST": [ 122 | 0, 123 | 0, 124 | 0, 125 | 0, 126 | 6, 127 | 6, 128 | 8, 129 | 17 130 | ], 131 | "z_relax": 17.19956241675549, 132 | "rc_limits": [ 133 | -4.3298697960381105e-15, 134 | 24.838690030073607 135 | ], 136 | "pi_limits": [ 137 | -0.052288739385832894, 138 | 7.184560440634099 139 | ], 140 | "z_relax_max": 41.0, 141 | "z_lb": 36.0, 142 | "z_ub": 36.0, 143 | "mipstart": [ 144 | [ 145 | "x(0,0)", 146 | 1.0 147 | ], 148 | [ 149 | "x(1,6)", 150 | 1.0 151 | ], 152 | [ 153 | "x(2,14)", 154 | 1.0 155 | ], 156 | [ 157 | "x(3,0)", 158 | 1.0 159 | ], 160 | [ 161 | "x(4,6)", 162 | 1.0 163 | ], 164 | [ 165 | "x(5,25)", 166 | 1.0 167 | ], 168 | [ 169 | "x(6,19)", 170 | 1.0 171 | ], 172 | [ 173 | "x(7,36)", 174 | 1.0 175 | ] 176 | ] 177 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-7.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 8, 15 | 8, 16 | 11, 17 | 3, 18 | 3, 19 | 8, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 5, 73 | 6 74 | ], 75 | [ 76 | 2, 77 | 4 78 | ], 79 | [ 80 | 2, 81 | 5 82 | ], 83 | [ 84 | 3, 85 | 5 86 | ] 87 | ], 88 | "c": [ 89 | 20, 90 | 20, 91 | 23 92 | ], 93 | "r": [ 94 | [ 95 | 0, 96 | 10, 97 | 8, 98 | 6, 99 | 7, 100 | 3, 101 | 13, 102 | 0 103 | ], 104 | [ 105 | 0, 106 | 12, 107 | 15, 108 | 3, 109 | 2, 110 | 1, 111 | 7, 112 | 0 113 | ], 114 | [ 115 | 0, 116 | 15, 117 | 15, 118 | 9, 119 | 1, 120 | 10, 121 | 2, 122 | 0 123 | ] 124 | ], 125 | "EST": [ 126 | 0, 127 | 0, 128 | 0, 129 | 0, 130 | 8, 131 | 11, 132 | 14, 133 | 22 134 | ], 135 | "z_relax": 22.0, 136 | "rc_limits": [ 137 | 0.0, 138 | 19.0 139 | ], 140 | "pi_limits": [ 141 | 0.0, 142 | 22.0 143 | ], 144 | "z_relax_max": 41.0, 145 | "z_lb": 38.0, 146 | "z_ub": 38.0, 147 | "mipstart": [ 148 | [ 149 | "x(0,0)", 150 | 1.0 151 | ], 152 | [ 153 | "x(1,30)", 154 | 1.0 155 | ], 156 | [ 157 | "x(2,0)", 158 | 1.0 159 | ], 160 | [ 161 | "x(3,8)", 162 | 1.0 163 | ], 164 | [ 165 | "x(4,10)", 166 | 1.0 167 | ], 168 | [ 169 | "x(5,19)", 170 | 1.0 171 | ], 172 | [ 173 | "x(6,22)", 174 | 1.0 175 | ], 176 | [ 177 | "x(7,38)", 178 | 1.0 179 | ] 180 | ] 181 | } -------------------------------------------------------------------------------- /test/data/rcpsp-6-9.json: -------------------------------------------------------------------------------- 1 | { 2 | "J": [ 3 | 0, 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 6, 10 | 7 11 | ], 12 | "d": [ 13 | 0, 14 | 8, 15 | 10, 16 | 2, 17 | 9, 18 | 1, 19 | 2, 20 | 0 21 | ], 22 | "S": [ 23 | [ 24 | 0, 25 | 1 26 | ], 27 | [ 28 | 0, 29 | 2 30 | ], 31 | [ 32 | 0, 33 | 3 34 | ], 35 | [ 36 | 0, 37 | 4 38 | ], 39 | [ 40 | 0, 41 | 5 42 | ], 43 | [ 44 | 0, 45 | 6 46 | ], 47 | [ 48 | 1, 49 | 7 50 | ], 51 | [ 52 | 2, 53 | 7 54 | ], 55 | [ 56 | 3, 57 | 7 58 | ], 59 | [ 60 | 4, 61 | 7 62 | ], 63 | [ 64 | 5, 65 | 7 66 | ], 67 | [ 68 | 6, 69 | 7 70 | ], 71 | [ 72 | 3, 73 | 5 74 | ], 75 | [ 76 | 4, 77 | 5 78 | ], 79 | [ 80 | 3, 81 | 6 82 | ] 83 | ], 84 | "c": [ 85 | 17, 86 | 18, 87 | 20 88 | ], 89 | "r": [ 90 | [ 91 | 0, 92 | 10, 93 | 1, 94 | 3, 95 | 11, 96 | 7, 97 | 8, 98 | 0 99 | ], 100 | [ 101 | 0, 102 | 8, 103 | 13, 104 | 1, 105 | 2, 106 | 1, 107 | 13, 108 | 0 109 | ], 110 | [ 111 | 0, 112 | 4, 113 | 11, 114 | 10, 115 | 12, 116 | 6, 117 | 9, 118 | 0 119 | ] 120 | ], 121 | "EST": [ 122 | 0, 123 | 0, 124 | 0, 125 | 0, 126 | 0, 127 | 9, 128 | 2, 129 | 10 130 | ], 131 | "z_relax": 12.134045988310753, 132 | "rc_limits": [ 133 | -1.7763568394002505e-15, 134 | 8.563144813009043 135 | ], 136 | "pi_limits": [ 137 | -0.07826011267098525, 138 | 3.6937104197939155 139 | ], 140 | "z_relax_max": 32.0, 141 | "z_lb": 29.0, 142 | "z_ub": 29.0, 143 | "mipstart": [ 144 | [ 145 | "x(0,0)", 146 | 1.0 147 | ], 148 | [ 149 | "x(1,0)", 150 | 1.0 151 | ], 152 | [ 153 | "x(2,19)", 154 | 1.0 155 | ], 156 | [ 157 | "x(3,0)", 158 | 1.0 159 | ], 160 | [ 161 | "x(4,10)", 162 | 1.0 163 | ], 164 | [ 165 | "x(5,28)", 166 | 1.0 167 | ], 168 | [ 169 | "x(6,8)", 170 | 1.0 171 | ], 172 | [ 173 | "x(7,29)", 174 | 1.0 175 | ] 176 | ] 177 | } -------------------------------------------------------------------------------- /test/data/rgn.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/rgn.mps.gz -------------------------------------------------------------------------------- /test/data/rout.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/rout.mps.gz -------------------------------------------------------------------------------- /test/data/set1ch.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/set1ch.mps.gz -------------------------------------------------------------------------------- /test/data/seymour.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/seymour.mps.gz -------------------------------------------------------------------------------- /test/data/stein27.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/stein27.mps.gz -------------------------------------------------------------------------------- /test/data/stein45.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/stein45.mps.gz -------------------------------------------------------------------------------- /test/data/swath.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/swath.mps.gz -------------------------------------------------------------------------------- /test/data/vpm1.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/vpm1.mps.gz -------------------------------------------------------------------------------- /test/data/vpm2.mps.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coin-or/python-mip/0ccb81115543e737ab74a4f1309891ce5650c8d5/test/data/vpm2.mps.gz -------------------------------------------------------------------------------- /test/examples_test.py: -------------------------------------------------------------------------------- 1 | """Tests all examples in the ../examples folder 2 | with all the solvers available""" 3 | from glob import glob 4 | from os.path import join 5 | from os import environ 6 | from itertools import product 7 | import types 8 | import importlib.machinery 9 | import pytest 10 | 11 | import mip.gurobi 12 | import mip.highs 13 | from mip import CBC, GUROBI, HIGHS 14 | from util import skip_on 15 | 16 | EXAMPLES = glob(join("..", "examples", "*.py")) + glob(join(".", "examples", "*.py")) 17 | 18 | SOLVERS = [CBC] 19 | if mip.gurobi.has_gurobi and "GUROBI_HOME" in environ: 20 | SOLVERS += [GUROBI] 21 | if mip.highs.has_highs: 22 | SOLVERS += [HIGHS] 23 | 24 | 25 | @skip_on(NotImplementedError) 26 | @pytest.mark.parametrize("solver, example", product(SOLVERS, EXAMPLES)) 27 | def test_examples(solver, example): 28 | """Executes a given example with using solver 'solver'""" 29 | environ["SOLVER_NAME"] = solver 30 | loader = importlib.machinery.SourceFileLoader("example", example) 31 | mod = types.ModuleType(loader.name) 32 | loader.exec_module(mod) 33 | -------------------------------------------------------------------------------- /test/mip_2d_pack.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2020 haroldo 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | 10 | """Creates a compact formulation for the two dimensional bin packing problem""" 11 | 12 | from mip import Model, BINARY, CONTINUOUS, INTEGER, xsum, minimize, MINIMIZE 13 | 14 | 15 | def create_mip(solver, w, h, W, relax=False): 16 | m = Model(solver_name=solver) 17 | n = len(w) 18 | I = set(range(n)) 19 | S = [[j for j in I if h[j] <= h[i]] for i in I] 20 | G = [[j for j in I if h[j] >= h[i]] for i in I] 21 | 22 | if relax: 23 | x = [ 24 | { 25 | j: m.add_var( 26 | var_type=CONTINUOUS, 27 | lb=0.0, 28 | ub=1.0, 29 | name="x({},{})".format(i, j), 30 | ) 31 | for j in S[i] 32 | } 33 | for i in I 34 | ] 35 | else: 36 | x = [ 37 | { 38 | j: m.add_var(var_type=BINARY, name="x({},{})".format(i, j)) 39 | for j in S[i] 40 | } 41 | for i in I 42 | ] 43 | 44 | if relax: 45 | vtoth = m.add_var(name="H", lb=0.0, ub=sum(h), var_type=CONTINUOUS) 46 | else: 47 | vtoth = m.add_var(name="H", lb=0.0, ub=sum(h), var_type=INTEGER) 48 | 49 | toth = xsum(h[i] * x[i][i] for i in I) 50 | 51 | m.objective = minimize(toth) 52 | 53 | # each item should appear as larger item of the level 54 | # or as an item which belongs to the level of another item 55 | for i in I: 56 | m += xsum(x[j][i] for j in G[i]) == 1, "cons(1,{})".format(i) 57 | 58 | # represented items should respect remaining width 59 | for i in I: 60 | m += ( 61 | ( 62 | xsum(w[j] * x[i][j] for j in S[i] if j != i) 63 | <= (W - w[i]) * x[i][i] 64 | ), 65 | "cons(2,{})".format(i), 66 | ) 67 | 68 | return m 69 | -------------------------------------------------------------------------------- /test/mip_rcpsp.py: -------------------------------------------------------------------------------- 1 | """Creates a compact MIP formulation for the resource constrained project 2 | scheduling problem""" 3 | from mip import Model, BINARY, CONTINUOUS, xsum, minimize, MINIMIZE, maximize 4 | 5 | 6 | def create_mip(solver, J, dur, S, c, r, EST, relax=False, sense=MINIMIZE): 7 | """Creates a mip model to solve the RCPSP""" 8 | NR = len(c) 9 | mip = Model(solver_name=solver) 10 | sd = sum(dur[j] for j in J) 11 | vt = CONTINUOUS if relax else BINARY 12 | x = [ 13 | { 14 | t: mip.add_var("x(%d,%d)" % (j, t), var_type=vt) 15 | for t in range(EST[j], sd + 1) 16 | } 17 | for j in J 18 | ] 19 | TJ = [set(x[j].keys()) for j in J] 20 | T = set() 21 | for j in J: 22 | T = T.union(TJ[j]) 23 | 24 | if sense == MINIMIZE: 25 | mip.objective = minimize(xsum(t * x[J[-1]][t] for t in TJ[-1])) 26 | else: 27 | mip.objective = maximize(xsum(t * x[J[-1]][t] for t in TJ[-1])) 28 | 29 | # one time per job 30 | for j in J: 31 | mip += xsum(x[j][t] for t in TJ[j]) == 1, "selTime(%d)" % j 32 | 33 | # precedences 34 | for (u, v) in S: 35 | mip += ( 36 | xsum(t * x[v][t] for t in TJ[v]) 37 | >= xsum(t * x[u][t] for t in TJ[u]) + dur[u], 38 | "prec(%d,%d)" % (u, v), 39 | ) 40 | 41 | # resource usage 42 | for t in T: 43 | for ir in range(NR): 44 | mip += ( 45 | xsum( 46 | r[ir][j] * x[j][tl] 47 | for j in J[1:-1] 48 | for tl in TJ[j].intersection( 49 | set(range(t - dur[j] + 1, t + 1)) 50 | ) 51 | ) 52 | <= c[ir], 53 | "resUsage(%d,%d)" % (ir, t), 54 | ) 55 | 56 | return mip 57 | -------------------------------------------------------------------------------- /test/numpy_test.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import numpy as np 4 | 5 | from mip import Model, OptimizationStatus 6 | from mip.ndarray import LinExprTensor 7 | from util import skip_on 8 | 9 | 10 | @skip_on(NotImplementedError) 11 | def test_numpy(): 12 | model = Model() 13 | N = 100 14 | 15 | start = time.time() 16 | x = model.add_var_tensor(shape=(N, N), name="x") 17 | 18 | # inefficient way to compute trace, so we can test optimizations 19 | # equivalent to model += np.trace(x) 20 | model += np.ones((N,)) @ (x * np.eye(N)) @ np.ones((N,)) 21 | 22 | # constraints 23 | model += np.vectorize(lambda x_i_j: x_i_j >= 1)(x) 24 | 25 | stop = time.time() 26 | print("model built in: %.1f seconds" % (stop - start)) 27 | 28 | model.write("numpy_tensors.lp") 29 | result = model.optimize() 30 | 31 | assert result == OptimizationStatus.OPTIMAL 32 | 33 | 34 | @skip_on(NotImplementedError) 35 | def test_LinExprTensor(): 36 | model = Model() 37 | x = model.add_var_tensor(shape=(3,), name="x") 38 | print(x) 39 | assert x.shape == (3,) 40 | assert isinstance(x, LinExprTensor) 41 | 42 | A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 43 | y = A @ x 44 | print(y) 45 | assert y.shape == (3,) 46 | assert isinstance(y, LinExprTensor) 47 | 48 | constr = y <= 10 49 | print(constr) 50 | assert constr.shape == (3,) 51 | assert isinstance(x, LinExprTensor) 52 | 53 | constr = y >= 10 54 | print(constr) 55 | assert constr.shape == (3,) 56 | assert isinstance(x, LinExprTensor) 57 | 58 | constr = y == 10 59 | print(constr) 60 | assert constr.shape == (3,) 61 | assert isinstance(x, LinExprTensor) 62 | 63 | 64 | if __name__ == "__main__": 65 | test_numpy() 66 | -------------------------------------------------------------------------------- /test/test_gurobi.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | import mip 4 | import mip.gurobi 5 | 6 | 7 | def test_gurobi_pip_installation(): 8 | # Even though we have no valid license yet, we could check that the binaries are found. 9 | # If no valid license is found, an InterfacingError is thrown 10 | 11 | if mip.gurobi.has_gurobi: 12 | with pytest.raises(mip.InterfacingError): 13 | mip.Model(solver_name=mip.GUROBI) 14 | -------------------------------------------------------------------------------- /test/util.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from functools import wraps 4 | 5 | 6 | def skip_on(exception): 7 | """ 8 | Skips the test in case the given exception is raised. 9 | :param exception: exception to consider 10 | :return: decorator function 11 | """ 12 | 13 | def decorator_func(f): 14 | @wraps(f) 15 | def wrapper(*args, **kwargs): 16 | try: 17 | return f(*args, **kwargs) 18 | except exception as e: 19 | pytest.skip(str(e)) 20 | 21 | return wrapper 22 | 23 | return decorator_func 24 | --------------------------------------------------------------------------------