Skip to main content

lb and ub of variables

Answered

Comments

13 comments

  • Official comment
    Simranjit Kaur
    Gurobi Staff Gurobi Staff
    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?.
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Hi Yansong,

    Note that the default lower bound for a variable is 0.0, so the first and third code block is more restrictive on the lower bound than in the second one, see the addVars() description. Your solution might require negative values which should explain infeasibility.

    Best regards,
    Mario

    1
  • yansong bai
    Gurobi-versary
    Conversationalist
    Curious

    Thank you very much for your prompt reply. It means if i don't set the lb or ub bound for a variable, the default value is 0?  But when i export the model corresponding to the first code and the third code,it shows  "fij  free" ,and it looks like there is no default limit of "fij" .

    0
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Yes, if you don't set LB and UB, the default values will be 0 and infinity, respectively.

    Did you export the model with write()? Which file format did you use? Could you please post the file for the first model variant (with default bounds)?

    0
  • yansong bai
    Gurobi-versary
    Conversationalist
    Curious

    Hi,Mario

    Yes, i export the model with write.

    \ LP format - for model browsing. Use MPS format to capture full model detail.
    Maximize
    ....
    Subject To
    R0: ai[0,0] = 1

    .....(the constraints are omitted)


    R663: - 0.01 ai[1,1] + fij[0,1] - fij[2,1] - fij[3,1] - fij[4,1] = 0
    Bounds
    fij[0,0] free,......
    Binaries
    ai[0,0],.......
    End

    the .lp file shows something like this if i don't set the lb and ub. I thought "free" means no boundaries before, but the result seems like to be the default boundaries(fij>=0)

    0
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Hi Yansong,

    This is indeed strange. I just tried to reproduce your issue on my side but when I create variables and constraints as you did it in your first block, then the LP file contains no information in the corresponding "Bounds" section which implies that default bounds 0 and infinity are used.
    Your assumption is correct that "free" should mean no bounds at all, i.e., -inf to +inf.

    Which Gurobi and Python version are you using? I used Gurobi 9.1.2 and Python 3.8.

    0
  • yansong bai
    Gurobi-versary
    Conversationalist
    Curious

    Gurobi version is 9.1.2 and Python is 3.7. The environment used is PyCharm.

    0
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Could you produce a small version of your Python script in which you still see the "free" variables in the LP file and post it here?

    0
  • yansong bai
    Gurobi-versary
    Conversationalist
    Curious
    import numpy as np
    import math
    import pandas as pd
    import gurobipy as gp
    from gurobipy import GRB

    set1 = range(0,46)
    set3 = range(0,39)
    set4 = range(0,10)
    set5 = range(29,39)
    set2 = range(0,20)
    index = np.array(set5)
    CU = np.setdiff1d(set3,set5)
    CU = CU.tolist()
    CW = [2,6,6,6,6,6,6,6,6,6];CW = np.array(CW)


    bu1 = [1,1,2,2,2,3,3,4,4,5,5,6,6,6,7,8,9,10,10,10,12,12,13,14,15,16,16,16,16,17,17,19,19,20,21,22,22,23,23,25,25,26,26,26,28,29]
    bu1 = np.array(bu1) - 1
    bu2 = [2,39,3,25,30,4,18,5,14,6,8,7,11,31,8,9,39,11,13,32,11,13,14,15,16,17,19,21,24,18,27,20,33,34,22,23,35,24,36,26,37,27,28,29,29,38]
    bu2 = np.array(bu2) - 1
    ac = gp.tuplelist([(bu1[i],bu2[i]) for i in set1])
    data1 = [0.560900000000000,1.01650000000000,1.06770000000000,1.10840000000000,0.924000000000000,0.879500000000000,0.500000000000000,0.678400000000000,0.536300000000000,0.698700000000000,0.674300000000000,0.530200000000000,0.762300000000000,1.08070000000000,0.910500000000000,1.50000000000000,1.05160000000000,0.771800000000000,0.702800000000000,0.520500000000000,0.633900000000000,0.690500000000000,0.690500000000000,0.633900000000000,0.807600000000000,0.952400000000000,0.739200000000000,0.520500000000000,0.659600000000000]

    m = gp.Model("model1")

    a1 = m.addVars(10,20,vtype=GRB.BINARY)
    a0 = m.addVars(10,20,vtype=GRB.BINARY)
    a3 = m.addVars(39,20,vtype=GRB.BINARY)
    a2 = m.addVars(46,20,vtype=GRB.BINARY)
    so = m.addVars(1,20,vtype=GRB.CONTINUOUS)
    w = m.addVars(46,20,vtype=GRB.CONTINUOUS,name='free_V')#lb=-1,ub=1,


    m.addConstr(a0[0,0]==1)#name=a0+str(1_1)
    m.addConstrs(a0[i,j]>=a0[i,j-1] for i in set4 for j in range(1,20))
    m.addConstrs(a1[i,j]>=a1[i,j-1] for i in set4 for j in range(1,20))
    m.addConstrs(a0[i,j]<=a3[index[i],j] for i in set4 for j in set2)
    m.addConstrs(so[0,j]>=0 for j in set2)
    m.addConstrs(so[0,j]<=1 for j in set2)

    for i in set3:

    fi = ac.select('*',i)
    fi = [ac.index(i) for i in fi]
    fo = ac.select(i,'*')
    fo = [ac.index(i) for i in fo]

    if i in set5:
    gen_index = set5.index(i)
    if gen_index == 0:
    if fi == [] and fo != []:
    m.addConstrs((gp.quicksum(-w[a, j] for a in fo) + so[0, j] == 0.01 * a3[i, j]) for j in set2)
    elif fi != [] and fo == []:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) + so[0, j] == 0.01 * a3[i, j]) for j in set2)
    else:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) - gp.quicksum(w[a, j] for a in fo) + so[0, j] == 0.01 * a3[i, j]) for t in set2)
    else:
    if fi==[] and fo!=[]:
    m.addConstrs((gp.quicksum(-w[a, j] for a in fo) == 0.01 * a3[i,j]) for j in set2)
    elif fi!=[] and fo==[]:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) == 0.01 * a3[i, j]) for j in set2)
    else:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) - gp.quicksum(w[a, j] for a in fo) == 0.01 * a3[i, j]) for j in set2)
    else:
    if fi == [] and fo != []:
    m.addConstrs((gp.quicksum(-w[a, j] for a in fo) == 0.01 * a3[i, j]) for j in set2)
    elif fi != [] and fo == []:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) == 0.01 * a3[i, j]) for j in set2)
    else:
    m.addConstrs((gp.quicksum(w[a, j] for a in fi) - gp.quicksum(w[a, j] for a in fo) == 0.01 * a3[i, j]) for j in set2)

    m.addConstrs(a3[i,j]>=a3[i,j-1] for i in set3 for j in range(1,20))
    m.addConstrs(a2[i,j]<=a3[bu1[i],j] for i in set1 for j in set2)
    m.addConstrs(a2[i,j]<=a3[bu2[i],j] for i in set1 for j in set2)
    m.addConstrs(a2[i,j]<=a3[bu1[i],j-1]+a3[bu2[i],j-1] for i in set1 for j in range(1,20))
    m.addConstrs(a2[i,j]>=a2[i,j-1] for i in set1 for j in range(1,20))
    m.addConstrs(-a2[i,j]<=w[i,j] for i in set1 for j in set2)
    m.addConstrs(w[i,j]<=a2[i,j] for i in set1 for j in set2)
    m.addConstrs(gp.quicksum((1-a1[i,j]) for j in set2)>=gp.quicksum((1-a0[i,j]) for j in set2)+CW[i] for i in set4)

    obj = gp.LinExpr(0)
    for i in CU:
    for j in set2:
    obj.add(a3[i,j],-100*data1[CU.index(i)])

    m.setObjective(obj, GRB.MINIMIZE)
    m.optimize()
    m.computeIIS()
    m.write('D:\model.ilp')

    I have produces the reduced codes. Finally, the some variables named 'free_V' seems to be free in the .ilp files.

    \ Model model1_copy
    \ LP format - for model browsing. Use MPS format to capture full model detail.
    Minimize

    Subject To
    R46: - C247 + C248 >= 0
    R47: - C248 + C249 >= 0
    R48: - C249 + C250 >= 0
    R49: - C250 + C251 >= 0
    R50: - C251 + C252 >= 0
    R421: C240 - C1020 <= 0
    R424: C243 - C1023 <= 0
    R433: C252 - C1032 <= 0
    R434: C253 - C1033 <= 0
    R435: C254 - C1034 <= 0
    R436: C255 - C1035 <= 0
    R437: C256 - C1036 <= 0
    R438: C257 - C1037 <= 0
    R439: C258 - C1038 <= 0
    R440: C259 - C1039 <= 0
    R806: - 0.01 C585 - free_V[17,5] - free_V[18,5] - free_V[19,5] = 0
    R814: - 0.01 C593 - free_V[17,13] - free_V[18,13] - free_V[19,13] = 0
    R815: - 0.01 C594 - free_V[17,14] - free_V[18,14] - free_V[19,14] = 0
    R820: - 0.01 C599 - free_V[17,19] - free_V[18,19] - free_V[19,19] = 0
    R1246: - 0.01 C1025 + free_V[19,5] = 0
    R1254: - 0.01 C1033 + free_V[19,13] = 0
    R1255: - 0.01 C1034 + free_V[19,14] = 0
    R1260: - 0.01 C1039 + free_V[19,19] = 0
    R1990: - C1020 + C1021 >= 0
    R1991: - C1021 + C1022 >= 0
    R1992: - C1022 + C1023 >= 0
    R1993: - C1023 + C1024 >= 0
    R1994: - C1024 + C1025 >= 0
    R2002: - C1032 + C1033 >= 0
    R2005: - C1035 + C1036 >= 0
    R2006: - C1036 + C1037 >= 0
    R2007: - C1037 + C1038 >= 0
    R2008: - C1038 + C1039 >= 0
    R7572: - C40 - C41 - C42 - C43 - C44 - C45 - C46 - C47 - C48 - C49 - C50
    - C51 - C52 - C53 - C54 - C55 - C56 - C57 - C58 - C59 + C240 + C241
    + C242 + C243 + C244 + C245 + C246 + C247 + C248 + C249 + C250 + C251
    + C252 + C253 + C254 + C255 + C256 + C257 + C258 + C259 >= 6
    Bounds
    free_V[19,5] free
    free_V[19,13] free
    free_V[19,14] free
    free_V[19,19] free
    Binaries
    C40 C41 C42 C43 C44 C45 C46 C47 C48 C49 C50 C51 C52 C53 C54 C55 C56 C57
    C58 C59 C240 C241 C242 C243 C244 C245 C246 C247 C248 C249 C250 C251 C252
    C253 C254 C255 C256 C257 C258 C259 C585 C593 C594 C599 C1020 C1021 C1022
    C1023 C1024 C1025 C1032 C1033 C1034 C1035 C1036 C1037 C1038 C1039
    End
    0
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Oh, you are computing an IIS after infeasibility is shown. Then, with

    m.write('D:\model.ilp')

    you are writing out the IIS, not the original model. Note that the file ending ILP does not mean "integer linear program", it refers to writing the IIS in LP-format. If you want to write the original model, you could use

    m.write('D:\model.lp')

    immediately before calling optimize(). Please check if the bounds are correct in that file.

    But the fact that the IIS does not include the bounds is definitely strange. Especially, since the output of the script says

    IIS computed: 34 constraints, 8 bounds

    But there are only 34 constraints and no bounds in the file. I will investigate this further and come back to you as soon as I know more.

    0
  • yansong bai
    Gurobi-versary
    Conversationalist
    Curious

    Ok, thank you Mario.

    0
  • Mario Ruthmair
    Gurobi Staff Gurobi Staff

    Ok, the explanation is in fact easier that I thought.

    The ILP file containing the IIS for your infeasible model is correct. The output says that 34 constraints and 8 bounds are needed to define the IIS. In total, there are 12 different "free_V" variables included in the IIS, and all of them had 0 as default lower bound in the original model. But in the IIS only 8 of the 12 lower bounds are needed, 4 variables can be free and still the model is infeasible. The residual 8 variables are not mentioned in the "Bounds" section, just because again the default lower bound of 0 applies.

    0
  • mcc
    Gurobi-versary
    First Comment

    Hello, I think you can try to check whether the data and model constraints are correct. It is better to add names to variables and constraints, so that you can see the changes of variables more intuitively after you export the file.

    0

Post is closed for comments.