メインコンテンツへスキップ

Adding constraints only if a certain condition is verified

回答済み

コメント

5件のコメント

  • 正式なコメント
    Simranjit Kaur
    • Gurobi Staff
    This post is more than two 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 try Gurobot, our chatbot interface offering instant, expert-level support.
  • Simranjit Kaur
    • Gurobi Staff

    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,
    Simran

    0
  • Maria Laura Santoni
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Simran,

    This is my current code:

    from gurobipy import Model, GRB, quicksum
    import 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 modello
    model = Model()

    # Crea le variabili binarie
    num_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 punti
    min_dist = 3  # Specifica il valore minimo di distanza
    dist_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 variabili
    model.addConstr(var.sum() == 5, "sum_constraint")
    # Crea la funzione obiettivo utilizzando le distanze
    # Definisci la funzione obiettivo
    objective = quicksum(var[i] * weights[i] for i in range(num_var))
    model.setObjective(objective, GRB.MINIMIZE)

    # Ottimizza il modello
    model.optimize()

    # Stampa i risultati
    if 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 file
        with 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 'flo
    0
  • Michel Soares
    • Gurobi-versary
    • Thought Leader

    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
  • Simranjit Kaur
    • Gurobi Staff

    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,
    Simran

    0

投稿コメントは受け付けていません。