メインコンテンツへスキップ

creating binary variables with specific indices from subset of nodepairs (edges)

回答済み

コメント

6件のコメント

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Sophia,

    You can construct your edge variables in different ways. One way would be to use a \(\texttt{for}\)-loop and the addVar method, e.g.,

    import gurobipy as gp

    m = gp.Model("test")
    E = [[0,1],[1,2],[2,3]]
    e = {}
    for i in E:
    e[(i[0],i[1])] = m.addVar(vtype='B', name='e%d%d'%(i[0],i[1]))

    m.update()
    # access variables via e[0,1], e[1,2], e[2,3]
    print(e[0,1])

    or by using the addVars method

    import gurobipy as gp

    m = gp.Model("test")
    E = [(0,1),(1,2),(2,3)]
    e = m.addVars(E,vtype='B', name='e')

    m.update()
    print(e[0,1])
    print(e[1,2])

    Note that in the latter case, the entries of \(\texttt{E}\) are tuples and not lists of length 2. If you cannot change your current code to generate tuples instead of lists of length 2, you can execute

    E = [[0,1],[1,2],[2,3]]
    E = [tuple(i) for i in E]

    which will turn each of the lists \(\texttt{[0,1],...}\) into tuples \(\texttt{(0,1),...}\)

    Best regards,
    Jaromił

    0
  • Sophia Beckmann
    Gurobi-versary
    First Comment
    First Question

    Hi Jaromił,

    thank you for helping me with this issue. I constructed my variables as you suggested first using the for loop and it works fine.

    Now I am struggeling with another issue concerning one of my constraints :

    I created another variable v:

    v = {}
    for i in edges:
        v[(i[0],i[1])] = Model.addVar(vtype = 'I', name = 'v'+str(i[0])+'_'+str(i[1]))

    Model.addConstr((gp.quicksum(e[edges[ij]] * d[ij] / v[edges[ij]] for ij in range(len(edges))) <= W * m - T), name = 'constraint 5')

    Since v[edges[ij]] is a decision variable not a constant i get the following Gurobi Error:

    '"GurobiError: Divisor must be a constant"

    Could you give me a hint on how to handle/ solve this problem? Thanks again for your helpt

    Best regards,

    Sophia

     

     

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Sophia,

    The Knowledge Base article How do I divide by a variable in Gurobi? holds the answer you seek.

    Best regards,
    Jaromił

    0
  • Sophia Beckmann
    Gurobi-versary
    First Comment
    First Question

    Hi Jaromił,

    yes, thank you, thats exactly what I am looking for. I tried to follow the lead of your recommended article but still am making some mistake I cannot seem to solve by myself.

    v = {}
    for i in edges:
    v[(i[0],i[1])] = Model.addVar(vtype = 'I', name = 'v'+str(i[0])+'_'+str(i[1]))

    #introduction continuous variable z
    z = Model.addVar(vtype = 'C', name = 'z')

    #adding constraint v*z = 1
    for ij in range(len(edges)):
        Model.addConstr(z * v[edges[ij]] == 1)

    Model.addConstr((gp.quicksum(e[edges[ij]] * d[ij] /z for ij in range(len(edges))) <= W * m - T))

    I still get the same Gurobi Error that my Divisor must be a constant (which makes sense, since z is a decision variable, just as v)? Did I misunderstand the article?

    Sorry to bother again..

    Best regards,

    Sophia

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Sophia,

    Note that by introducing the constraint \(z \cdot v_{ij} =1\) it holds that \(z=\frac{1}{v_{ij}}\). Thus, your constraint should read

    Model.addConstr((gp.quicksum(e[edges[ij]] * d[ij] * z for ij in range(len(edges))) <= W * m - T))

    Please note that currently you introduced exactly 1 auxiliary variable \(z\) to represent all divisions by each \(v_{ij}\). However, you should introduce an auxiliary variable \(z\) for each variable \(v_{ij}\)

    v = {}
    z = {}
    for i in edges:
    v[(i[0],i[1])] = Model.addVar(vtype = 'I', name = 'v'+str(i[0])+'_'+str(i[1]))
    z[(i[0],i[1])] = Model.addVar(vtype = 'I', name = 'z'+str(i[0])+'_'+str(i[1]))

    #adding constraint v*z = 1

    for ij in range(len(edges)):
       Model.addConstr(z[edges[ij]] * v[edges[ij]] == 1)

    Model.addConstr((gp.quicksum(e[edges[ij]] * d[ij] * z[ij] for ij in range(len(edges))) <= W * m - T))

    If the variables \(\texttt{e}\) and \(\texttt{d}\) are both optimization variables, then you will have to introduce additional auxiliary variable to deal with the trilinear term, cf. How do I model multilinear terms in Gurobi? If only one of the variables \(\texttt{e}\) and \(\texttt{d}\) is an optimization variable, then you very likely have to set the parameter NonConvex=2, since your model is nonconvex.

    Model.setParam("NonConvex",2)

    Best regards,
    Jaromił

    0
  • Sophia Beckmann
    Gurobi-versary
    First Comment
    First Question

    Hi Jaromił,

    thank you very much for your help! I implemented the necessary auxiliary variables as you suggested and set my parameter to NonConvex = 2 as well. I works just fine now!

    Thank you for your time!

    Best regards, Sophia

    0

サインインしてコメントを残してください。