Skip to content

Commit 84f6896

Browse files
authored
perf: use xpress c interface, xpress solution order of operations improvement, remove writing of redundant solution files (#497)
* perf: use xpress c interface and order of operations improvement * perf: only write solution file if requested or needed * refactor: adds no_solution_file_solvers constant
1 parent 2d69959 commit 84f6896

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

linopy/model.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@
5959
from linopy.matrices import MatrixAccessor
6060
from linopy.objective import Objective
6161
from linopy.remote import OetcHandler, RemoteHandler
62-
from linopy.solvers import IO_APIS, available_solvers, quadratic_solvers
62+
from linopy.solvers import (
63+
IO_APIS,
64+
NO_SOLUTION_FILE_SOLVERS,
65+
available_solvers,
66+
quadratic_solvers,
67+
)
6368
from linopy.types import (
6469
ConstantLike,
6570
ConstraintLike,
@@ -1190,7 +1195,11 @@ def solve(
11901195
if problem_fn is None:
11911196
problem_fn = self.get_problem_file(io_api=io_api)
11921197
if solution_fn is None:
1193-
solution_fn = self.get_solution_file()
1198+
if solver_name in NO_SOLUTION_FILE_SOLVERS and not keep_files:
1199+
# these (solver, keep_files=False) combos do not need a solution file
1200+
solution_fn = None
1201+
else:
1202+
solution_fn = self.get_solution_file()
11941203

11951204
if sanitize_zeros:
11961205
self.constraints.sanitize_zeros()

linopy/solvers.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@
5050
"mindopt",
5151
]
5252

53+
# Solvers that don't need a solution file when keep_files=False
54+
NO_SOLUTION_FILE_SOLVERS = [
55+
"xpress",
56+
"gurobi",
57+
"highs",
58+
"mosek",
59+
"scip",
60+
"copt",
61+
"mindopt",
62+
]
63+
5364
FILE_IO_APIS = ["lp", "lp-polars", "mps"]
5465
IO_APIS = FILE_IO_APIS + ["direct"]
5566

@@ -1578,8 +1589,7 @@ def solve_problem_from_file(
15781589

15791590
if solution_fn is not None:
15801591
try:
1581-
# TODO: possibly update saving of solution file
1582-
m.writesol(path_to_string(solution_fn))
1592+
m.writebinsol(path_to_string(solution_fn))
15831593
except Exception as err:
15841594
logger.info("Unable to save solution file. Raised error: %s", err)
15851595

@@ -1591,13 +1601,15 @@ def solve_problem_from_file(
15911601
def get_solver_solution() -> Solution:
15921602
objective = m.getObjVal()
15931603

1594-
var = [str(v) for v in m.getVariable()]
1595-
1596-
sol = pd.Series(m.getSolution(var), index=var, dtype=float)
1604+
var = m.getnamelist(xpress.Namespaces.COLUMN, 0, m.attributes.cols - 1)
1605+
sol = pd.Series(m.getSolution(), index=var, dtype=float)
15971606

15981607
try:
1599-
dual_ = [str(d) for d in m.getConstraint()]
1600-
dual = pd.Series(m.getDual(dual_), index=dual_, dtype=float)
1608+
_dual = m.getDual()
1609+
constraints = m.getnamelist(
1610+
xpress.Namespaces.ROW, 0, m.attributes.rows - 1
1611+
)
1612+
dual = pd.Series(_dual, index=constraints, dtype=float)
16011613
except (xpress.SolverError, xpress.ModelError, SystemError):
16021614
logger.warning("Dual values of MILP couldn't be parsed")
16031615
dual = pd.Series(dtype=float)

0 commit comments

Comments
 (0)