Skip to content

Commit

Permalink
added scip_cmd, added uv (#804)
Browse files Browse the repository at this point in the history
* added scip_cmd, added uv

* fix bug

* fix scip_cmd tests and scip_cmd

* added pulp installation + removed pip.

* retry downloading scip

* retry SCIP

* FSCIP_CMD tests sometimes fail.
  • Loading branch information
pchtsp authored Feb 24, 2025
1 parent 6f9138a commit 7c8aa93
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 43 deletions.
57 changes: 22 additions & 35 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,27 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv and set the python version
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
- name: Update pip, install dev deps
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
run: uv pip install -r requirements-dev.txt
- name: Code Quality
run: |
python -m pip install black
black pulp/ --check
run: black pulp/ --check
- name: Type Check
run: |
mypy ./
- name: Install dependencies
run: |
python -m pip install .
- name: install glpk
run: mypy ./
- name: install ubuntu-only solvers
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update -qq
sudo apt-get install -qq glpk-utils
sudo apt update -qq
sudo apt install -qq glpk-utils
- name: install xpress
if: matrix.os != 'macOS-latest' && matrix.python-version != '3.12'
run: python -m pip install xpress
- name: Install gurobipy
run: |
python -m pip install gurobipy
- name: Install highspy
if: matrix.python-version != '3.12'
# alternatively if: contains(fromJSON("['3.8', '3.9', '3.10', '3.11']"), matrix.python-version)
run: uv pip install xpress
- name: Install other solvers, gurobi, highspy, coptpy, saspy, swat, SCIP_PY
run: |
python -m pip install highspy "numpy<2"
uv pip install gurobipy highspy "numpy<2" coptpy saspy swat pyscipopt .
- name: Install highspy cmd
if: matrix.os == 'ubuntu-latest'
uses: supplypike/setup-bin@v4
Expand All @@ -58,17 +49,13 @@ jobs:
subPath: 'bin'
name: 'highs'
version: '1.7.1'
- name: Install coptpy
run: |
python -m pip install coptpy
- name: Install saspy
run: |
python -m pip install saspy
- name: Install swat
run: |
python -m pip install swat
- name: Install SCIP_PY
run: |
python -m pip install pyscipopt
- name: Install SCIP_CMD
if: matrix.os == 'ubuntu-latest'
uses: supplypike/setup-bin@v4
with:
uri: 'https://www.scipopt.org/download/release/SCIPOptSuite-9.2.1-Linux-ubuntu24.deb'
name: 'SCIPOptSuite-9.2.1-Linux-ubuntu24.deb'
version: '9.2.1'
command: "sudo apt install -qq ./SCIPOptSuite-9.2.1-Linux-ubuntu24.deb"
- name: Test with pulptest
run: pulptest
run: uv run --no-project pulp/tests/run_tests.py
9 changes: 5 additions & 4 deletions pulp/apis/scip_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,6 @@ def readsol(filename):
)
values = {}

if status in SCIP_CMD.NO_SOLUTION_STATUSES:
return status, values

# Look for an objective value. If we can't find one, stop.
try:
line = f.readline()
Expand All @@ -211,7 +208,8 @@ def readsol(filename):
assert len(comps) == 2
float(comps[1].strip())
except Exception:
raise PulpSolverError(f"Can't get SCIP solver objective: {line!r}")
# we assume there was not solution found
return status, values

# Parse the variable values.
for line in f:
Expand All @@ -221,6 +219,9 @@ def readsol(filename):
except:
raise PulpSolverError(f"Can't read SCIP solver output: {line!r}")

# if we have a solution, we should change status to Optimal by conventio
status = constants.LpStatusOptimal

return status, values


Expand Down
13 changes: 9 additions & 4 deletions pulp/tests/test_pulp.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,13 @@ def test_unbounded(self):
elif self.solver.__class__ is GLPK_CMD:
# GLPK_CMD Does not report unbounded problems, correctly
pulpTestCheck(prob, self.solver, [const.LpStatusUndefined])
elif self.solver.__class__ in [GUROBI_CMD, SCIP_CMD, FSCIP_CMD, SCIP_PY]:
elif self.solver.__class__ in [GUROBI_CMD, SCIP_CMD, SCIP_PY]:
# GUROBI_CMD has a very simple interface
pulpTestCheck(prob, self.solver, [const.LpStatusNotSolved])
elif self.solver.__class__ in [CHOCO_CMD, HiGHS_CMD]:
elif self.solver.__class__ in [CHOCO_CMD, HiGHS_CMD, FSCIP_CMD]:
# choco bounds all variables. Would not return unbounded status
# highs_cmd is inconsistent
# FSCIP_CMD is inconsistent
pass
else:
pulpTestCheck(prob, self.solver, [const.LpStatusUnbounded])
Expand Down Expand Up @@ -850,10 +851,11 @@ def test_elastic_constraints_penalty_unbounded(self):
elif self.solver.__class__ is GLPK_CMD:
# GLPK_CMD Does not report unbounded problems, correctly
pulpTestCheck(prob, self.solver, [const.LpStatusUndefined])
elif self.solver.__class__ in [GUROBI_CMD, FSCIP_CMD]:
elif self.solver.__class__ in [GUROBI_CMD, SCIP_CMD]:
pulpTestCheck(prob, self.solver, [const.LpStatusNotSolved])
elif self.solver.__class__ in [CHOCO_CMD]:
elif self.solver.__class__ in [CHOCO_CMD, FSCIP_CMD]:
# choco bounds all variables. Would not return unbounded status
# FSCIP_CMD returns optimal
pass
else:
pulpTestCheck(prob, self.solver, [const.LpStatusUnbounded])
Expand Down Expand Up @@ -1292,6 +1294,7 @@ def test_measuring_solving_time(self):
solver_settings = dict(
PULP_CBC_CMD=30,
COIN_CMD=30,
SCIP_PY=30,
SCIP_CMD=30,
GUROBI_CMD=50,
CPLEX_CMD=50,
Expand Down Expand Up @@ -1352,6 +1355,8 @@ def test_invalid_var_names(self):
prob += w >= 0, "c4"
if self.solver.name not in [
"GUROBI_CMD", # end is a key-word for LP files
"SCIP_CMD", # not sure why it returns a wrong result
"FSCIP_CMD", # not sure why it returns a wrong result
]:
pulpTestCheck(
prob,
Expand Down

0 comments on commit 7c8aa93

Please sign in to comment.