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

Else/If conditions

回答済み

コメント

3件のコメント

  • Simranjit Kaur
    • Gurobi Staff

    Hi Arthur,

    Please have a look at our knowledge base article How do I model conditional statements in Gurobi?

    Best regards,

    Simran

    0
  • Arthur d'Hertog
    • Gurobi-versary
    • First Comment
    • First Question

    Hi,

    Thanks for your respond.

    I'm trying to make a BMF. The goal is therefore to decompose a "test" matrix into two sub-matrices W and H. The goal is to minimize the differences between the test matrix and the matrix obtained by the binary product of W and H. The binary product of two matrices is the classical product of the two matrices or the maximum value of the matrix cannot exceed 1.

    To represent the binary product, I want to use the following condition. If expr_ij > 1, then P[i,j] = 1. Otherwise P[i,j] = 0. I tried to put the conditions as in the link you sent but it does not give me the expected result.Do you have any idea how to model the binary product?

    test =  np.array([[1, 1, 1, 1, 1],
    [0, 1, 1, 1, 1],
    [1, 1, 1, 1, 0],
    [0, 1, 0, 1, 0],
    [1, 1, 1, 1, 0]])

     

    #Choisir quel dataset utilisé : 
    X = test

     


    # Définir la taille de la matrice X et le rang r
    m, n = X.shape
    r = 3

    # Créer le modèle
    model = gp.Model("BMF")
    model.setParam('NonConvex', 2)
    # Créer les variables binaires pour les éléments de W et H
    W = model.addVars(m, r, vtype=gp.GRB.BINARY, name="W")
    H = model.addVars(r, n, vtype=gp.GRB.BINARY, name="H")


    # Ajouter les variables pour les éléments de la matrice produit
    P = model.addVars(m, n, vtype=gp.GRB.BINARY, name="P")

    # Ajouter les variables pour les éléments de la matrice X - WH
    D = model.addVars(m, n, vtype=gp.GRB.INTEGER, name="D")

     

     

    b = model.addVars(m, n,vtype=gp.GRB.BINARY, name="b")

    eps = 0.0001
    M = 10 + eps # smallest possible given bounds on x and y

     

    for i in range(m):
        for j in range(n):
            expr_ij = 0
            for k in range(r):
                expr_ij += W[i,k] * H[k,j]
            #if expr_ij > 1, then b = 1, otherwise b = 0
            model.addConstr(expr_ij >= 1 + eps - M * (1 - b[i,j]), name="bigM_constr1")
            model.addConstr(expr_ij <= 1 + M * b[i,j], name="bigM_constr2")

            
            
            model.addConstr(P[i, j] == b[i,j]) 

            model.addConstr(D[i,j] == X[i,j] - P[i,j]) 

     


    # Ajouter la fonction objectif
    obj_expr = 0
    for i in range(m):
        for j in range(n):
            obj_expr += D[i,j] * D[i,j]
    model.setObjective(obj_expr, gp.GRB.MINIMIZE)

    # Optimiser le modèle
    model.optimize()

    0
  • Simranjit Kaur
    • Gurobi Staff

    Hi Arthur,

    Thanks for providing context to the problem you are solving.

    I understand you want to find two binary matrices, W and H, such that X is the boolean product of W and H. For example, \( W = \begin{bmatrix}1 & 0\\1 & 1\end{bmatrix} \) and \( H = \begin{bmatrix}0 & 1\\1 & 1\end{bmatrix} \) will be a valid decomposition for \( X = \begin{bmatrix}0 & 1\\1 & 1\end{bmatrix} \).

    Instead of adding if/else constraints, you can add the following constraints in your model:

    model.addConstr(  b[i,j] <= gp.quicksum( W[i,k] * H[k,j] for k in range(r) ) )
    model.addConstrs( b[i,j] >= W[i,k] * H[k,j] for k in range(r) )
    If \( \sum_{k} W_{ik} * H_{kj} = 0 \), the first constraint will force b[i,j] to be zero; otherwise the second set of constraints will force b[i,j]  to take a value of 1.
     
    You can set the objective to minimize the sum of the absolute difference between b[i,j] and X[i,j] or to minimize the sum of squares of the difference between b[i,j] and X[i,j].
     
    Best regards,
    Simran 

     

     

    0

サインインしてコメントを残してください。