柔性车间调度问题丨一种贪婪策略的应用:以算例MK02例

车间调度系列文章:

引言

调度问题定义:在一定的约束条件下,把有限的资源在时间上分配给若干个任务,以满足或优化一个或多个性能指标。柔性车间问题的特点就是:每个工序有多机床可选。因此,要想在短时间内更好的分配资源,是很困难的,需要借助计算机来帮我们运算得出答案。

问题描述

柔性车间调度问题可描述为:多个工件在多台机器上加工,工件安排加工时严格按照工序的先后顺序,至少有一道工序有多个可加工机器,在某些优化目标下安排生。柔性车间调度问题的约束条件如下:

  • (1)同一台机器同一时刻只能加工一个工件;

  • (2)同一工件的同一道工序在同一时刻被加工的机器数是一;

  • (3)任意工序开始加工不能中断;

  • (4)各个工件之间不存在的优先级的差别;

  • (5)同一工件的工序之间存在先后约束,不同工件的工序之间不存在先后约束;

  • (6)所有工件在零时刻都可以被加工。

数学模型

1、 符号定义

n工件总数makespan i工件i的完工时间
m机器总数LPz机器z的负载功率
i,h工件号ULPz机器z的空载功率
j,k工序号makespan最大完工时间
z机器号Twork机器总负荷
qi工件i的工序数Eall总能耗
oij工件i的第j道工序Xijz工序oij是否在机器z上加工,为0-1变量,在z上加工为1
Mij工序oij的可选机器Gijhk工序oij和工序ohk的先后顺序,为0-1变量,ij在前为1
Sij工序oij的开工时间M一个大正实数
Cij工序oij的完工时间Tijz工序oij在机器z的加工时间
CTz机器z的结束或者完工时间

2、模型建立

目标函数:

6)

目标是完工时间
约束条件:

1)

式(1)指工序开工后不能中断,式(2)指任意工序在机器上只加工1次,式(3)指任意工序的开工时间不大于完工时间,式(4)指任意工序完工时间不大于最大完工时间,式(5)指了每台机器在同一时刻只能加工一道工序,式(6)指任意工件的上一道工序的完工时间不大于下一道工序的开工时间,式(7)指任意工序的开工、加工、完工时间都非负。

MK02算例:

10 6 3.5
6 6 3 3 4 5 1 3 6 6 2 2 5 3 2 6 5 3 4 6 1 1 5 6 3 3 4 3 2 6 6 5 1 2 6 2 6 3 5 6 3 3 2 2 1 5 4
6 5 6 1 5 6 1 3 2 4 4 2 2 6 3 5 6 1 5 2 2 2 4 3 3 3 3 2 2 1 5 4 6 3 3 4 5 1 3 6 6 2 2 5 3
6 6 1 1 5 6 3 3 4 3 2 6 6 5 6 5 3 4 6 2 4 6 6 3 6 1 2 3 3 2 2 1 5 4 5 3 5 1 4 2 3 6 3 5 2 6 4 1 1 5 2 4 5 5 3 3 6 3 5 6 3 1 4 4 6 3 6 5 3
6 5 3 5 1 4 2 3 6 3 5 2 5 6 1 5 6 1 3 2 4 4 2 1 2 6 6 1 1 5 6 3 3 4 3 2 6 6 5 5 1 4 4 5 2 3 6 3 5 4 6 4 1 1 5 2 4 5 5 3 3 6 3
6 6 5 3 4 6 2 4 6 6 3 6 1 2 5 1 4 4 5 2 3 6 3 5 4 1 4 3 5 6 3 1 4 4 6 3 6 5 3 5 6 1 5 6 1 3 2 4 4 2 2 2 4 3 3
6 5 6 3 1 4 4 6 3 6 5 3 2 6 5 3 4 5 3 5 1 4 2 3 6 3 5 2 6 5 3 4 6 2 4 6 6 3 6 1 2 1 2 6 5 6 1 5 6 1 3 2 4 4 2
5 6 4 1 1 5 2 4 5 5 3 3 6 3 1 5 2 6 5 3 4 6 2 4 6 6 3 6 1 2 6 3 3 4 5 1 3 6 6 2 2 5 3 5 6 3 1 4 4 6 3 6 5 3
6 2 2 4 3 3 5 3 5 1 4 2 3 6 3 5 2 6 5 3 4 6 2 4 6 6 3 6 1 2 5 6 3 1 4 4 6 3 6 5 3 5 1 4 4 5 2 3 6 3 5 4 5 6 1 5 6 1 3 2 4 4 2
5 1 2 6 2 6 5 3 4 5 6 1 5 6 1 3 2 4 4 2 5 1 4 4 5 2 3 6 3 5 4 2 2 4 3 3
6 1 4 3 6 5 3 4 6 2 4 6 6 3 6 1 2 5 6 3 1 4 4 6 3 6 5 3 6 4 1 1 5 2 4 5 5 3 3 6 3 2 6 3 5 6 5 6 1 5 6 1 3 2 4 4 2

