I have an integer optimisation problem that I want to solve with Mosek-Fusion. Since it might take too long, I want to impose a timeout of 10 seconds. The program stops after 10 seconds, but how can I access the best solution that Mosek found until this point?
When the program terminates normally, I get the solution via x.level()
. But when it timeouts, I get an error.
For simplicity, my MWE has a timeout of 1 second.
from mosek.fusion import *
import mosek.fusion.pythonic
import numpy as np
import sys
if __name__ == '__main__':
M = Model()
A = np.array(np.random.randint(-1,2, size = (128,256)), dtype = np.float64)
x = M.variable("x", 256, Domain.binary())
b = np.array(np.random.randint(0,20, size = (128)), dtype = np.float64)
c = np.random.random(size = 256)
M.constraint(A @ x <= b)
M.objective(ObjectiveSense.Maximize, x.T @ c)
M.setSolverParam("optimizerMaxTime", 1)
M.setLogHandler(sys.stdout)
M.solve()
print(x.level())
This yields the error
SolutionError: Solution status is Feasible but Optimal is expected. Reason: Accessing integer solution whose problem status is PrimalFeasible.
Sidenote: I want to iteratively add constraints to my problem, without rerunning it. As far as I know, changing to cvxpy therefore is not an option.
How do I obtain the best feasible solution at the end of the timeout?
You have to explicitly tell Fusion that you are interested in non-optimal solutions. See the remark in
https://docs.mosek.com/latest/pythonfusion/accessing-solution.html#retrieving-solution-values
For example
M.acceptedSolutionStatus(AccSolutionStatus.Feasible)