Adding constraints only if a certain condition is verified
AnsweredHi everyone,
I am trying to model a problem on Gurobi Python. I have n binary variables and each couple has assigned a fixed number that I load from outside.
A constraint that the problem should have is that if var_i =1 and var_j =1 then dist_ij>= min_dist
where dist_ij is the fixed number (float) that is assigned to the couple with the indexes i and j and min_dist is a fixed number that I decide.
Thanks a lot!
-
Hi Maria,
It seems you are trying to find the minimum of the dist_ij when the fixed number (loaded from outside) assigned to both i and j is 1. In this case, the min_dist calculation can simply be done in Python (no need to define any variables or constraints):
min_dist = min( dist_ij for i in I for j in I if num_i = 1 and num_j = 1)
where num_i is the fixed number assigned to i. Please note here I am assuming that dist_ij is a known fixed value for every pair of i and j.
Best regards,
Simran0 -
Hi Simran,
This is my current code:
from gurobipy import Model, GRB, quicksumimport numpy as np
# Carica i pesi da un file txt (10000 pesi)weights = np.loadtxt('15_0_2_10000_5_-5_5_1000_sample_values.txt', usecols=[0], skiprows=1)
# Carica le distanze da un file txt (10000 righe e 10000 colonne)distances = np.loadtxt('distances.txt')
# Creazione del modellomodel = Model()
# Crea le variabili binarienum_var = len(weights)var = model.addVars(num_var, vtype=GRB.BINARY, name="variable")#distanza_vars = model.addVars([(i, j) for i in range(num_var) for j in range(i + 1, num_var)], vtype=GRB.INTEGER, name="distanza_var")
# Constants# M is chosen to be as small as possible given the bounds on x and y# eps = 0.0001# M = 2 + eps# Crea il vincolo per la distanza tra i puntimin_dist = 3 # Specifica il valore minimo di distanzadist_var = model.addVars(num_var, num_var, vtype=GRB.INTEGER, name='dist_var')for i in range(num_var):for j in range(i + 1, num_var):model.addConstr(dist_var[i,j] == var[i] + var[j])model.addConstr((dist_var[i,j] == 2) >> (distances[i,j]>=min_dist))# Crea il vincolo per la somma delle variabilimodel.addConstr(var.sum() == 5, "sum_constraint")# Crea la funzione obiettivo utilizzando le distanze# Definisci la funzione obiettivoobjective = quicksum(var[i] * weights[i] for i in range(num_var))model.setObjective(objective, GRB.MINIMIZE)
# Ottimizza il modellomodel.optimize()
# Stampa i risultatiif model.status == GRB.OPTIMAL:results= f"Optimal value: {model.objVal}\nOptimal solution: {[var[i].x for i in range(num_var)]}"# Salva i risultati in un filewith open('results_d3_f15.txt', 'w') as file:file.write(results)else:print("The problem does not have a solution.")''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''I am trying to put some constraints: if var_i and var_j are both equal to 1 then d_ij has to be bigger or equal to min_dist. I already know d_ij and min_dist to (It is a threshold that I fix before).with this code, I got the error:raceback (most recent call last): File "/dss/dsshome1/lxc0D/ge89yen2/Gurobi/main3.py", line 29, in <module> model.addConstr((dist_var[i,j] == 2) >> (distances[i,j]>=min_dist)) File "src/gurobipy/model.pxi", line 3591, in gurobipy.Model.addConstr File "src/gurobipy/model.pxi", line 4670, in gurobipy.Model.addGenConstrIndicator TypeError: unsupported operand type(s) for -=: 'NoneType' and 'flo0 -
Hi Maria,
I believe var_i =1 and var_j =1 then dist_ij>= min_dist could be modelled as:
dist_ij >= (var_i * var_j * min_dist)
That would make your model quadratic, but it should yield the desired result. I believe this would be the constraint, and I encourage you to read the documentation for quadratic constraint:
model.addQConstr(dist_var[i,j] >= var[j] * var[j] * min_dist)
0 -
Hi Maria,
Thanks for sharing your code. Since var_i and var_j are decision variables in the model that are not known a priori, the suggestion in my previous comment will not work.
The condition
"If var_i =1 and var_j =1, then dist_ij>= min_dist"
is equivalent to saying
" If dist_ij < min_dist, then at least one of var_i or var_j must be zero".Since distances[i,j] and min_dist are inputs to your model, the above condition can be modelled using linear constraints as follows:
if distances[i,j] < min_dist:
model.addConstr(var[i] +var[j] <= 1)Best regards,
Simran0
Please sign in to leave a comment.
Comments
4 comments