第一行的10,6是工件数和机器数。

第二行第一个数字6表示,工件1有6道工序。加粗的6 3 3 4 5 1 3 6 6 2 2 5 3,表示工件1的第一道工序有6个可选机器,在机器3的加工时间是3、机器4加工时间是5、机器1加工时间是3,机器6加工时间是6,机器2加工时间是2,机器5加工时间是3,后面的2 6 5 3 4表示工件1的第二道工序有2个可选机器,分别是6,3,加工时间是5,4,一行就是1个工件的所有工序的可选机器可加工时间,后面的工件以此类推。

本系列算例数据文件可在gitee仓库下载:

https://gitee.com/XZDNF-1618/data.git

算法介绍

贪心算法是一种局部搜索算法,其提出较早,在很多领域都有广泛应用,对于车间调度问题,其大多是与其他算法混合使用。贪心算法的核心是贪婪策略,对于问题的求解,每次贪婪策略下解的选择都是当前最好的选择,其出发点是局部最优,对于一些优化问题,其能取得很好的效果。贪心算法的两个主要性质是贪心选择和最优子结构,贪心选择性质指问题的的局部最优选择能使问题能达到整体最优,最优子结构选择指局部问题的最优解是在整个问题的最优解的组成部分。

贪心算法适合的最优化问题:问题在约束条件下有多个可行解且有最优解的存在,问题含有评价解的优劣目标函数。贪心算法的一般求解步骤如下:

(1)初始化:问题有多个输入选择,初始解集合为空;

(2)目标函数选择:根据题意选择合适的目标函数,并对多个输入选择排序;

(3)输入选择:保证解可行(局部最优)的情况下每次选择一个输入,所有输入选择完成后得到解。

柔性车间问题贪婪思想:

画一个可行调度方案的甘特图:

2)

最晚加工机器是M5,M5首先加工的是工件3的第一道工序,工件3第一道工序加工机器和加工时间数据是6 1 1 5 6 3 3 4 3 2 6 6 5

6个可加工机器,编号1,5,3,4,2,6,时间是1,6,3,3,6,5。当前选择了机器M5,加工时间是6,

贪婪思想:调整工件3的第一道工序的加工机器,使得完工时间变低。

贪婪策略:把最晚完工机器上的工序往其他机器上安排,目的是使完工时间降低。

初始调度方案生成

工序编码:

  • MK02工件的工序情况如下:

work =[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9]

程序里为方便运算,0表示工件1,依次类推。

  • 随机打乱work即得一个可行的工序编码

机器和加工时间编码:

根据工序编码读出对应工序的可加工机器和时间,随机选择可加工机器。

编码生成代码:

def creat_job(self):
    job=self.work.copy()
    np.random.shuffle(job)                  #打乱生成工序编码
    job=np.array(job).reshape(1,len(self.work))
    
    ccount=np.zeros((1,self.job_num),dtype=np.int)
    machine=np.ones((1,job.shape[1]))
    machine_time=np.ones((1,job.shape[1]))    #初始化矩阵
    for i in range(job.shape[1]):
        oper=int(job[0,i])
        highs=self.tom[oper][ccount[0,oper]]
        lows=self.tom[oper][ccount[0,oper]]-self.tdx[oper][ccount[0,oper]]
        n_machine=self.Tmachine[oper,lows:highs]
        n_time=self.Tmachinetime[oper,lows:highs]
        ccount[0,oper]+=1
                                                #随机挑选机器                              
        index=np.random.randint(0,len(n_time),1)
        machine[0,i]=n_machine[index[0]]        #机器编码生成
        machine_time[0,i]=n_time[index[0]]      #加工时间编码生成
    return job,machine,machine_time

贪婪算法设计

贪婪算法一般存在陷入局部最优和因为无限循环导致无法跳出迭代等问题,为避免这些问题,设计算法流程如下:

step1:找到原方案最晚完工时间的加工机器,读取机器的第一个加工工序,改变工序的加工机器,计算完工时间,

step2:如果完工时间小于原方案时间,更新加工机器和加工时间编码,转入step1,如果完工时间不小于原方案时间,不更新编码,转入step3,

step3:读取机器第二个加工工序(每次读取第i个加工工序,i每次加1),改变工序的加工机器,计算完工时间,转入step2

