Python-82:多零件流水线优化

问题描述

小C、小U、小R是工厂里的三个工人,他们互相协同制作零件。零件的制作包括三种工序:"加工"、"质检"、"收尾",分别由小C、小U、小R负责。每个零件需要多次进行"加工"和"质检"工序,但只需要进行一次"收尾"工序。每次"加工"完成后,需要进行对应的"质检",只有当质检合格后,才可以开始下一次"加工"。当所有的"加工"和"质检"工序完成后,进行一次"收尾"工序,这样零件制作就算完成了。

小C、小U、小R的工作方式原本非常机械化,他们只能按照既定顺序一个工序一个工序地完成一个零件,比如对于一个零件的工序"加工1、质检1、加工2、质检2、收尾",他们会按顺序逐一完成各自的任务。

老板觉得这样太低效了,于是制定了新的加工方式:小C、小U、小R之间不应该互相等待,当他们因工序等待而被阻塞时,可以直接开始新零件的加工。但是每个工序在进行中不能被打断,必须连贯地完成。

例如,有5个零件,每个零件有7道工序,分别耗时如下:

零件一:10, 10, 10, 10, 10, 10, 20
零件二:10, 10, 10, 10, 10, 10, 20
零件三:10, 10, 10, 10, 10, 10, 20
零件四:10, 10, 10, 10, 10, 10, 20
零件五:10, 10, 10, 10, 10, 10, 20

(每一行的7个数字分别表示"加工1","质检1","加工2","质检2","加工3","质检3","收尾"的耗时)

假设零件按照5、4、3、2、1的优先级开始制作,优化后的工序流程中,小C、小U、小R会更加忙碌,避免空闲。

现在给你n个零件及每个零件的工序耗时,问在经过流程优化后,所有零件加工需要花费的总时间是多少?

代码

import heapq

def solution(n: int, parts: list) -> int:

    assert n == len(parts)

    flag = [[0 for _ in range(len(part))] for part in parts]

    b = [part[0] for part in parts]

    sum_jobs = sum(b)

    a = [part[1:] for part in parts]

    for i in range(n):

        flag[i][0] = 1

    time = 0

    m1, m2, m3 = 0, 0, 0

    last1i, last1j = -1, -1

    last2i, last2j = -1, -1

    last3i = -1

    q = []

    heapq.heappush(q, 0)

    while sum_jobs > 0:

        time = heapq.heappop(q)

        while q and q[0] == time:

            heapq.heappop(q)

        if time == m3 and last3i != -1:

            sum_jobs -= 1

        if time == m2 and last2i != -1 and last2j != -1:

            flag[last2i][last2j + 1] = 1

            sum_jobs -= 1

        if time >= m1:

            if time == m1 and last1i != -1 and last1j != -1:

                flag[last1i][last1j + 1] = 1

                sum_jobs -= 1

            # Get suitable m1

            found = False

            for i in range(n):

                for j in range(0, b[i], 2):

                    if flag[i][j] == 1 and j != b[i] - 1:

                        temi, temj = i, j

                        flag[temi][temj] = 0

                        m1 = time + a[temi][temj]

                        last1i, last1j = temi, temj

                        heapq.heappush(q, m1)

                        found = True

                        break

                if found:

                    break

        if time >= m2:

            # Get suitable m2

            found = False

            for i in range(n):

                for j in range(1, b[i], 2):

                    if flag[i][j] == 1:

                        temi, temj = i, j

                        flag[temi][temj] = 0

                        m2 = time + a[temi][temj]

                        last2i, last2j = temi, temj

                        heapq.heappush(q, m2)

                        found = True

                        break

                if found:

                    break

        if time >= m3:

            # Get suitable m3

            for i in range(n):

                if flag[i][b[i] - 1] == 1:

                    temi = i

                    flag[temi][b[temi] - 1] = 0

                    m3 = time + a[temi][b[temi] - 1]

                    last3i = temi

                    heapq.heappush(q, m3)

                    break

    return time

if __name__ == "__main__":

    #  You can add more test cases here

    parts1 = [[7, 10, 10, 10, 10, 10, 10, 20],

              [7, 10, 10, 10, 10, 10, 10, 20],

              [7, 10, 10, 10, 10, 10, 10, 20],

              [7, 10, 10, 10, 10, 10, 10, 20],

              [7, 10, 10, 10, 10, 10, 10, 20]]

    parts2 = [[5, 10, 5, 10, 5, 10],

              [5, 2, 4, 6, 2, 10],

              [3, 10, 2, 5]]

    print(solution(5, parts1) == 200)

    print(solution(3, parts2) == 57)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

完成大叔

你的鼓励是创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值