0

I have an expression given below and i was wondering if you can help me to formalize as an ILP constraint in order to solve by Gurobi optimizer (Python):

forall ( y in Y), forall (j in M), forall (x in X): IF r[x][y] = 1 and c[y,j] = 1 THEN p[x,a] = 1 , forall (a in {U[j],...,W[j] - 1} ) Where: r[x][y], c[y,j] and p[x,a] are 3 binary variables; U[j] and W[j] are 2 positive integer variables, where U[j] + beta = W[j] (beta is a positive constant)

I know that this constraint can be written as a logical implication in conjunctive normal form: x ∧ y → z I have already tried this solution: z≥x+y−1 together with several other possibilities :( But, i had an error with Gurobi solver

My Python code for this constraint is as follows:

for y in Y:

for j in M:

for x in X:

for a in range(int(U[j]),int(W[j])):

M1.addConstr(r[x][y] + c[y,j] - 1 <= p[x,a], 'TileRequirement_%s_%s_%s_%s'%(y,j,x,a))

I always get the error in this line: for a in range(int(U[j]),int(W[j])):, because both U[j] and W[j] are defined as positive integer variables So, can someone help me ? Thanks :)

Best regards Khadija

2 Answers 2

1

You can't build constraints based on yet-to-optimize variables like in:

for a in range(int(U[j]),int(W[j]))  # optimized value unknown @ build-constr-time

Casting like that looks also dangerous and it solely depends on gurobipy, if that's possible in general (but not helping here).

Your question is hard to read and there is no information about the motivation for these constraints, but the general idea could be:

  • get rid of the range defined by U[j] and W[j]
  • formulate your constraint for the full-range
    • with one modification:
      • introduce one more activating-variable a:
      • (x^y)->z becomes: (a^x^y)->z == !a v !x v !y v z
      • as linear expression: (1-a) + (1-x) + (1-y) + z >= 1
  • now use the concept of indicator-variables to formulate your activating-variables

Yes, it's messy and because of this (and because information is sparse) i won't post a full solution.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you for your answer. I have already tried several alternatives using Big-M but i get every time the same error :(
I told you exactly what's the source of the problem (first sentence). You need a lot of changes to formulate this (and it's not something a beginner will like).
0

# -*- coding: utf-8 -*-
#programmer: Khadija HS
#date: June 2017
#name: B-C-MCT PLNE Model (Khadija.HS,2017) <---> BCMCT1.py


"""
Solve the B-C-MCTP (fixed Z & min Delta) sub-pb of 3-PSDPP (K-HS et al.,2016), where:
    X: list of input tiles (tile x)
    Y: list of output tiles (tile y)
    Ry: requirement relation between  X & Y
        <---> is a List of Y list, each sub List define the input tiles required by each y
        <---> rxy: incidence matrix (0-1): Input Tiles/Output Tiles (Configuration of each output tile % input tile)
        <---> Ry is a list of list where Row <--- x & Column <--- y
    alpha: prefetches times (uniform)
    beta: computations times (uniform)
    Delta: the Total completion time (to be determined)
"""

from gurobipy import *
""" Find Yx: set of output tiles y that required the input tile x """
def OuputTileTe(Ry,X):
    Yx=[]
    for x in X:
        Yx.append(OuputTileTex(Ry,x))
    return Yx
""" Find B: List Ts for x """
def OuputTileTex(Ry,x):
    B=[]
    for y in range(len(Ry)):
        if x in Ry[y]:
            B.append(y)
    return B

""" Find N: Max Value of N ( <---> sum(len(Ry),y in Y)) """
def NbPrefetchTile(S):
    N=0        
    for k in range(0,len(S)):
        N += len(S[k])       
    return  N



