【问题标题】:How to implement this constraint in Python with Gurobi?如何使用 Gurobi 在 Python 中实现这个约束?
【发布时间】:2017-06-06 08:46:13
【问题描述】:

我在下面给出了一个表达式,我想知道您是否可以帮助我将其形式化为 ILP 约束,以便通过 Gurobi 优化器 (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} ) 在哪里: r[x][y]、c[y,j] 和 p[x,a] 是 3 个二进制变量; U[j] 和 W[j] 是 2 个正整数变量,其中 U[j] + beta = W[j] (beta是一个正常数)

我知道这个约束可以写成合取范式的逻辑蕴涵:x ∧ y → z 我已经尝试过这个解决方案:z≥x+y−1 以及其他几种可能性:( 但是,我在使用 Gurobi 求解器时遇到了错误

我的这个约束的 Python 代码如下:

对于 Y 中的 y:

对于 M 中的 j:

对于 X 中的 x:

对于范围内的a(int(U[j]),int(W[j])):

M1.addConstr(r[x][y] + c[y,j] - 1

我总是在这一行得到错误:for a in range(int(U[j]),int(W[j])):,因为 U[j] 和 W[j] 都被定义为正数整数变量 那么,有人可以帮助我吗? 谢谢:)

最好的问候 哈迪亚

【问题讨论】:

    标签: python-2.7 linear-programming gurobi


    【解决方案1】:

    您不能基于 尚未优化 变量构建约束,例如:

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

    这样的铸造看起来也很危险,而且它完全取决于 gurobipy,如果这在一般情况下是可能的(但在这里没有帮助)。

    您的问题很难阅读,并且没有关于这些限制的动机的信息,但总体思路可能是:

    • 摆脱U[j]W[j]定义的范围
    • 全范围制定您的约束
      • 有一个修改
        • 再引入一个激活变量 a:
        • (x^y)->z 变为:(a^x^y)->z == !a v !x v !y v z
        • 作为线性表达式:(1-a) + (1-x) + (1-y) + z >= 1
    • 现在使用indicator-variables 的概念来制定您的激活变量

    是的,它很乱,因此(而且因为信息稀少)我不会发布完整的解决方案。

    【讨论】:

    • 感谢您的回答。我已经尝试过使用 Big-M 的几种替代方法,但每次都会遇到相同的错误:(
    • 我告诉你问题的根源是什么(第一句话)。你需要做很多改变来制定这个(这不是初学者会喜欢的)。
    【解决方案2】:

    # -*- 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

    请在附件中找到我的详细 ILP 可能会更容易理解我关于约束编号 17 的问题 哪里,

    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 &amp; forall y in Y) : incidence matrix given as input data

    我会给你一个非常简单的例子来理解我的问题如下: 让: X=[X1,X2,X3,X4] Y=[Y1,Y2,Y3] Ry=[(X1,X2,X3), (X2,X4),(X1,X3,X4)] Z=3 alpha=2, beta=4

    目标是找到计算Y1,Y2 &amp; Y3的计算序列,以最小化Delta(总完成时间)

    最佳解决方案是:Y2, Y3, Y1 (or Y2,Y1,Y3)\Delta=17

    ILP Formulation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      相关资源
      最近更新 更多