Skip to main content

Need help understanding the output of Gurobi for an IP problem

Answered

Comments

5 comments

  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Christos,

    Did you increase the number of PoolSolutions

    Could you please share the code you used to generate the different solutions?

    Best regards, 
    Jaromił

    0
  • Christos Kolomvakis
    • Gurobi-versary
    • First Comment
    • First Question

    Hello,

    my apologies for not posting the code, here it is (in Julia):

    model = Model(() -> Gurobi.Optimizer(env))
    # set_silent(model)
    # set_optimizer_attribute(model, "OutputFlag", 0)
    # set_optimizer_attribute(model, "LogToConsole", 0)
    set_optimizer_attribute(model, "NonConvex", 2)
    @variable(model, y[1:m], Bin)
    @variable(model, h[1:r], Bin)
    @objective(model, Min, 3 - 2*y[2] - 2*y[4] - 2*y[5] + y[1] + y[2] + y[3] + y[4] + y[5])
    @constraints(model, begin
    h[2]/r <= y[1]
    y[1] <= h[2]
    h[2]/r <= y[3]
    y[3] <= h[2]
    (h[1]+h[3]+h[4])/r <= y[2]
    y[2] <= h[1] + h[3] + h[4]
    (h[1]+h[3]+h[4])/r <= y[5]
    y[5] <= h[1] + h[3] + h[4]
    (h[5]+h[3]+h[4])/r <= y[4]
    y[4] <= h[5] + h[3] + h[4]
    end)

    set_time_limit_sec(model,timelimit)
    JuMP.set_optimizer_attribute(model, "PoolSolutions", 20)
    JuMP.optimize!(model)

    println(JuMP.value.(h))
    println(JuMP.value.(y))

    I set the PoolSolutions to 20 but that did not seem to influence the result.

    Thanks for your quick response,
    Christos

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    Hi Christos,

    I am not a JuMP user so I unfortunately cannot help much with your code. However, I tested your model and the setting in gurobipy. I used the poolsearch.py example to check how the PoolSolutions feature works. I used the below code

    import gurobipy as gp
    from gurobipy import GRB

    m = gp.Model()

    N = [1,2,3,4,5]

    y = m.addVars(N, vtype = GRB.BINARY, name="y")
    h = m.addVars(N, vtype = GRB.BINARY, name="h")

    m.setObjective(3 - 2*y[2] - 2*y[4] - 2*y[5] + y[1] + y[2] + y[3] + y[4] + y[5])

    r = 5

    m.addConstr(h[2] / r <= y[1])
    m.addConstr(y[1] <= h[2])
    m.addConstr(h[2] / r <= y[3])
    m.addConstr(y[3] <= h[2])
    m.addConstr((h[1] + h[3] + h[4])/r <= y[2])
    m.addConstr(y[2] <= h[1] + h[3] + h[4])
    m.addConstr((h[1] + h[3] + h[4])/r <= y[5])
    m.addConstr(y[5] <= h[1] + h[3] + h[4])
    m.addConstr((h[5] + h[3] + h[4])/r <= y[4])
    m.addConstr(y[4] <= h[5] + h[3] + h[4])

    # write a human readable model file to check whether the model is correct
    m.write("myLP.lp")

    # set parameters
    m.setParam("PoolSearchMode",2)
    m.setParam("PoolSolutions", 10)
    m.optimize()

    # get number of solutions
    nSolutions = m.SolCount

    # iterate over all solutions and print the objective
    # and variable values
    for e in range(nSolutions):
        m.setParam("SolutionNumber",e)
        print(f"obj: {m.PoolObjVal}")
        for i in N:
            print(f"{y[i].VarName}: {y[i].Xn}")
        for i in N:
            print(f"{h[i].VarName}: {h[i].Xn}")

        print("================================")

    When I run this code on my personal Mac using Gurobi v11 I get the solutions

    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: 0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: 1.0
    h[2]: 0.0
    h[3]: 1.0
    h[4]: 1.0
    h[5]: 1.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: -0.0
    h[2]: -0.0
    h[3]: -0.0
    h[4]: 1.0
    h[5]: -0.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: 1.0
    h[2]: -0.0
    h[3]: 1.0
    h[4]: -0.0
    h[5]: -0.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: 1.0
    h[2]: -0.0
    h[3]: -0.0
    h[4]: -0.0
    h[5]: 1.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: -0.0
    h[2]: -0.0
    h[3]: 1.0
    h[4]: -0.0
    h[5]: 0.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: -0.0
    h[2]: -0.0
    h[3]: 0.0
    h[4]: 1.0
    h[5]: 1.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: 1.0
    h[2]: -0.0
    h[3]: -0.0
    h[4]: 1.0
    h[5]: 0.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: -0.0
    h[2]: -0.0
    h[3]: 1.0
    h[4]: 1.0
    h[5]: -0.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: -0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: -0.0
    h[2]: -0.0
    h[3]: 1.0
    h[4]: -0.0
    h[5]: 1.0
    ================================
    obj: 0.0
    y[1]: 0.0
    y[2]: 1.0
    y[3]: 0.0
    y[4]: 1.0
    y[5]: 1.0
    h[1]: 1.0
    h[2]: 0.0
    h[3]: 1.0
    h[4]: 1.0
    h[5]: -0.0
    ================================

    You can see that the objective value and y variable values are always the same and the values for h variables change.

    I don't know how to replicate the Python code in JuMP but maybe someone else in the Community might help.

    Best regards, 
    Jaromił

    0
  • Christos Kolomvakis
    • Gurobi-versary
    • First Comment
    • First Question

    Hello and thank you for your response,

    I will try study and try to replicate the example in JuMP.

    Kind regards,
    Christos

    0
  • Christos Kolomvakis
    • Gurobi-versary
    • First Comment
    • First Question

    Alright it works! I must have made a mistake before to get the same result always.

    Thank you so much for your help,
    Christos

    0

Please sign in to leave a comment.