Skip to main content

Model.AddConstrs does not work?

Answered

Comments

7 comments

  • Official comment
    Simranjit Kaur
    • 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?.
  • Jaromił Najman
    • Gurobi Staff

    Hi Vy,

    I am not sure how you print your \(\texttt{sol}\) array but the solution of the model you posted does not violate any constraints. You can print the variables participating in each of the \(\leq 1\) constraints via

    if status == GRB.OPTIMAL:
    print('The optimal objective is %g' % model.objVal)
    vx = model.getAttr('x', x)
    sol = np.zeros((len(Workers), len(Shifts)))
    counter = 0
    for v in x:
    print("%s: %f"%(x[v].VarName,x[v].X))
    counter+=1
    if counter == 5:
    print("\n")
    counter = 0

    and you can see that all variable groups add up to at most \(1\).

    Best regards,
    Jaromił

    0
  • Vy Luu
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił, 

    Thank you very much for your response. I may have misunderstood the example code. Is this true?

    x.sum('*', s) = x[0_T,s] + x[1_T,s] + x[2_T,s] + x[3_T,s] + x[4_T,s]

    So the constraint:

    model.addConstrs((x.sum('*', s) <= ShiftRequirements[s] for s in Shifts), name='shiftRequirement')

    is equivalent to the below set of constraints (This is the constraints I actually want)

    x[0_T,0_S] + x[1_T,0_S] + x[2_T,0_S] + x[3_T,0_S] + x[4_T,0_S] < 1 
    x[0_T,1_S] + x[1_T,1_S] + x[2_T,1_S] + x[3_T,1_S] + x[4_T,1_S] < 1
    ...
    x[0_T,14_S] + x[1_T,14_S] + x[2_T,14_S] + x[3_T,14_S] + x[4_T,14_S] < 1

    This is what I got from running your code:

    Solved in 0 iterations and 0.00 seconds
    Optimal objective  1.938000000e+03
    The optimal objective is 1938

    x[0_T,0_S]: 1.000000
    x[1_T,0_S]: 1.000000
    x[2_T,0_S]: 1.000000
    x[3_T,0_S]: 0.000000
    x[4_T,0_S]: 1.000000

    x[0_T,1_S]: 1.000000
    x[1_T,1_S]: 1.000000
    x[2_T,1_S]: 1.000000
    x[3_T,1_S]: 1.000000
    x[4_T,1_S]: 1.000000

    x[0_T,2_S]: 1.000000
    x[1_T,2_S]: 1.000000
    x[2_T,2_S]: 1.000000
    x[3_T,2_S]: 1.000000
    x[4_T,2_S]: 1.000000

    x[0_T,3_S]: 0.000000
    x[1_T,3_S]: 1.000000
    x[2_T,3_S]: 1.000000
    x[3_T,3_S]: 1.000000
    x[4_T,3_S]: 1.000000

    x[0_T,4_S]: 0.000000
    x[1_T,4_S]: 1.000000
    x[2_T,4_S]: 1.000000
    x[3_T,4_S]: 0.000000
    x[4_T,4_S]: 0.000000

    x[0_T,5_S]: 1.000000
    x[1_T,5_S]: 1.000000
    x[2_T,5_S]: 1.000000
    x[3_T,5_S]: 1.000000
    x[4_T,5_S]: 1.000000

    x[0_T,6_S]: 1.000000
    x[1_T,6_S]: 0.000000
    x[2_T,6_S]: 1.000000
    x[3_T,6_S]: 0.000000
    x[4_T,6_S]: 1.000000


    ...

    Optimization was stopped with status 2
    Freeing default Gurobi environment

    The sum for each s = 0_S, ..., 14_S, for example,

    x[0_T,0_S] + x[1_T,0_S] + x[2_T,0_S] + x[3_T,0_S] + x[4_T,0_S] = 5

    is not less than 1 though. 

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Vy,

    Interesting, I have copy-pasted and execute the code you posted. This is the output I get when I execute your code

    Optimize a model with 19 rows, 70 columns and 140 nonzeros
    Model fingerprint: 0xd161aaf7
    Coefficient statistics:
    Matrix range [1e+00, 1e+00]
    Objective range [5e+00, 1e+02]
    Bounds range [1e+00, 1e+00]
    RHS range [1e+00, 2e+00]
    Presolve time: 0.00s
    Presolved: 19 rows, 70 columns, 140 nonzeros

    Iteration Objective Primal Inf. Dual Inf. Time
    0 1.2260000e+03 3.000000e+00 0.000000e+00 0s
    5 1.1880000e+03 0.000000e+00 0.000000e+00 0s

    Solved in 5 iterations and 0.00 seconds
    Optimal objective 1.188000000e+03
    The optimal objective is 1188

    Could you please check wether the \(\texttt{assignment.lp}\) file you write in your code contains the inequality constraints?

    Best regards,
    Jaromił

    0
  • Vy Luu
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił, 

    My apology, the code I ran to get my above output is a bit different from the code I posted above: I took out some code which modified the matrix A because I thought it was unimportant. I ran code I posted above and get the right result, i.e. all constraints are obeyed. And actually it's the removed code that causes the <=1 constraint fails and I'm still not sure why. This is the code which modified A and make the <=1 constraint fails (everything else is the same):

    # create a random observation_cond_mat
    observation_cond_mat = np.ceil(np.random.rand(n_target, n_time_interval) * 100)
    observation_cond_mat -= 20.
    observation_cond_mat = observation_cond_mat.clip(0) # replace negative with 0
    observation_cond_mat[:, 10] = np.zeros(n_target) # add a col of all zeros.

    # remove cols with all zero values and keep track of the indices. 
    unobservable_time_indice = np.where(~observation_cond_mat.any(axis=0))[0]
    observation_cond_mat = np.delete(observation_cond_mat, unobservable_time_indice, axis=1)

    # remove corresponding zero cols from Shift array
    Shifts = np.delete(Shifts, unobservable_time_indice)

    A = observation_cond_mat
    #np.ceil(np.random.rand(n_worker, n_time_interval) * 100)

    When this code is included, the assignment.lp does have the failed constraint (shiftRequirement) but in a form I don't understand (different from the constraint which works- workRequirement)

    Subject To
     shiftRequirement[0,_,S]: <= 1
     shiftRequirement[1,_,S]: <= 1
     shiftRequirement[2,_,S]: <= 1
     shiftRequirement[3,_,S]: <= 1
     shiftRequirement[4,_,S]: <= 1
     shiftRequirement[5,_,S]: <= 1
     shiftRequirement[6,_,S]: <= 1
     shiftRequirement[7,_,S]: <= 1
     shiftRequirement[8,_,S]: <= 1
     shiftRequirement[9,_,S]: <= 1
     shiftRequirement[1,1,_,S]: <= 1
     shiftRequirement[1,2,_,S]: <= 1
     shiftRequirement[1,3,_,S]: <= 1

    workerRequirement[0_T]: x[0_T,0_S] + x[0_T,1_S] + x[0_T,2_S] + x[0_T,3_S] + x[0_T,4_S] + x[0_T,5_S] + x[0_T,6_S] + x[0_T,7_S] + x[0_T,8_S] + x[0_T,9_S] + x[0_T,11_S] + x[0_T,12_S] + x[0_T,13_S] >= 2.5
    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Vy,

    The call

    Shifts = np.delete(Shifts, unobservable_time_indice)

    turns the list \(\texttt{Shifts}\) into a numpy ndarray object. In order to keep \(\texttt{Shifts}\)  a list you have to call

    Shifts.remove(Shifts[unobservable_time_indice[0]])

    This should resolve your issue.

    Best regards,
    Jaromił

    0
  • Vy Luu
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił, 

    Thank you so much for your help. This solves the issue. I some how thought an numpy ndarray Shifts was ok. 

    Best,

    Vy 

    0

Post is closed for comments.