45、动态规划-排产问题

import random as rd
from pyscipopt import Model, quicksum

def sorting(L1, L2, time_limit):

    n = len(L1)
    model = Model("Plan_sorting")

    #A[i][j] = 1代表第i个任务排在第j个, E1[i]-S1[i]代表第i个执行的任务所用时间
    A = [[model.addVar(vtype="B", name="A[%s,%s]" % (i, j)) for j in range(n)] for i in range(n)]
    S1 = [model.addVar(vtype="I", name="S1[%s]" % (i)) for i in range(n)]
    E1 = [model.addVar(vtype="I", name="E1[%s]" % (i)) for i in range(n)]
    S2 = [model.addVar(vtype="I", name="S2[%s]" % (i)) for i in range(n)]
    E2 = [model.addVar(vtype="I", name="E2[%s]" % (i)) for i in range(n)]

    # 以总成本最小为目标
    model.setObjective(E2[n-1], "minimize")

    #确定每个任务在第几个
    for i in range(n):
        model.addCons(quicksum(A[i][j] for j in range(n)) == 1)
        model.addCons(quicksum(A[j][i] for j in range(n)) == 1)

    # 确定每个任务延续的时间
    for i in range(n):
        model.addCons(E1[i] - S1[i] - quicksum(L1[j] * A[j][i] for j in range(n)) == 0)
        model.addCons(E2[i] - S2[i] - quicksum(L2[j] * A[j][i] for j in range(n)) == 0)

    # 开始时间为0
    model.addCons(S1[0] == 0)

    # 每个任务执行完1才会开始2,每个任务必须在上个任务结束后才开始
    for i in range(n):
        model.addCons(S2[i] - E1[i] >= 0)
    for i in range(n-1):
        model.addCons(S1[i + 1] - E1[i] == 0)
        model.addCons(S2[i + 1] - E2[i] >= 0)

    # 设置求解时间
    model.setRealParam("limits/time", time_limit)
    model.optimize()
    print("\ngap:", model.getGap())

    # 拿结果
    S1 = [round(model.getVal(S1[i])) for i in range(n)]
    E1 = [round(model.getVal(E1[i])) for i in range(n)]
    S2 = [round(model.getVal(S2[i])) for i in range(n)]
    E2 = [round(model.getVal(E2[i])) for i in range(n)]

    A1 = [[round(model.getVal(A[i][j])) for j in range(n)] for i in range(n)]
    r = ""
    for j in range(n):
        for i in range(n):
            if A1[i][j] == 1:
                r += str(i+1)
                if j < n-1:
                    r += "-"
                break

    return S1, E1, S2, E2, r


if __name__ == "__main__":

    #任务数
    n = 6

    #时间生成
    L1 = [int(rd.random() * 10) + 1 for i in range(n)]
    L2 = [int(rd.random() * 10) + 1 for i in range(n)]
    # L1 = [3,10,5,2,9,11]
    # L2 = [8,12,9,6,5,2]
    print("\nL1:\n", L1)
    print("\nL2:\n", L2)

    S1, E1, S2, E2, r = sorting(L1, L2, 100)
    print("\nS1:\n", S1)
    print("\nE1:\n", E1)
    print("\nS2:\n", S2)
    print("\nE2:\n", E2)
    print("\nr:\n", r)

 

你可能感兴趣的:(45、动态规划-排产问题)