Forum Discussion

FICO's avatar
FICO
Community Manager
4 years ago

How to get multiple solution

p.addcbintsol (printsol, None, 0)
 
    
 
    p.mipoptimize ("")

The solver only returns one feasible solution in the callback function then stop, how do I ask for multiple solutions ?

3 Replies

  • FICO's avatar
    FICO
    Community Manager

    Hi Yang Du,

    I assume that you either work with a feasibility problem, where finding any solution would lead to immediate termination, or with an optimization problem where the first solution the solver finds happens to be an optimal one. Also in the latter case, the solver will prune the search space s.t. all potential other feasible solutions become cut off and spend the remaining time proving the optimality of the said solution. There is a way, though, how you can make the solver also consider suboptimal parts of the search space and this is by the MIPADDCUTOFF control:

    https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/MIPADDCUTOFF.html

    As documented, setting it to (large) negative values will enforce (large) progression steps in a sequence of incumbent solutions. By default, it is set to a small negative value, which represents minimum progress between one solution and the next.

    Setting it to a POSITIVE value, however, will make the solver also accept solutions that are worse than the best one seen so far (worse by at most MIPADDCUTOFF) and might be what you are looking for in your application.

    Note that of course depending on your problem it might happen that

    a) the solution to your problem is unique, in which case there is simply no way to get another solution or

    b) there are MANY alternative optima. In this case, you might want to set a MAXMIPSOL limit

    Best regards,

    Timo

  • FICO's avatar
    FICO
    Community Manager

    Hi Timo,

    Thanks for your reply. I'm working with feasibility problem and I'm sure there are many feasible solutions. I tried your proposal but still only get one solution.

        p.setControl({'MIPADDCUTOFF': 1, 'MAXMIPSOL':5})
        p.addcbintsol (printsol, None, 0)
        p.solve()
     
    def  printsol(my_prob, object):
        cols = my_prob.attributes.originalcols
        objval = my_prob.attributes.lpobjval
        x = []
        my_prob.getlpsol (x, None, None, None)
        print ("Integer solution found:", objval, "; values:")
  • FICO's avatar
    FICO
    Community Manager

    Hi Yang Du,

    Curious. Could you try to add an artificial objective that you minimize (for maximization, the logic of negative/positive would have to be inverted), just as an experiment? Maybe there is only a single optimum?

    Anyhow, an alternative approach and a slightly more involved variant would be to implement a preintsol callback (unlike intsol, this is called BEFORE the solution will be accepted by the Optimizer) and always reject the solution via the p_reject field, see https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/XPRSaddcbpreintsol.html (and do whatever you want to do with the solution, like storing it away yourself. Note that due to heuristics, the Optimizer might now try to present you the same solution multiple times, so it would be up to you to check this (e.g., by a pairwise comparison). That workflow is independent of the MIPADDCUTOFF approach.

    Timo