Skip to main content

Soft Constraints being treated as Hard Constraints?

Answered

Comments

20 comments

  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Furthermore, I tried formulating this way:

    i_CA1SH = []

    for ca1sh in CA1SH:

        for i in ca1sh.teams:

            i_CA1SH.append((i,ca1sh))

    di_CA1SH = grb_model.addVars(i_CA1SH)

    for ca1sh in CA1SH:

        for i in ca1sh.teams:

            grb_model.addConstr(minimumg == (k_RR - quicksum(x_ijsg[i,j,s] for s in ca1sh.slots for j in team_ids if i != j)), name="Min")

            grb_model.addConstr(maximumg == (quicksum(x_ijsg[i,j,s] for s in ca1sh.slots for j in team_ids if i != j) - k_RR), name="Max")

            grb_model.addConstr(max_valg == max_([minimumg, maximumg], constant=0), name="max")

            di_CA1SH[i,ca1sh] = max_valg

    constraint_413 = grb_model.addConstrs((quicksum(x[i,j,k] for j in team_ids for k in ca1sh.slots if i != j) - ca1sh.max <= di_CA1SH[i,ca1sh] for ca1sh in CA1SH for i in ca1sh.teams), "Constraint 4.13")

    But I am still getting an infeasible solution.

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    The Knowledge Base article How do I determine why my model is infeasible? should be helpful here.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi. Thanks for this.

    About a particular question I asked in the first post, how can I determine hard and soft constraints?

    Oleg

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    I am no expert on hard/soft constraints but I think that one way to model soft constraints is to add an additional free so-called slack variable (sometimes also called violation variable) which captures the violation of the constraint and add it with a penalty coefficient to the objective function. If in the optimal solution, this additional variable is positive, you know that the soft constraint is violated and you know by how much.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi. Thanks for your reply.

    How would you instantiate such slack variables?

    Thanks
    Oleg

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Oleg,

    You define such variables just as normal optimization variables

    slack = dev_model.addVars(I,J,K,name="slack")

    and then use those in your soft constraints.

    Don't forget to add a penalty for those slack in your objective. In case that you are minimizing, this could be something like \(\texttt{10e3 * slack[i,j,k]}\).

    Best regards, 
    Jaromił

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi.

    How would I assign a slack variable to a constraint?

    Thanks

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    You have to add the slack variable to the constraint, e.g.,

    x[4,0,5] + x[4,1,5] + x[4,2,5] + x[4,3,5] + x[4,5,5] - slack <= 1

    You can see that if the \(\texttt{x}\) variables actually add up to \(>1\), the slack variable can compensate it.

    Depending on the sign of your inequality, you have to either add or subtract a slack variable to catch the violation of the given constraint. For an equality constraint, you will require 2 slack variables and add one and subtract the other.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    So it would be along the lines of this:

    i_CA1SH = []
    for ca1sh in CA1SH:
        for i in ca1sh.teams:
            i_CA1SH.append((i,ca1sh))
    di_CA1SH = grb_model.addVars(i_CA1SH)
    for ca1sh in CA1SH:
        for i in ca1sh.teams:
            grb_model.addConstr(minimumg == (k_RR - quicksum(x_ijsg[i,j,s] for s in ca1sh.slots for j in team_ids if i != j)), name="Min")
            grb_model.addConstr(maximumg == (quicksum(x_ijsg[i,j,s] for s in ca1sh.slots for j in team_ids if i != j) - k_RR), name="Max")
            grb_model.addConstr(max_valg == max_([minimumg, maximumg], constant=0), name="max")
            di_CA1SH[i,ca1sh] = max_valg
    constraint_413 = grb_model.addConstrs((quicksum(x[i,j,k] for j in team_ids for k in ca1sh.slots if i != j) - di_CA1SH[i,ca1sh] <= ca1sh.max for ca1sh in CA1SH for i in ca1sh.teams), "Constraint 4.13")

    di_CA1Sh is the slack variable in this case

    Also, can I assign values as I did here?

     

     

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    This will not work. \(\texttt{di_CA1SH}\) is an optimization variable and you cannot just assign some value to it. It has to be used in a constraint.

    grb_model.addConstr(max_valg + di_CA1SH_plus[i,ca1sh] - di_CA1SH_minus[i,ca1sh] == max_([minimumg, maximumg], constant=0), name="max")

    Note that I used 2  \(\texttt{di_CA1SH}\) variables as slacks, because the above is an equality constraint.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    When doing what you suggested, it is giving me the following error:

    Any ideas?

     

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Right, that one is on me.

    You will have to introduce an additional auxiliary variable because general constraint are limited to exactly one single variable in an equality constraint.

    max_valg_aux = grb_model.addVar() # defined with the same properties as max_valg
    grb_model.addConstr(max_valg_aux == max_([minimumg, maximumg], constant=0), name="max")
    grb_model.addConstr(max_valg + di_CA1SH_plus[i,ca1sh] - di_CA1SH_minus[i,ca1sh] == max_valg_aux, name="max_aux")
    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi again.

    Upon inspection, I noticed that the model is being infeasible because of the following constraints:

    grb_model.addConstr((ca1sh.min - quicksum(x[i,j,s] for s in ca1sh.slots for j in team_ids if i != j)) == minimumg, name="Min")
    grb_model.addConstr((quicksum(x[i,j,s] for s in ca1sh.slots for j in team_ids if i != j) - ca1sh.max) == maximumg, name="Max")

    Somehow they are being added to the final solution while I just want them to be temporary so that I can get a value that I will pass to the max_ function. minimumg and maximumg are not being added to the objective function

    Any ideas?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Oleg,

    How did you define the variables \(\texttt{maximumg, minimumg}\)? You have to make sure that these are free variables.

    maximumg = grb_model.addVar(lb=-GRB.INFINITY, name="maximumg")
    minimumg = grb_model.addVar(lb=-GRB.INFINITY, name="minimumg")

    Best regards, 
    Jaromił

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi after doing what you suggested, it is still giving me the same issue when looking at the ilp file

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    I have added a GitHub link so that you can access the code: https://github.com/oleggrech7/Sports_Scheduling

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    You need a different minimumg, maximumg variable for each constraint. Otherwise, you are forcing all equality constraints holding minimumg or maximumg to the same value. This means that you will have to introduce multiple minimumg and maximumg variables, namely one for each equality constraint of interest.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi.

    Thank you for the suggestion. But I am still getting that the model is infeasible.

    Here is my updated code with another constraint:

    # Constraints 4.13

    max_valCA1SH = grb_model.addVar(lb=-GRB.INFINITY, name="max_valCA1SH")

    minimumCA1SH = grb_model.addVar(lb=-GRB.INFINITY, name="minimumCA1SH")

    maximumCA1SH = grb_model.addVar(lb=-GRB.INFINITY, name="maximumCA1SH")

    i_CA1SH = []

    for ca1sh in CA1SH:

        for i in ca1sh.teams:

            i_CA1SH.append((i,ca1sh))

    di_CA1SH = grb_model.addVars(i_CA1SH)

    for ca1sh in CA1SH:

        for i in ca1sh.teams:

            grb_model.addConstr(minimumCA1SH == (ca1sh.min - quicksum(x[i,j,s] for s in ca1sh.slots for j in team_ids if i != j)), name="Min")

            grb_model.addConstr(maximumCA1SH == (quicksum(x[i,j,s] for s in ca1sh.slots for j in team_ids if i != j) - ca1sh.max), name="Max")

            grb_model.addConstr(max_valCA1SH == max_([minimumCA1SH, maximumCA1SH], constant=0), name="max")

            grb_model.addConstr(di_CA1SH[i,ca1sh] == max_valCA1SH, name="max_aux")

    constraint_413 = grb_model.addConstrs((quicksum(x[i,j,k] for j in team_ids for k in ca1sh.slots if i != j) - ca1sh.max <= di_CA1SH[i,ca1sh] for ca1sh in CA1SH for i in ca1sh.teams), "Constraint 4.13")
    # Constraint 4.14

    max_valCA1SA = grb_model.addVar(lb=-GRB.INFINITY, name="max_valCA1SA")

    minimumCA1SA = grb_model.addVar(lb=-GRB.INFINITY, name="minimumCA1SA")

    maximumCA1SA = grb_model.addVar(lb=-GRB.INFINITY, name="maximumCA1SA")

    i_CA1SA = []

    for ca1sa in CA1SA:

        for i in ca1sa.teams:

            i_CA1SA.append((i,ca1sa))

    di_CA1SA = grb_model.addVars(i_CA1SA)

    for ca1sa in CA1SA:

        for i in ca1sa.teams:

            grb_model.addConstr(minimumCA1SA == (ca1sa.min - quicksum(x[i,j,s] for s in ca1sa.slots for j in team_ids if i != j)), name="Min")

            grb_model.addConstr(maximumCA1SA == (quicksum(x[i,j,s] for s in ca1sa.slots for j in team_ids if i != j) - ca1sa.max), name="Max")

            grb_model.addConstr(max_valCA1SA == max_([minimumCA1SA, maximumCA1SA], constant=0), name="max")

            grb_model.addConstr(di_CA1SA[i,ca1sa] == max_valCA1SA, name="max_aux")

    constraint_414 = grb_model.addConstrs((quicksum(x[j,i,k] for j in team_ids for k in ca1sa.slots if i != j) - ca1sa.max <= di_CA1SA[i,ca1sa] for ca1sa in CA1SA for i in ca1sa.teams), "Constraint 4.14")

    Any idea?

    The code is updated on Git aswell.

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    In the LP file Schedule.lp in your github, you are still using the same maximumCA1SH and minimumCA1SH variable for every equality constraint. As mentioned before, you have to introduce multiple of these variable, namely one for each equality constraint.

    0
  • Oleg Grech
    Gurobi-versary
    Collaborator
    First Question

    Hi.

    Thanks for your help! Worked like a charm. Wish I knew this beforehand.

    0

Please sign in to leave a comment.