How to use the .sol files to set multiple MIP Starts?
AnsweredDear all,
According to the following example given in this page(https://support.gurobi.com/hc/en-us/articles/360043834831-How-do-I-use-MIP-starts-),
model.NumStart = 2
# iterate over all MIP starts
for s in range(model.NumStart):
# set StartNumber
model.params.StartNumber = s
# now set MIP start values using the Start attribute, e.g.:
for v in model.getVars():
v.Start = <value>
I tried to set multiple MIP starts by using the .sol files retrieved by setting SolFiles parameter. I only changed the code as follow,
model.NumStart = 2
# iterate over all MIP starts
for s in range(model.NumStart):
# set StartNumber
model.params.StartNumber = s
# now set MIP start values using the .sol file, e.g.:
model.update()
model.read('solutions/solution_%d.sol'%(16 - s))
PS: I got 16 .sol files by setting the SolFiles.
Unfortunately, I got the following message
No start values specified in MIP start
No start values specified in MIP start
No start values specified in MIP start
No start values specified in MIP start
No start values specified in MIP start
So, I am wondering if I can use .sol file to set multiple MIP starts? and how to do that?
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
One way to use .sol file to set multiple MIP starts is by reading the .sol files and using the Start Attribute directly as follow,
model.NumStart = 10
# iterate over all MIP starts
model.update()
for s in range(model.NumStart):
# set StartNumber
model.params.StartNumber = swith open('{}_{}.sol'.format(model.ModelName, s), 'r') as f:
for line in f:
line.strip()
(names, xn) = line.split()
for var in model.getVars():
if var.varName == names:
var.Start = np.array(xn)This method contains two loops, which may be inefficient. I would be very appreciated if someone can give me a much better way.
0 -
Hi Jiongjian,
just to be sure to understand your workflow:
- You solve a MIP and by setting the \(\texttt{SolFiles}\) parameter you write all solutions that come up during the solution process to a file.
- Then, you again solve the same MIP and want to use the SOL files obtained in the first run as MIP starts.
Is this correct?
Your code looks ok (I guess the lines within the loop are indented). Note that you do not necessarily need \(\texttt{model.update()}\). Are you sure that the two SOL files with number 15 and 16 exist and that the file format is valid, see here?
Best regards,
Mario0 -
Hi Jiongjian,
my answer above refers to your first message. The approach used there should work, I just tried it. Could you please show more details of your Gurobi output?
Best regards,
Mario0 -
Hi Mario,
Thank you very much for your help. Actually, my full model contains a quadartic constraint that hugely increase the difficulty of my problem(10000s to get the first feasible point). But luckily, in my problem, I can first ignore the quadartic constraint and compute several feasible solutions(300s) of both the sub and the full model. Then I use them as MIP starts of the full problem to accelerate the computation process.
As for the solution number and format, I just use the Params.PoolSolutions to control the number of the solution I need and use the following code adapted from your website to restore the solution,
gv = LCB.getVars()
names = LCB.getAttr('VarName', gv)
for i in range(LCB.SolCount):
model.params.SolutionNumber = i
xn = model.getAttr('Xn', gv)
lines = ["{} {}".format(v1, v2) for v1, v2 in zip(names, xn)]
with open('{}_{}.sol'.format(model.ModelName, i), 'w') as f:
f.write("\n".join(lines))But, by using this two stage strategy, the solution of the full model heavily depends on the MIP start. Does this mean my model has several sub-optimal point and the MIP solver is stucked in one of them?
Another question is if I use the following code to model constraint e_r_pw = -sqrt(3)*r_pw,
r_min = 0
r_max = 1
size = 1e-3
r_pw = np.arange(r_min, r_max, size)
e_r_pw = np.exp(-np.sqrt(3) * r_pw)model.addGenConstrPWL(r_xX_list[i], e_xX_list[i], r_pw, e_r_pw)
What type of SOS constraint will be used to determined which piece of line of r_pw is used? Is SOS I constraint or SOS II constraint? I guess it is SOS II, because in this way, we can compute any point in the piece we choose.
All the best,
Jiongjian Cai
0 -
Hi Jiongjian,
Regarding your MIP start question: Every change in parameters or MIP starts can potentially have a large effect on the solver runtime due to different solution paths in presolving, branch-and-bound, etc. It is hard to say what exactly happens in your case but you could post the solver output to get more insights.
Regarding your PWL constraint: Yes, Gurobi implements a piecewise-linear constraint with an SOS2 system (and might potentially exploit this knowledge in presolving and branching), i.e., each point on the function is defined by a convex combination of the two endpoints of the current segment. Note that you might obtain a better approximation of your function by using function constraints, see here.
Best regards,
Mario0
Post is closed for comments.
Comments
6 comments