Skip to main content

How to change constraints to make model feasible/bounded

Answered

Comments

5 comments

  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Hi Natalie,

    You force some variables to be one but simultaneously create infeasible constraints.

    zMoveLimitLower[0,0,0]: 1.486237670110135 x[0,0,0] >= 0
    zMoveLimitLower[0,1,0]: 1.486237670110135 x[0,1,0] >= 1

    x[0,1,0] have to be one here (then x[0,0,0] is 0 because of assignOne). While this constraint

    zMoveLimitLower[3,1,0]: 0.6610736466481952 x[0,1,3] >= 1

    cannot be feasible for x binary.

    If I understand correctly, you want to forbid that the object is picked if the object's coordinate does not fit to the work area of the robot arm.
    So why not set these variables explicitly to 0?

    Best regards,
    Marika

    0
  • Natalie Pueyo
    Gurobi-versary
    Conversationalist
    First Question

    Hi Marika,

    When you mention these variables, which ones do you mean? The x[k,l,i] variable when the i-th object falls outside the k,l-th arm's work area? If so, how would I do this? I just tried using an indicator constraint:

    m.addConstrs((((x[k, l, i] == 0) >> (Z[i] >= z_row_bot_edges[l])) for i in N for l in L for k in K), name="zMoveLimitLower")

    but I ended up getting a Type error:

    TypeError: unsupported operand type(s) for -=: 'NoneType' and 'float'

    Is it because a binary value cannot be == 0?

    What would be the correct way to set the variables equal to zero to that I can forbid an arm from picking an object outside of it's work are?

    Thank you so much!

    Natalie

    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Hi Natalie,

    you do not need constraints. You can change the bounds of your variables, ie., x[k,l,i].UB= 0 for the respective cases.

    Maybe a look at the Gurobi examples also helps do get further ideas. 

    Best regards,
    Marika

    0
  • Natalie Pueyo
    Gurobi-versary
    Conversationalist
    First Question

    That's a really neat way to do it! Would I use an if-else statement to set the respective cases, something like:

    if Z[i] > top_edge[l]:
      x[k,l,i].UB= 0

    Since it depends on the l, i, and k to determine if the bound would change?

    Another way I got to work is to use a conditional within a constraint. I followed your advice to explicitly set x[k,l,i] to zero and got:

    m.addConstrs(((x[k, l, i] == 0) for i in N for l in L for k in K if Z[i] < z_row_bot_edges[l] or Z[i] > z_row_top_edges[l]), name="verticalWorkArea")

    which seems to be working.

    Thank you so much for your help!

    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Yes, you can use for loops and if statements to set the variables

    for i in N:
    for l in L:
    for k in K:
    if Z[i] > top_edge[l]:
    x[k,l,i].UB = 0

    It is also possible to add the constraints you propose. Gurobi then will detect that these are actually bound changes on the variables.

    I do not know your exact problem but maybe you find a way to create fewer variables from the beginning instead of setting them to 0 later? 
    As far as I understand your constraints, an item with Z coordinate between 0 and 1 can only be picked up if the robot arm is at row position 0  and an item with Z coordinate between 1 and 2 can only be picked up if the robot arm is at row position 1. So you could create only for those cases variables and then your assignOne constraints are also not needed. 
    But that is only an idea to maybe find a more compact formulation.
    If you find a formulation that works, that's also fine.

    0

Please sign in to leave a comment.