停止条件:当连续读取最晚完工时间机器的加工工序,改变加工机器都无法优化完工时间,贪婪结束。

代码对算法进行了比较完整的注释:

def greedy(machine,machine_time,C_finish,tmax):
    ccount=np.zeros((1,10),dtype=np.int)
    s_index=[]
    m_index=[]
    for i in range(job.shape[1]): #记录当前每道工序的位置
        oper=int(job[0,i])
        s_index.append([oper,ccount[0,oper]])
        m_index.append(i)
        ccount[0,oper]+=1
        
    fit,Ma=C_finish,tmax    #初始完工时间和完工机器
    machine_last=machine[0].tolist()  #加工机器情况转为列表
    signal=0              #控制最晚完工时间机器上遍历工序的位置
    control=0             #控制读取到机器编码的最后一道工序
    memeroy=-1            #控制两次循环是否遍历到相同位置
    while (control<1)and(Ma in machine_last[signal:]):  #当不是机器编码的最后一道工序,且最晚完工机器还存在未遍历到的工序
        sig=machine_last[signal:].index(Ma)  
        svg=m_index[signal:][sig]    #每次遍历到最晚完工机器的加工工序位置

        swg1,swg2=s_index[svg][0],s_index[svg][1]   #根据位置找到加工工件和第几道工序
        
        highs=tom[swg1][swg2]
        lows=tom[swg1][swg2]-tdx[swg1][swg2]
        n_machine=Tmachine[swg1,lows:highs].tolist()
        n_time=Tmachinetime[swg1,lows:highs].tolist()  #找到工序对应的可加工机器和时间

        num=-1
        if len(n_machine)>1 :                  #如果可加工机器数大于1
            if memeroy==svg :                  #如果遍历到和上一次相同位置,下一次遍历从当前位置的下一个开始
                signal=svg+1
            if memeroy!=svg :
                for ma in n_machine :       
                    num+=1
                    if ma!=Ma:                #选择对应工序和原方案不同的加工机器
                        x,y=machine[0,svg],machine_time[0,svg]
                        machine[0,svg]=n_machine[num]
                        machine_time[0,svg]=n_time[num]
                        C_finish,_,_,_,tmax=fj.caculate(job,machine,machine_time)
                        if C_finish>=fit :     #如果完工时间没有变小,不更新编码,遍历位置也加1
                            machine[0,svg]=x
                            machine_time[0,svg]=y
                            signal=svg+1
                        if C_finish<fit :      #如果完工时间变小,更新编码,下一次从0开始遍历
                            fit=C_finish
                            Ma=tmax
                            memeroy=svg        #记录位置
                            signal=0

        if len(n_machine)==1:              #如果可加工机器数是1,下一次遍历从当前位置的下一个开始
            signal=svg+1    

        if signal>len(machine_last) :      #如果遍历到遍历最后一个位置,控制量变为1
            control=1   
    return machine,machine_time

代码运行环境
windows系统,python3.6.0,第三方库及版本号如下:

numpy==1.18.5
matplotlib==3.2.1

第三方库需要在安装完python之后,额外安装,以前文章有讲述过安装第三方库的解决办法。

主函数

设计主函数如下:

da=data_deal(10,6)                              #数据模块
Tmachine,Tmachinetime,tdx,work,tom=da.cacu()    #数据
parm_data=[Tmachine,Tmachinetime,tdx,work,tom]
fj=FJSP(10,6,parm_data)                         #柔性解码模块

for i in range(1):                             #生成多个编码并进行贪婪优化,可任意调整
    job,machine,machine_time=fj.creat_job()    #随机生成初始调度方案

    C_finish,_,_,_,tmax=fj.caculate(job,machine,machine_time)  #计算完工时间和最晚完工机器
    t1=C_finish
    print(C_finish)                         
    fj.draw(job,machine,machine_time)         #优化前画图,不需要可以屏蔽

    machine,machine_time=greedy(machine,machine_time,C_finish,tmax)   #贪婪优化


    C_finish,_,_,_,tmax=fj.caculate(job,machine,machine_time)     #优化后计算完工时间和最晚完工机器
    print(C_finish)
    fj.draw(job,machine,machine_time)          #优化后画图,不需要可以屏蔽

运行结果

展示一次优化结果:

原调度方案:

贪婪算法\3)

贪婪优化后调度方案:

贪婪算法\4)

随机生成100个编码不画图的优化结果:

贪婪算法\5)

结论

就贪婪策略来说,调整最晚完工机器的加工任务,难以确定能否得到最优结果,但无疑能很快降低完工时间。就本文这种贪婪策略来说,很可能对相同工序的加工机器进行重复调整,也可能更新到某个编码后,无法再进行优化,进入死循环,必须设置迭代结束条件。所以迭代结束了,并不是说明方案已经优化到最好,只能当前贪婪策略无法优化了。

