使用纸浆进行3D箱包装

时间:2019-01-29 10:21:17

标签: python pulp bin-packing

我正在尝试使用线性编程优化器解决NP难(https://en.wikipedia.org/wiki/Bin_packing_problem)的3D装箱问题。我刚开始使用PuLP,面临一些问题。我已详细添加了我的约束,代码,输出和需要的帮助。

约束:

目标函数是enter image description here,我希望对以下约束进行建模 enter image description here,其中enter image description here

PYTHON代码:

     from pulp import *

        #Variable Decleration
        prob = LpProblem('BinPacking', LpMinimize)

        ps = [LpVariable("p{0}{1}".format(i + 1, j + 1), cat="Binary")
              for i in range(parcel.parcels) for j in range(parcel.containers)]
        print(ps)

        us = [LpVariable("u{0}".format(j + 1), cat="Binary") for j in range(parcel.containers)]
        print(us)
    #location of left bottom (x,y,z)
        xs = [LpVariable("x{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]        

        ys = [LpVariable("y{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]    

        zs = [LpVariable("z{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]

        rs = [LpVariable("r{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]       

        ss = [LpVariable("s{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]   

        ts = [LpVariable("t{0}".format(i+1), cat="Integer") for i in range(parcel.parcels)]

    #for the overlapping constraint
        xik = [LpVariable("xik", cat="Binary")]
        yik = [LpVariable("yik", cat="Binary")]
        zik = [LpVariable("zik", cat="Binary")]
        xki = [LpVariable("xki", cat="Binary")]
        yki = [LpVariable("yki", cat="Binary")]
        zki = [LpVariable("zki", cat="Binary")]

    #orientation
        a = ["1", "2", "3"]
        b = ["1", "2", "3"]
        os = [LpVariable("o{0}{1}".format(j, k), cat="Binary")for j in a for k in b]
    print(os)     


# Objective function

     t = lpSum([us[i] * parcel.conVolume[i] for i in range(parcel.containers)]) - sum(parcel.parVolume)
        prob += t
        print(t)


# Dimension Constraint
     a = []
        for j in range(parcel.parcels):
            b = rs[j] - xs[j]
            a.append(b)
            a[j] = parcel.parLength[j]
        print(a)
        for j in range(parcel.parcels):
            u = ps[j * parcel.containers: (j + 1) * parcel.containers]
            condition1 = sum([u1 * w for u1, w in zip(u, parcel.conLength)])
            #print(rs[j])
            t = rs[j] <= condition1
            prob += t
            print(t)

# Overlapping Constraint
    for i in range(parcel.parcels):
        if rs[i - 1] <= xs[i]:
            xik = 1
            xki = 0
        elif xs[i] < rs[i + 1]:
            xik = 0
            xki = 1
    print(xik, xki)

    for i in range(parcel.parcels):
        # for k in range(parcel.parcels):
        # u = bs[i * parcel.containers: (i + 1) * parcel.containers]
        if ss[i - 1] <= ys[i]:
            yik = 1
            yki = 0
        elif ss[i] < ys[i - 1]:
            yik = 0
            yki = 1
    print(yik, yki)

    for i in range(parcel.parcels):
        # for k in range(parcel.parcels):
        # u = bs[i * parcel.containers: (i + 1) * parcel.containers]
        if ts[i - 1] <= zs[i]:
            zik = 1
            zki = 0
        elif ts[i] < zs[i - 1]:
            zik = 0
            zki = 1
    print(zik, zki)

    li = []
    for j in range(parcel.parcels):
        u = ps[j * parcel.containers: (j + 1) * parcel.containers]
        # print(u)
        li.append(u)
    # print(li)

    r = []
    for i in range(parcel.containers):
        z = [x[i] for x in li]
        r.append(z)

    for i in range(0, len(r)):
        for j in range(0, len(r[i])):
            if (j == len(r[i]) - 1):
                s = r[i][-1] + r[i][0]
            else:
                s = r[i][j] + r[i][j + 1]
            # print(s)
            t = xik + xki + yik + yki + zik + zki >= s - 1
            prob += t
            print(t)

    for i in range(parcel.containers):
        for j in range(parcel.parcels):
            a = rs[j - 1] <= xs[j] + (1 - xik) * parcel.conLength[i]
            b = xs[j] + 1 <= rs[j-1] + (xik * parcel.conLength[i])
            c = ss[j - 1] <= ys[j] + (1 - yik) * parcel.conWidth[i]
            d = ys[j] + 1 <= ss[j-1] + (yik * parcel.conWidth[i])
            e = ts[j - 1] <= zs[j] + (1 - zik) * parcel.conHeight[i]
            f = zs[j] + 1 <= ts[j-1] + (zik * parcel.conHeight[i])

            prob += a, b
            prob += c, d
            prob += e, f
            print(a, b, c, d, e, f)

 #

    Orientation Constraint  

    for i in range(parcel.parcels):
     p = (rs[i] - xs[i]) == ((os[0] * parcel.parLength[i])+(os[1] * parcel.parWidth[i])+(os[2]*parcel.parHeight[i]))
          q = (ss[i] - ys[i]) == ((os[3] * parcel.parLength[i]) + (os[4] * parcel.parWidth[i]) + (os[5] * parcel.parHeight[i]))
                r = (ts[i] - zs[i]) == ((os[6] * parcel.parLength[i])+(os[7] * parcel.parWidth[i])+(os[8]*parcel.parHeight[i]))
                prob += q
                prob += p, r
                print(p)
                print(q)
                print(r)

        # Output
            o11 = 0.0
            o12 = 0.0
            o13 = 0.0
            o21 = 0.0
            o22 = 0.0
            o23 = 0.0
            p11 = 1.0
            p12 = 0.0
            p21 = 1.0
            p22 = 0.0
            p31 = 1.0
            p32 = 0.0
            r1 = 0.0
            r2 = 0.0
            r3 = 0.0
            s1 = 0.0
            s2 = 0.0
            s3 = 0.0
            t1 = 0.0
            t2 = 0.0
            t3 = 0.0
            u1 = 1.0
            u2 = 0.0
            x1 = 0.0
            x2 = 0.0
            x3 = 0.0
            y1 = 0.0
            y2 = 0.0
            y3 = 0.0
            z1 = 0.0
            z2 = 0.0
            z3 = 0.0

问题/帮助:

  1. 所有输出值均为0。我不确定约束定义中是否存在某些问题。有人可以帮忙检查我的代码吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

欢迎您!我尚未检查完整的问题表述,但我认为您的目标函数至少是错误的。我的理解是,目标应该是使用的容器数量:

# Objective - minimise wasted volume = volume of chosen boxes - volume of parcels
    prob += lpSum([us[i] * parcel.conVolume[i] for i in range(parcel.containers)]) - sum(parcel.parVolume)

如果我在输出上方进行更改,则得到的是:

('Status:', 'Optimal')
('Objective value:', 45.0)

The values of the variables : 

('p11', '=', 1.0)
('p12', '=', 0.0)
('p21', '=', 1.0)
('p22', '=', 0.0)
('p31', '=', 1.0)
('p32', '=', 0.0)
('u1', '=', 1.0)
('u2', '=', 0.0)

所以至少现在目标已经开始工作-假设所有约束都设置正确(我没有检查过),似乎仅使用其中一个容器就解决了包装问题。