""" BCMCT1 - Model"""
def BCMCT1(X,Y,Z,Ry,alpha,beta):
    # DET VBLES: M,N,Z1,T,K,L
    M=list(range(len(Y)))                   # List of Computation steps
    nb=NbPrefetchTile(Ry)                   # Number of prefetches (Big Value of N)
    N=range(nb)                             # List of Prefetches steps 
    ListZ=range(Z)                          # List of Buffers
    T=range(alpha*len(X) + beta*len(Y))     # List of Start Date times (Computation+Prefetches)
    K=range(alpha)                          # Interval Time of a prefetch step
    L=range(beta)                           # Interval Time of a compute step
    
    # DET VBLES: A,T1,B,Yx
    A=alpha*nb + beta*len(Y)                # Big Value of Total Completion Time  
    T1=range(A)                             # List of Start Date times (Computation+Prefetches)
    minLen=min([len(elt) for elt in Ry])    #1,alpha+1
    B=alpha*minLen + beta*len(Y)            # Value of LB2
    Yx=OuputTileTe(Ry,X)                    # List of output tile y, for x, x in X
    
    


    # MODEL
    M1=Model("BCMCT1")    


    # CONSTANT VARIABLES
    r=[[0]*len(Y) for i in range(len(X))]
    for x in X:
        for y in Y:
            if x in Ry[Y.index(y)]:
                r[x][y]=1
    

    # DECISION VARIABLES
    c,p,q,U,W,a={},{},{},{},{},{}

    for y in Y:
        for j in M:
            c[y,j]=M1.addVar(vtype=GRB.BINARY,name="c[%s,%s]"%(y,j)) #obj=beta,

    for x in X:
        for t in T:
            p[x,t]=M1.addVar(vtype=GRB.BINARY,name="p[%s,%s]"%(x,t)) #obj=1,

    for x in X:
        for t in T:
            q[x,t]=M1.addVar(vtype=GRB.BINARY,name="q[%s,%s]"%(x,t)) #obj=1,
    
    for j in M:
        U[j]=M1.addVar(vtype='I',name="U_%s"%j)
        W[j]=M1.addVar(obj=1,vtype='I',name="W_%s"%j)

    for j in M:
        a[j]=M1.addVar(vtype=GRB.BINARY,name="a[%s]"%j) 
    

    # MODEL UPDATE
    M1.update()


    # OBJECTIVE
    Obj=W[len(M)-1]   
    M1.setObjective(Obj, GRB.MINIMIZE)


    # CONSTRAINTS     
    """ (1): Computation's Assignement Constraints """
    """ (a) """
    for j in M:
        M1.addConstr(quicksum(c[y,j] for y in Y)==1,'ComputeAssign1_%s'%j)
    """ (b) """
    for y in Y:
        M1.addConstr(quicksum(c[y,j] for j in M)==1,'ComputeAssign2_%s'%y)    

       
    """ (2): Buffer's Constraints """
    for t in T:
        M1.addConstr(quicksum(p[x,t] for x in X) <= Z,'BufferNb_%s'%t)

        
    """ 3): Computation/Prefetch's Constraints """    
    """ (a) """
    for t in T:
        M1.addConstr(quicksum(q[x,t] for x in X) <= 1,'PrefetchTileA_%s'%t)

    """ (b) """
    for x in X:
        for t in T[1:]:
            for k in K:
                M1.addConstr(p[x,t] - p[x,t-1] <= q[x,t-k],'PrefetchTileB_%s_%s_%s'%(x,t,k))

    """ (c) """ 
    for y in Y:
        for j in M:
            for x in X:
                for t in T: 
                    M1.addConstr(3 - r[x][y] - c[y,j] - a[j] + p[x,t] >= 1, 'TileRequirement_%s_%s_%s_%s'%(y,j,x,t)) 
                 
    """ (5): Computation Time's Constraint """
    """ (a) """
    for j in M:
        M1.addConstr(W[j] == U[j] + beta,'ComputeTime1_%s'%j)

    """ (b) """
    for j in M[1:]:
        M1.addConstr(W[j-1] <= U[j],'ComputeTime2_%s'%j)
    

    # SOLUTION
    M1.__data=c,p,q,U,W,a
    return M1

Please find attached my detailed ILP May be, it will be easier to understand my question about constraint number 17 where,

L = range(beta)

K=range(alpha)

\Lambda (Big M)=alpha*Z*Y+beta*Y

r[x][y]= 1 if x in Ry and 0 otherwise (forall x in X & forall y in Y) : incidence matrix given as input data

I will give you an example that is very simple to understand more my problem as follows: let: X=[X1,X2,X3,X4] Y=[Y1,Y2,Y3] Ry=[(X1,X2,X3), (X2,X4),(X1,X3,X4)] Z=3 alpha=2, beta=4

The objective is to find a computation sequence for computing Y1,Y2 & Y3 in order to minimize Delta (total completion time)

An optimal solution is: Y2, Y3, Y1 (or Y2,Y1,Y3) with \Delta=17

ILP Formulation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.