Skip to main content

How to solve continuous-variable quadratic program and do warm-stating

Awaiting user input

Comments

5 comments

  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Shadi,

    There is nothing wrong with your code.  Your variables are continuous but the optimal solution just naturally has integer values.  If there was a better solution with non-integer values then it would find it - but there isn't.

    You can provide a valid starting extreme point to warm start, either through PStart, DStart, or through VBasis, CBasis. Note that this disables LP presolve by default. For models where presolve greatly reduces the problem size, this might hurt performance. To allow presolve, you need to set parameter LPWarmStart to 2. 

    - Riley

    0
  • Shadi Beheshti
    Gurobi-versary
    First Comment
    First Question

    Thanks for the reply and your great help.

    I expect to have at least some continuous values where I stop Gurobi where the MIPGap is still large. For example, in the following code:

    import numpy as np
    from numpy.linalg import inv
    import quimb as qu
    import quimb.tensor as qtn
    import networkx as nx
    import itertools
    import tqdm
    from scipy.sparse import csc_matrix
    from itertools import product
    import numba as nb
    import copy
    import matplotlib.pyplot as plt
    from scipy import optimize

    Adj_G = np.array([[0.        , 0.05219673, 0.        , 0.16303623, 0.        ,
            0.67521474, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.09561873, 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.55474926],
           [0.05219673, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.49808213, 0.        , 0.53599452,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.04826614,
            0.        , 0.        , 0.        , 0.51098376, 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.9012575 , 0.2084062 ,
            0.        , 0.        , 0.        , 0.        , 0.62677833,
            0.19434701, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.37677331, 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.16303623, 0.        , 0.9012575 , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.88774306,
            0.        , 0.84029947, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.41976977, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.2084062 , 0.        , 0.        ,
            0.87952865, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.92751916, 0.        , 0.        ,
            0.        , 0.        , 0.86352158, 0.64232798, 0.        ,
            0.        ],
           [0.67521474, 0.        , 0.        , 0.        , 0.87952865,
            0.        , 0.5057895 , 0.        , 0.        , 0.        ,
            0.80035643, 0.        , 0.        , 0.24959981, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.5057895 , 0.        , 0.45582632, 0.26956553, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.64960479, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.66420765,
            0.        ],
           [0.        , 0.49808213, 0.        , 0.        , 0.        ,
            0.        , 0.45582632, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.05319689, 0.        , 0.        , 0.33955944,
            0.        , 0.        , 0.79072681, 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.26956553, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.95428089, 0.80772909, 0.5564221 , 0.        , 0.        ,
            0.78341913],
           [0.        , 0.53599452, 0.62677833, 0.88774306, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.45334776,
            0.00274732, 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.19434701, 0.        , 0.        ,
            0.80035643, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.02048179, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.43266406, 0.56560779, 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.84029947, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.89235174, 0.        , 0.        ,
            0.47988292, 0.        , 0.        , 0.        , 0.        ,
            0.66394688, 0.        , 0.        , 0.        , 0.        ,
            0.40707133],
           [0.09561873, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.89235174, 0.        , 0.38101796, 0.        ,
            0.        , 0.        , 0.24381057, 0.        , 0.        ,
            0.82976059, 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.24959981, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.38101796, 0.        , 0.30463268,
            0.        , 0.        , 0.        , 0.85735497, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.14984741,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.30463268, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.66473423, 0.78331818, 0.        , 0.55290625,
            0.10918973],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.47988292, 0.        , 0.        , 0.        ,
            0.        , 0.64922511, 0.54986399, 0.        , 0.        ,
            0.        , 0.29496819, 0.        , 0.        , 0.98257993,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.05319689, 0.        , 0.        ,
            0.02048179, 0.        , 0.        , 0.        , 0.        ,
            0.64922511, 0.        , 0.        , 0.66010914, 0.        ,
            0.        , 0.        , 0.        , 0.57230448, 0.        ,
            0.        ],
           [0.        , 0.        , 0.37677331, 0.        , 0.92751916,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.24381057, 0.        , 0.        ,
            0.54986399, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.53402091, 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.41976977, 0.        ,
            0.        , 0.64960479, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.85735497, 0.        ,
            0.        , 0.66010914, 0.        , 0.        , 0.66693744,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.04826614, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.33955944, 0.        , 0.45334776,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.66693744, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.79111979],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.95428089, 0.00274732,
            0.        , 0.66394688, 0.82976059, 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.89126883, 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.80772909, 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.66473423,
            0.29496819, 0.        , 0.53402091, 0.        , 0.        ,
            0.89126883, 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.86352158,
            0.        , 0.        , 0.79072681, 0.5564221 , 0.        ,
            0.43266406, 0.        , 0.        , 0.        , 0.78331818,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ],
           [0.        , 0.51098376, 0.        , 0.        , 0.64232798,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.56560779, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.57230448, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.        , 0.49486887,
            0.        ],
           [0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.66420765, 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.14984741, 0.55290625,
            0.98257993, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.49486887, 0.        ,
            0.        ],
           [0.55474926, 0.        , 0.        , 0.        , 0.        ,
            0.        , 0.        , 0.        , 0.78341913, 0.        ,
            0.        , 0.40707133, 0.        , 0.        , 0.10918973,
            0.        , 0.        , 0.        , 0.        , 0.79111979,
            0.        , 0.        , 0.        , 0.        , 0.        ,
            0.        ]])

    #Find the adjacency matrix of the graph
    G = nx.Graph()   # or DiGraph, MultiGraph, MultiDiGraph, etc
    G.add_weighted_edges_from(terms)
    Adj_G = (nx.adjacency_matrix(G)).todense()
    #Generate single-term entries of Qubo matrix
    Mu = np.zeros((len(Adj_G),1))
    for i in range(0, len(Adj_G)):
        Mu[i] = sum(Adj_G[i,:])  
    Mu = np.transpose(Mu)
    Sigma = Adj_G.copy()

    import gurobipy as gp
    import numpy as np
    import matplotlib.pyplot as plt

    # Create a Gurobi model
    model = gp.Model()

    # Create variables
    x = [model.addVar(vtype=gp.GRB.CONTINUOUS, name="x%s" % i, lb=0, ub=1) for i in range(len(Sigma))]
    objective = sum([Mu[0][i] * x[i] for i in range(len(Sigma))])
    objective -= 2 * sum(
            [Sigma[i][j] * x[i] * x[j] for i in range(len(Sigma)) for j in range(len(Sigma))]
       )
    # Set objective: quadratic function (non-convex)
    model.setObjective(objective, gp.GRB.MAXIMIZE)
    model.setParam("NonConvex", 2)
    # Optimize the model with callback to track objective values
    objective_values = []

    def callback(model, where):
        if where == gp.GRB.Callback.MIP:
            current_obj = model.cbGet(gp.GRB.Callback.MIP_OBJBST)
            objective_values.append(current_obj)
    model.setParam('outputFlag',True)
    # Set the callback function
    model.optimize(callback)
    #model.optimize()

    for v in model.getVars():
        print('%s: %g' % (v.varName, v.x))

    This code gives me the following output:

    Optimize a model with 0 rows, 26 columns and 0 nonzeros
    Model fingerprint: 0x6903cd3e
    Model has 65 quadratic objective terms
    Coefficient statistics:
      Matrix range     [0e+00, 0e+00]
      Objective range  [2e+00, 4e+00]
      QObjective range [2e-02, 8e+00]
      Bounds range     [1e+00, 1e+00]
      RHS range        [0e+00, 0e+00]
    
    Continuous model is non-convex -- solving as a MIP
    
    Found heuristic solution: objective -0.0000000
    Presolve time: 0.01s
    Presolved: 65 rows, 91 columns, 195 nonzeros
    Variable types: 0 continuous, 91 integer (91 binary)
    
    Root relaxation: objective 3.191450e+01, 27 iterations, 0.00 seconds (0.00 work units)
    
        Nodes    |    Current Node    |     Objective Bounds      |     Work
     Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
    
         0     0   31.91450    0   24   -0.00000   31.91450      -     -    0s
    H    0     0                      23.7008622   31.91450  34.7%     -    0s
    H    0     0                      24.6478244   31.91450  29.5%     -    0s
    H    0     0                      25.1587044   31.91450  26.9%     -    0s
    H    0     0                      25.4479741   28.63059  12.5%     -    0s
         0     0   28.57396    0   25   25.44797   28.57396  12.3%     -    0s
         0     0   27.48074    0   32   25.44797   27.48074  7.99%     -    0s
    H    0     0                      25.7761577   27.48074  6.61%     -    0s
    
    Cutting planes:
      Gomory: 1
      MIR: 2
      Zero half: 21
      RLT: 5
    
    Explored 1 nodes (70 simplex iterations) in 0.03 seconds (0.00 work units)
    Thread count was 8 (of 8 available processors)
    
    Solution count 6: 25.7762 25.448 25.1587 ... -0
    
    Optimal solution found (tolerance 1.00e-04)
    Best objective 2.577615770146e+01, best bound 2.577615770146e+01, gap 0.0000%
    
    User-callback calls 138, time in user-callback 0.00 sec
    x0: 1
    x1: 0
    x2: -0
    x3: 0
    x4: 1
    x5: 0
    x6: -0
    x7: 1
    x8: 1
    x9: 1
    x10: 1
    x11: 0
    x12: 1
    x13: -0
    x14: 1
    x15: 1
    x16: 0
    x17: -0
    x18: 1
    x19: 0
    x20: -0
    x21: 0
    x22: 0
    x23: 0
    x24: 0
    x25: 0

    Then, I try to stop it where the Mipgap is still large by adding the command:
    model.setParam("MIPGap", 3.47), However, I still get binaries.
    So, even in the early stage of optimization process, it gives me binary.
    I am solving maxcut problem. Even for large number of variables,
    it gives me binary in the early stage of optimization!!

     

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Shadi,

    As you can see in the log, the presolve routine is creating a model in which the variables are binary.

    See "How does presolve work?"

    If you turn presolve off:

    model.params.presolve=0

    then you can avoid this behavior (although I don't see a benefit in doing this).

    If you were to set a solution limit of 2, for example, :

    model.params.SolutionLimit=2

    then you will see you get fractional solutions found - however don't expect the optimal solution to be fractional.

    - Riley

    0
  • Shadi Beheshti
    Gurobi-versary
    First Comment
    First Question

    Thanks a lot for your great help and the nice clarification.

    Sure. You are right. The pre-solver considers the variables as binaries.

    I deactivate the pre-solver in the early stage of process using 

    import gurobipy as gp
    import numpy as np
    import matplotlib.pyplot as plt

    # Create a Gurobi model
    model = gp.Model()

    # Create variables
    x = [model.addVar(vtype=gp.GRB.CONTINUOUS, name="x%s" % i, lb=0, ub=1) for i in range(len(Sigma))]
    objective = sum([Mu[0][i] * x[i] for i in range(len(Sigma))])
    objective -= 2 * sum(
            [Sigma[i][j] * x[i] * x[j] for i in range(len(Sigma)) for j in range(len(Sigma))]
       )
    # Set objective: quadratic function (non-convex)
    model.setObjective(objective, gp.GRB.MAXIMIZE)
    model.setParam("NonConvex", 2)
    model.params.presolve=0
    model.params.SolutionLimit=2
    # Optimize the model with callback to track objective values
    objective_values = []

    def callback(model, where):
        if where == gp.GRB.Callback.MIP:
            current_obj = model.cbGet(gp.GRB.Callback.MIP_OBJBST)
            objective_values.append(current_obj)
    model.setParam('outputFlag',True)
    # Set the callback function
    model.optimize(callback)
    #model.optimize()

    for v in model.getVars():
        print('%s: %g' % (v.varName, v.x))

    that gives me the following outputlog:

    Set parameter NonConvex to value 2
    Set parameter Presolve to value 0
    Set parameter SolutionLimit to value 3
    Gurobi Optimizer version 10.0.2 build v10.0.2rc0 (mac64[arm])
    
    CPU model: Apple M1
    Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
    
    Optimize a model with 0 rows, 20 columns and 0 nonzeros
    Model fingerprint: 0x439bdf76
    Model has 190 quadratic objective terms
    Coefficient statistics:
      Matrix range     [0e+00, 0e+00]
      Objective range  [8e+00, 1e+01]
      QObjective range [2e-02, 8e+00]
      Bounds range     [1e+00, 1e+00]
      RHS range        [0e+00, 0e+00]
    
    Continuous model is non-convex -- solving as a MIP
    
    Found heuristic solution: objective -0.0000000
    Variable types: 211 continuous, 0 integer (0 binary)
    
    Root relaxation: objective 9.623557e+01, 86 iterations, 0.00 seconds (0.00 work units)
    
        Nodes    |    Current Node    |     Objective Bounds      |     Work
     Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
    
         0     0   96.23557    0  190   -0.00000   96.23557      -     -    0s
    H    0     0                       6.2015125   96.23557  1452%     -    0s
    H    0     0                      38.7463939   96.23557   148%     -    0s
    
    Explored 1 nodes (86 simplex iterations) in 0.01 seconds (0.00 work units)
    Thread count was 8 (of 8 available processors)
    
    Solution count 3: 38.7464 6.20151 -0 
    
    Solution limit reached
    Best objective 3.874639385111e+01, best bound 9.623557229450e+01, gap 148.3730%
    
    User-callback calls 48, time in user-callback 0.00 sec
    x0: 2.32926e-10
    x1: 1.07374e-09
    x2: 2.36949e-10
    x3: 2.24515e-10
    x4: 1
    x5: 5.20858e-10
    x6: 1
    x7: 3.94854e-10
    x8: 1
    x9: 1
    x10: 2.14363e-10
    x11: 5.63529e-10
    x12: 1
    x13: 5.96567e-10
    x14: 2.28581e-10
    x15: 1
    x16: 3.25358e-10
    x17: 1
    x18: 3.79257e-10
    x19: 2.68775e-10

    However, I still get the solutions that are very close to binaries. Would you please let me know if you think the solver rounds the solutions to binaries? If yes, is there ant way to avoid that and get fractional values. Thanks a lot for your help

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Shadi,

    Your code:

    model.params.SolutionLimit=2

    The log:

    Set parameter SolutionLimit to value 3

    What went wrong here?

     

    However, I still get the solutions that are very close to binaries. Would you please let me know if you think the solver rounds the solutions to binaries?

    In your example you have printed out the solutions from the solver, which are not rounded, but you're asking if the solver rounds them?  I'm confused.

    If you are wanting a non-optimal non-integral solution then there are many ways you could get one, including just forcing it by setting lb = ub = 0.5 on all the variables:

    x = [model.addVar(vtype=gp.GRB.CONTINUOUS, name="x%s" % i, lb=0.5, ub=0.5) for i in range(len(Sigma))]

    Perhaps we need to address what you are ultimately trying to do, because a lot of this isn't making sense to me.  Why are you wanting a non-optimal non-integer solution?

    - Riley

    0

Please sign in to leave a comment.