就车间调度这一类组合优化问题来说,贪婪算法的这种由局部最优到全局最优的算法并一定行得通,但其算法优化效率,运行时间这些都是很优秀的,与其他算法搭配无疑会有很好的效果。

本文的贪心算法总的来说只是对工序的加工机器进行优化,如果后续想做这方面研究,可以对工序安排进行优化,或者对贪婪逻辑进行优化。

代码

有3个代码和mk01,mk02的2个text文档,可以任意切换文档进行算法测试:

7
演示视频:

柔性车间调度问题丨一种贪婪策略的应用:以算例MK02例

知识博主创作不易,完整代码,可见微信公众号:学长带你飞,搜索XZDNF-1618,关注后回复:车间调度,查看相关超链接即可。

# 微信公众号:学长带你飞
# 主要更新方向:1、车辆路径问题和车间调度问题求解算法
#              2、学术写作技巧
#              3、读书感悟
# @Author  : Jack Hao

公众号二维码:
在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 柔性作业车间调度问题是指在具有某些约束条件的车间中,如何合理地安排设备的使用,使得所有作业能够在规定的时间内完成,同时尽量减少生产成本。 MK一种常用于求解此类调度问题的解法。其基本思路是将车间中的作业划分为若干个阶段,并按照优先级进行排序。然后,按照一定的规则分配设备,并利用各种约束条件进行求解,可以得到最优的调度方案。 对于柔性作业车间调度问题,需要考虑的约束条件包括设备工作时间,设备切换时间,作业加工时间和作业之间的交错关系等。在进行算法求解时,需要根据这些约束条件进行有效地编码和解码,以实现快速而有效的求解。 总之,柔性作业车间调度问题是一项复杂而重要的生产调度任务,MK一种常用的求解算法。在实践中,需要综合考虑各种约束条件,灵活运用调度策略和技巧,以提高生产效率和降低生产成本。 ### 回答2: 柔性作业车间调度是现代工业生产中非常重要的一环,它可以有效地提高生产效率、降低成本,并且能够适应生产需求的变化,实现生产的最优化。MK柔性作业车间调度中一个常用的算法MK一种基于遗传算法的作业车间调度算法。它主要分为两个步骤:首先通过遗传算法的方式对作业序列进行优化,然后再根据优化后的作业序列进行车间调度。在优化作业序列时,MK主要考虑每个作业任务的加工时间、加工设备、工件存储区域等因素,通过遗传算法的方式对作业任务进行排列组合,得到最佳的作业序列。在车间调度时,MK通过生成作业开始时间的方法,确定每个作业的开工时间、加工时间和完成时间等。同时,MK还可以进行异常情况的处理,如设备故障、工艺异常等情况的处理。 MK通过遗传算法的方式对车间调度进行优化,可以有效地降低生产成本、提高生产效率,同时还可以适应不同生产环境的需求。在实际应用中,MK已经被广泛地应用于工业生产的各个方面,并且在大量的案中得到了验证和应用。 ### 回答3: 柔性作业车间调度是指在生产过程中,根据客户需求和生产情况,灵活调整车间生产计划,以达到最佳的生产效益和客户满意度。而mk则是一个常用的调度算法,也被广泛应用于生产制造中。 在柔性作业车间调度mk中,需要考虑以下几个方面: 首先是任务的分配和调度车间内有多种不同类型的设备,每个设备可以完成不同的任务。在任务分配中需要考虑到设备的类型特性,同时将任务按照其完成时间、优先级等因素进行评估,然后进行优先级调度和任务分配。 其次是设备调度车间内的设备都是有限的资源,需要对其进行合理的调度。在设备调度中需要考虑它们的特性,如加工能力、维修需要等。通过对设备负载的监控和分析,实现对设备的动态调度。 再次是车间作业调度。在车间作业调度中需要考虑的是车间内多个任务之间的相互影响。通过调整车间生产计划来防止任务之间的冲突,实现车间内各项任务的协调与统一。 最后是数据的收集和分析。在柔性作业车间调度mk中,需要对生产过程中的各类数据进行收集和分析,以帮助生产管理人员做出更加准确的决策。通过对数据的分析,可以及时发现生产问题,并进行及时的处理。同时也为车间内生产计划的优化提供了有力的支持。 综上所述,柔性作业车间调度mk一种基于计算机算法的生产管理方式,它能够有效地帮助企业提高生产效益和降低生产成本。同时也能够提高车间生产计划的灵活性和符合度,为企业的高效发展提供有力支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值