(MATLAB代码分享,可运行)基于改进遗传算法的柔性作业车间调度优化研究

问题描述

柔性加工车间,一个工件的单个工序的加工机床可以由多台机床完成,一个机床可以加工多种工件。

多目标优化的时候,加权系数暂定a=1,b=1;
a+b=1,a=0.6或0.7或,0.8
单目标的时候
a=0,b=1;(只考虑能耗最小,不在乎时间的长短。)
a=1,b=0; (只考虑加工时间最短,不在乎加工能耗多少)

变量定义与注解

(定值,取值范围确定的,可由案例中看到具体的,工件种类,每种工件的加工工序即加工步骤,每个工件的单个加工工序可由多台候选中的1台来完成,机床的空载与待机功率确定不变。工件的单步加工能耗,加工时间,对刀时间,空闲等待时间的不同,具体取值受限于可选用的机床不同而不同)

i , j , m i,j,m i,j,m 分别表示工件种类序号,工件工序序号,机床序号,是中间过程值。 I , J , M I,J,M I,J,M表示所有的工件,工序机床的所有集合。i定值,取值范围确定,m定值,取值范围确定,j的取值范围受限于i的变化
n i {{n}_{i}} ni 表示工件 i i i的加工个数的序号 中间过程值,取值范围受限于 N i {{N}_{i}} Ni
N i {{N}_{i}} Ni 表示工件 i i i的加工总量,定值,取值范围受限于i的变化
n i j i j {{n}_{ij}}ij nijij 中间值, N i j i j {{N}_{ij}}ij Nijij 定值,受限于i
N i m {{N}_{im}} Nim 机床 M m {{M}_{m}} Mm上被加工的第i种工件加工总量
O i j {{O}_{ij}} Oij 工件i的工序的第j道加工工序,可由符合条件的多台机床完成。定值受限于i,j的变化。
N m {{N}_{m}} Nm 表示机床m可执行的所有工件的所有工序总集合{ O i j {{O}_{ij}} Oij} ,定值,受限于i,j,m
M i j {{M}_{ij}} Mij 工件工序 o i j {{o}_{ij}} oij可选的机器集合,定值,受限于i,j,

t c i j m {{t}^{c}}_{ijm} tcijm 是机床m单个工序 O i j {{O}_{ij}} Oij的总加工时间,定值,取值范围受限于i,j,m的个体差异,
T c i j m {{T}^{c}}_{ijm} Tcijm 工件工序 o i j {{o}_{ij}} oij在机床 M m {{M}_{m}} Mm上整体加工时间. 受限于 t c i j m {{t}^{c}}_{ijm} tcijm与数量的差异
E i j m {{E}_{ijm}} Eijm 工件工序 o i j {{o}_{ij}} oij在机床 M m {{M}_{m}} Mm上加工阶段能耗,定值,取值范围受限于i,j,m的差异,
E c m {{E}^{c}}_{m} Ecm 机床 M m {{M}_{m}} Mm所有工件的阶段总能耗, 受限于 E i j m {{E}_{ijm}} Eijm与数量的限制
t u i j m {{t}^{u}}_{ijm} tuijm 单个工件的单个工序 o i j {{o}_{ij}} oij在机床 M m {{M}_{m}} Mm上加工之前需要对刀时间,定值,取值范围受限于i,j,m
T u i j m {{T}^{u}}_{ijm} Tuijm 所有工件工序 o i j {{o}_{ij}} oij在机床 M m {{M}_{m}} Mm上加工之前需要对刀时间,受限于 t u i j m {{t}^{u}}_{ijm} tuijm
与数量
P m u P_{m}^{\text{u}} Pmu机床 M m {{M}_{m}} Mm的空载功率 定值,取值范围受限于m的取值范围
E w m {{E}^{w}}_{m} Ewm机床 M m {{M}_{m}} Mm的空载能耗 定值,取值范围受限于m的变化
P m w P_{m}^{w} Pmw机床 M m {{M}_{m}} Mm的待机功率 定值,取值范围受限于m的取值范围
T w i j m {{T}^{w}}_{ijm} Twijm 单个工件单工序 o i j {{o}_{ij}} oij在机床 M m {{M}_{m}} Mm上的空闲待机时间,受限于开始装夹时刻,结束拆家时刻,加工时间,与对刀时间。
E w m {{E}^{w}}_{m} Ewm机床 M m {{M}_{m}} Mm的待机能耗, 受限于待机功率与待机时间。
S T m k S_{{{T}_{m}}}^{k} STmk 在机床 M m {{M}_{m}} Mm加工第k件工件的开始装夹时刻
C T m k C_{{{T}_{m}}}^{k} CTmk在机床 M m {{M}_{m}} Mm加工第k件工件的结束拆夹时刻
g m k g_{m}^{k} gmk 在机床 M m {{M}_{m}} Mm加工第k件工序之前需要对刀•

C i j m k C_{ijm}^{k} Cijmk 用来判断 在机床 M m {{M}_{m}} Mm上加工的工件工序j是否是工件i的工序 O i j {{O}_{ij}} Oij M i j ∈ { O i j } {{M}_{ij}}\in \{{{O}_{ij}}\} Mij{Oij}
x i j m {{x}_{ijm}} xijm 用来判断 N m {{N}_{m}} Nm表示机床m可执行的所有工件的所有工序总集合{ O i j {{O}_{ij}} Oij} O i j ∈ N m = { O i j } {{O}_{ij}}\in {{N}_{m}}=\{{{O}_{ij}}\} OijNm={Oij}
y i j m h m k ∈ { 0 , 1 } {{y}_{ijm}}h_{m}^{k}\in \left\{ 0,1 \right\} yijmhmk{0,1} 中间变量
g m k g_{m}^{k} gmk 用来判断,是否需要换刀,受限于中间变量 y i j m h m k {{y}_{ijm}}h_{m}^{k} yijmhmk

x i j m , g m k , G i j m k ∈ { 0 , 1 } {{x}_{ijm}},g_{m}^{k},G_{ijm}^{k}\in \left\{ \left. 0,1 \right\} \right. xijm,gmk,Gijmk{0,1}
在这里插入图片描述

调度过程中的机床能耗由工序加工能耗 、对刀能耗 、机床空闲等待能耗三部分构成。

柔性车削加工车间分批调度总能耗 E 是车间机床消耗电能之和,计算公式如下
E = ∑ m = 1 M E m = ∑ m = 1 M ( E m c + E m t + E m i ) E=\sum\limits_{m=1}^{M}{{{E}_{m}}}=\sum\limits_{m=1}^{M}{(E_{m}^{c}}+E_{m}^{t}+E_{m}^{i}) E=m=1MEm=m=1M(Emc+Emt+Emi) (1)
总完工时间 T C = max ⁡ ∀ m   C T m K m {{T}_{C}}=\underset{\forall m}{\mathop{\max }}\,C_{{{T}_{m}}}^{{{K}_{m}}} TC=mmaxCTmKm m ∈ [ 1 , M ] m\in [1,M] m[1,M] (2)

单台机床能耗与时间具体分析如下

工序加工阶段

加工能耗:在第m台机床上加工第i种工件的第j到工序。
E m c = ∑ i = 1 I ∑ j = 1 L i ∑ n i = 1 N i n i j × E i j m × x i j m E_{m}^{c}=\sum\limits_{i=1}^{I}{\sum\limits_{j=1}^{{{L}_{i}}}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{{{n}_{ij}}\times {{E}_{ijm}}}}}\times {{x}_{ijm}} Emc=i=1Ij=1Lini=1Ninij×Eijm×xijm (3)
注意: x i j m = 1 , i f , O i j ∈ N m {x}_{ijm}=1 ,if , {O}_{ij} \in {N}_{m} xijm=1,if,OijNm

是给定值。 N i j {{N}_{ij}} Nij为给定值
单位加工时间 t c i j m {{t}^{c}}_{ijm} tcijm 为给定值
总加工时间 T i j m c = ∑ i = 1 I ∑ j = 1 L i ∑ n i N i n i j × t c i j m × x i j m T_{ijm}^{c}=\sum\limits_{i=1}^{I}{\sum\limits_{j=1}^{{{L}_{i}}}{\sum\limits_{{{n}_{i}}}^{{{N}_{i}}}{{{n}_{ij}}\times {{t}^{c}}_{ijm}}}}\times {{x}_{ijm}} Tijmc=i=1Ij=1LiniNinij×tcijm×xijm (4)

对刀阶段

能耗。此此时刻机床处于空载状态,运用空载功率与空载时间。
E m u = P m u ( ∑ i I ∑ j L i G i j m k × x i j m × g m k × t u i j m ) E_{m}^{u}=P_{m}^{u}\left( \sum\limits_{i}^{I}{\sum\limits_{j}^{{{L}_{i}}}{G_{ijm}^{k}\times {{x}_{ijm}}\times }}g_{m}^{k}\times {{t}^{\text{u}}}_{ijm} \right) Emu=Pmu(iIjLiGijmk×xijm×gmk×tuijm) (5)

注意: t i j m u t_{ijm}^{u} tijmu 为给定值。
在这里插入图片描述
当机床 M m {{M}_{m}} Mm上加工,由于同一种工件毛坯料尺寸的相似性,当工件的代加工工序属于机床m的加工序列集合即 O i j ∈ N m {{O}_{ij}}\in {{N}_{m}} OijNm,并且是该批工件的第1个工件即$$ n i = 1 {{n}_{i}}=1 ni=1,两个条件都满足的时候,机床才会产生对刀能耗。其余条件下,本机床不会产生这种能耗
对刀时间总时间
T i j m u = ∑ i = 1 I ∑ j = 1 L i x i j m × g m k × t i j m u T_{ijm}^{u}=\sum\limits_{i=1}^{I}{\sum\limits_{j=1}^{{{L}_{i}}}{{{x}_{ijm}}\times g_{m}^{k}}}\times t_{ijm}^{u} Tijmu=i=1Ij=1Lixijm×gmk×tijmu (6)

机床空闲等待阶段(此时机床属于待机状态。具体能耗值为待机功率与待机时间)

机床空闲等待时间为
T i j m w = C T m N i − S T m 1 − T i j m c − T i j m u T_{ijm}^{w}=C_{{{T}_{m}}}^{{{N}_{i}}}-S_{{{T}_{m}}}^{1}-T_{ijm}^{c}-T_{ijm}^{u} Tijmw=CTmNiSTm1TijmcTijmu (7)

因此机床空闲等待能耗的计算公式为
E m w = p m s t × T i j m w E_{m}^{w}=p_{m}^{st}\times T_{ijm}^{w} Emw=pmst×Tijmw (8)

约束条件

(1)机床的加工必须满足前一个工件加工完成后,下一个工件方可开始加工。
C T m n i   ≤ S T m n i + 1 C_{{{T}_{m}}}^{{{n}_{\text{i}}}\text{ }}\le S_{{{T}_{m}}}^{{{n}_{i}}+1} CTmni STmni+1 n i ∈ [ 1 , N i ] {{n}_{i}}\in \left[ 1,{{N}_{i}} \right] ni[1,Ni] m ∈ [ 1 , M ] m\in \left[ 1,M \right] m[1,M]
(2)同一个工件的加工必须满足前一道工序加工完成后,下一道才能开始加工。
∑ m = 1 M ∑ i = 1 I ∑ n i = 1 N i ( C T m n i x i j m ) ≤ ∑ m = 1 M ∑ i = 1 I ∑ n i = 1 N i ( S T m n i x i ( j + 1 ) m ) \sum\limits_{m=1}^{M}{\sum\limits_{i=1}^{I}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{\left( C_{{{T}_{m}}}^{{{n}_{i}}}{{x}_{ijm}} \right)\le }}}\sum\limits_{m=1}^{M}{\sum\limits_{i=1}^{I}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{{}}\left( S_{{{T}_{m}}}^{{{n}_{i}}}{{x}_{i(j+1)m}} \right)}} m=1Mi=1Ini=1Ni(CTmnixijm)m=1Mi=1Ini=1Ni(STmnixi(j+1)m) m ∈ [ 1 , M ] m\in \left[ 1,M \right] m[1,M] i ∈ [ 1 , I ] i\in \left[ 1,I \right] i[1,I] n i ∈ [ 1 , N i ] {{n}_{i}}\in \left[ 1,{{N}_{i}} \right] ni[1,Ni] j ∈ [ 1 , L i ] j\in [1,{{L}_{i}}] j[1,Li]
(3) 同一台机床同一时刻只能加工一种工件的一道工序。
∑ i = 1 I ∑ j = 1 L i G i j m k = 1 \sum\limits_{i=1}^{I}{\sum\limits_{j=1}^{{{L}_{i}}}{G_{ijm}^{k}=1}} i=1Ij=1LiGijmk=1 i ∈ [ 1 , I ] i\in [1,I] i[1,I] j ∈ [ 1 , L i ] j\in \left[ 1,{{L}_{i}} \right] j[1,Li] m ∈ [ 1 , M ] m\in \left[ 1,M \right] m[1,M] k ∈ [ 1 , N i m ] k\in [1,{{N}_{im}}] k[1,Nim]
(4)批量的工件的任意工序一旦开始加工,中途不能被打断。
∑ m = 1 M ∑ n i = 1 N i G i j m k = 1 \sum\limits_{m=1}^{M}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{G_{ijm}^{k}=1}} m=1Mni=1NiGijmk=1 i ∈ [ 1 , I ] i\in [1,I] i[1,I] n i ∈ [ 1 , N i ] {{n}_{i}}\in \left[ 1,{{N}_{i}} \right] ni[1,Ni] m ∈ [ 1 , M ] m\in \left[ 1,M \right] m[1,M] k ∈ [ 1 , N i m ] k\in [1,{{N}_{im}}] k[1,Nim]
(5)同一种工件的同种加工工序的工序只能选择一台机床加工。
∑ m = 1 M x i j m = 1 \sum\limits_{m=1}^{M}{{{x}_{ijm}}=1} m=1Mxijm=1 i ∈ [ 1 , I ] i\in [1,I] i[1,I] j ∈ [ 1 , L i ] j\in \left[ 1,{{L}_{i}} \right] j[1,Li] m ∈ [ 1 , M ] m\in \left[ 1,M \right] m[1,M]
(6)工件必须在到达之后才能开始加工。
min ∀ i   ( ∑ m = 1 M ∑ n i = 1 N i ( S T m n i × x i j m × G i j m k ) ) ≥ A i \underset{\forall i}{\mathop{\text{min}}}\,\left( \sum\limits_{m=1}^{M}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{\left( S_{{{T}_{m}}}^{{{n}_{i}}}\times {{x}_{ijm}}\times G_{ijm}^{k} \right)}} \right)\ge {{A}_{i}} imin(m=1Mni=1Ni(STmni×xijm×Gijmk))Ai
(7)工件必须在工件交货期之前完工。
max ∀ i   ( ∑ m = 1 M ∑ n i = 1 N i ( C T m n i × x i j m × G i j m k ) ) ≤ B i \underset{\forall i}{\mathop{\text{max}}}\,\left( \sum\limits_{m=1}^{M}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{\left( C_{{{T}_{m}}}^{{{n}_{i}}}\times {{x}_{ijm}}\times G_{ijm}^{k} \right)}} \right)\le {{B}_{i}} imax(m=1Mni=1Ni(CTmni×xijm×Gijmk))Bi
(8)工件的单工序加工数量之和必须等于该工件的加工批量。
∑ i = 1 I ∑ n i = 1 N i n i j = ∑ i = 1 I N i \sum\limits_{i=1}^{I}{\sum\limits_{{{n}_{i}}=1}^{{{N}_{i}}}{{{n}_{ij}}=\sum\limits_{i=1}^{I}{{{N}_{i}}}}} i=1Ini=1Ninij=i=1INi i ∈ [ 1 , I ] i\in [1,I] i[1,I] n i ∈ [ 1 , N i ] {{n}_{i}}\in \left[ 1,{{N}_{i}} \right] ni[1,Ni]
(9)0-1 变量约束。
x i j m , g m k , G i j m k ∈ { 0 , 1 } {{x}_{ijm}},g_{m}^{k},G_{ijm}^{k}\in \left\{ \left. 0,1 \right\} \right. xijm,gmk,Gijmk{0,1} 中间变量 y i j m h m k ∈ { 0 , 1 } {{y}_{ijm}}h_{m}^{k}\in \left\{ 0,1 \right\} yijmhmk{0,1}

编码方式与数据设置

机床序号m=[1,10]
工件种类序号i=[1,5]
i=1时候, j ∈ L 1 = { 1 , 2 , 3 } j\in {{L}_{1}}=\{1,2,3\} jL1={1,2,3}
I=2 j ∈ L 2 = { 1 , 2 , 34 } j\in {{L}_{2}}=\{1,2,34\} jL2={1,2,34}
i=3, j ∈ L 3 = { 1 , 2 , 3 } j\in {{L}_{3}}=\{1,2,3\} jL3={1,2,3}
i=4, j ∈ L 4 = { 1 , 2 , 34 } j\in {{L}_{4}}=\{1,2,34\} jL4={1,2,34}
i=5 j ∈ L 5 = { 1 , 2 , 34 } j\in {{L}_{5}}=\{1,2,34\} jL5={1,2,34}
双层编码结构。基于工件加工工序编码与对应的工序分配的机床编码。
示例:染色体基因段 (工序排列基因段,选用机床排列段)
工序总集    ⁣ ⁣ {  ⁣ ⁣   O 11 O 12 O 13 O 21 O 22 O 23 O 24 O 31 O 32 O 33 O 41 O 42 O 43 O 44 O 51 O 52 O 53 O 54 } \text{ }\!\!\{\!\!\text{ }{{O}_{11}}{{O}_{12}}{{O}_{13}}{{O}_{21}}{{O}_{22}}{{O}_{23}}{{O}_{24}}{{O}_{31}}{{O}_{32}}{{O}_{33}}{{O}_{41}}{{O}_{42}}{{O}_{43}}{{O}_{44}}{{O}_{51}}{{O}_{52}}{{O}_{53}}{{O}_{54}}\}  { O11O12O13O21O22O23O24O31O32O33O41O42O43O44O51O52O53O54}
工序染色体基因段1 1 1 2 2 2 2 3 3 3 4 4 4 4 5 5 5 5
对应加工工序的选用机床分配染色体基因段1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 注解:每种加工工序的可选机床机床集合中的排位,比如 O 21 {{O}_{21}} O21可选用机床集合{ M 01 M 02 M 03 M 04 {{M}_{01}}{{M}_{02}}{{M}_{03}}{{M}_{04}} M01M02M03M04}, 对应的1就是可选机床集合中的第1台即 M 01 {{M}_{01}} M01

表2机床信息

1.车床

机床 M m {{M}_{m}} Mm机床类别机床型号待机功率/W空载功率/W
M 01 {{M}_{01}} M01数控车床CHK56016262102
M 02 {{M}_{02}} M02数控车床CHK46010721556
M 03 {{M}_{03}} M03数控车床C2-6150K2412836
M 04 {{M}_{04}} M04数控车床C2-6150HK/12841253

2.铣床

M 05 {{M}_{05}} M05数控铣床XK503285961
M 06 {{M}_{06}} M06数控铣床1341048
M 07 {{M}_{07}} M07数控铣床X503285850
  1. 钻床
M 08 {{M}_{08}} M08数控钻床ZXK50421653
M 09 {{M}_{09}} M09数控钻床ZHL765574826

4,磨床

M 10 {{M}_{10}} M10数控磨床—内磨M131W81709
M 10 {{M}_{10}} M10数控磨床—外磨M131W811723

表3工件加工信息表

工件种类 i i i加工数量 N i {{N}_{i}} Ni到达时间 A i {{A}_{i}} Ai/S交货期 D i {{D}_{i}} Di/S
1800600000
21502800600000
31001740600000
41803750600000
5300860600000

表4工件加工能耗/时间信息表

工件种类工序编号工序名称加工机床工序加工能耗工序加工时间对刀时间
I 1 {{I}_{1}} I1 O 11 {{O}_{11}} O11车削 M 03 {{M}_{03}} M03376213258968
M 04 {{M}_{04}} M04335632481578
O 12 {{O}_{12}} O12铣削 M 05 {{M}_{05}} M0518547318581
M 06 {{M}_{06}} M0620895017177
O 13 {{O}_{13}} O13数控钻 M 08 {{M}_{08}} M0848900747578
I 2 {{I}_{2}} I2 O 21 {{O}_{21}} O21车削 M 01 {{M}_{01}} M0144314571532103
M 02 {{M}_{02}} M024387694176864
M 03 {{M}_{03}} M034922201117878
M 04 {{M}_{04}} M044417923150191
O 22 {{O}_{22}} O22铣削 M 05 {{M}_{05}} M0594970826176
M 07 {{M}_{07}} M0798568323487
O 23 {{O}_{23}} O23数控钻 M 08 {{M}_{08}} M0878629747699
M 09 {{M}_{09}} M09972452413114
O 24 {{O}_{24}} O24数控磨-外磨 M 10 {{M}_{10}} M1032660541537
I 3 {{I}_{3}} I3 O 31 {{O}_{31}} O31车削 M 01 {{M}_{01}} M01299218471746
M 02 {{M}_{02}} M02317408792347
M 03 {{M}_{03}} M03304259774553
M 04 {{M}_{04}} M04297538278945
O 32 {{O}_{32}} O32车削 M 01 {{M}_{01}} M0145293711022
M 02 {{M}_{02}} M0244061814617
M 03 {{M}_{03}} M0344623512119
M 04 {{M}_{04}} M0442683713515
O 33 {{O}_{33}} O33 M 06 {{M}_{06}} M06738266739
M 07 {{M}_{07}} M07688195843
I 4 {{I}_{4}} I4 O 41 {{O}_{41}} O41 M 01 {{M}_{01}} M0152376316689
M 02 {{M}_{02}} M0245828319371
M 03 {{M}_{03}} M0350092116669
M 04 {{M}_{04}} M0447381516963
O 42 {{O}_{42}} O42 M 01 {{M}_{01}} M0166101421668
M 02 {{M}_{02}} M0265160128747
M 03 {{M}_{03}} M0365602323053
M 04 {{M}_{04}} M0461431424546
O 43 {{O}_{43}} O43外磨 M 10 {{M}_{10}} M1032660541533
O 44 {{O}_{44}} O44内磨 M 10 {{M}_{10}} M1040111518717
I 5 {{I}_{5}} I5 O 51 {{O}_{51}} O51 M 01 {{M}_{01}} M014431457153249
M 02 {{M}_{02}} M024387694176856
M 03 {{M}_{03}} M034922201117851
O 52 {{O}_{52}} O52 M 05 {{M}_{05}} M05738264343
M 07 {{M}_{07}} M07688195957
O 52 {{O}_{52}} O52 M 09 {{M}_{09}} M0978629747697
O 54 {{O}_{54}} O54外磨 M 10 {{M}_{10}} M1020428816846

改进遗传算法(代码以及参考资料可以私信评论邮箱获取)

在这个问题中涉及到的变量种类较多,较为复杂,这里介绍一种比较新颖的数据传递方式。在matlab中将所有的常量打包放进一个global变量中,在函数调用时,直接申请使用全局变量。这样可以避免函数定义写的非常长非常乱。对开发过程具有较好效果。缺点是,使用全局变量会导致速度变慢。
在这里插入图片描述

优化过程示意图

在这里插入图片描述

结果展示

在这里插入图片描述

// 函数的主程序入口
%% 清空环境
clc
clear
close all

%% 模型参数
load data
global Global info
Global.M = 11;
Global.I = 5;
Global.m_power = M_power;

% Ai=zeros(5,1);
% Ni=ones(5,1);

Global.Ni = Ni;
Global.Ai = Ai;
Global.Di = Di;
% Global.fault = [4 50000]; %第一个是机器编号,第二个是故障时间

Global.Ni(5)=130;
Global.xishu=[0,1];
Global.fun = @(x) fun(x);%改成fun1就是有故障的。
init_data();

nVar = 0;
for i=1:Global.I
    nVar = nVar+info(i).num_gongxu;
end

%% 遗传算法参数
maxgen=300;                         %进化代数
sizepop=50;                       %种群规模
k1=7e+8;                      %交叉概率
k2=4e+8;                  %变异概率

%% 个体初始化
individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]);  %种群结构体
avgfitness=[];                                               %种群平均适应度
bestfitness=[];                                              %种群最佳适应度
bestchrom=[];                                                %适应度最好染色体
% 初始化种群
for i=1:sizepop
    individuals.chrom(i,:)=Code();       %随机产生个体
    x=individuals.chrom(i,:);
    individuals.fitness(i)=Global.fun(x);                     %个体适应度
end

%找最好的染色体
[bestfitness bestindex]=min(individuals.fitness);
bestchrom=individuals.chrom(bestindex,:);  %最好的染色体
avgfitness=sum(individuals.fitness)/sizepop; %染色体的平均适应度
% 记录每一代进化中最好的适应度和平均适应度
trace=[];

%% 进化开始
h = waitbar(0,'正在优化中。。。');
for i=1:maxgen
    waitbar(i/maxgen,h);
    %自适应修改交叉变异概率
    pcross=k1/(avgfitness-bestfitness);                      %交叉概率
    pmutation=k2/(avgfitness-bestfitness);                  %变异概率
    
    % 选择操作
    individuals=Select(individuals,sizepop);
    avgfitness=sum(individuals.fitness)/sizepop;
    % 交叉操作
    individuals.chrom=Cross(pcross,individuals.chrom,sizepop);
    % 变异操作
    individuals.chrom=Mutation(pmutation,individuals.chrom,sizepop);
    
    % 计算适应度
    for j=1:sizepop
        x=individuals.chrom(j,:);
        individuals.fitness(j)=Global.fun(x);
    end
    
    %找到最小和最大适应度的染色体及它们在种群中的位置
    [newbestfitness,newbestindex]=min(individuals.fitness);
    [worestfitness,worestindex]=max(individuals.fitness);
    % 代替上一次进化中最好的染色体
    if bestfitness>newbestfitness
        bestfitness=newbestfitness;
        bestchrom=individuals.chrom(newbestindex,:);
        
        figure(1)
        hold off
        plot(1,1)
        draw
        pause(0.01)
    end
    individuals.chrom(worestindex,:)=bestchrom;
    individuals.fitness(worestindex)=bestfitness;
    
    avgfitness=sum(individuals.fitness)/sizepop;
    trace=[trace;avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度
end
close(h);
%进化结束

%% 结果显示
[r c]=size(trace);
figure
plot([1:r]',trace(:,2),'r-','LineWidth',2);
title(['函数值曲线  ' '终止代数=' num2str(maxgen)],'fontsize',12);
xlabel('进化代数','fontsize',12);ylabel('函数值','fontsize',12);
legend('迭代优化曲线')
disp(['函数值:' num2str(bestfitness)]);
// 这里是计算目标函数值的程序代码
function [y,release_time,T_start,T_need,T_end,T_total,T_jiagong,T_duidao,T_kongxian,P_total,P_jiagong,P_duidao,P_kongxian] = fun(x)
nVar = numel(x);
global Global info

%% 从头到尾安排工件进行加工
T_jiagong = 0;
T_duidao = 0;
T_kongxian = 0;
T_start = zeros(Global.I,4); %开工时间
T_need = zeros(Global.I,4); %加工时间
T_end = zeros(Global.I,4); %完工时间
release_time = zeros(1,Global.M); %下一次的可用时间

P_jiagong = 0;
P_duidao = 0;
P_kongxian = 0;

count_gongxu=ones(1,Global.I);
count_gongjian=zeros(1,Global.M); %记录机器使用次数
for i=1:nVar/2
    cur_gongjian = x(i);
    cur_gongxu = count_gongxu(cur_gongjian);
    count_gongxu(cur_gongjian) = count_gongxu(cur_gongjian)+1;
    cur_machine = x(nVar/2+i);
    cur_machine_code = info(cur_gongjian).gongxu(cur_gongxu).bianhao(cur_machine);
    count_gongjian(cur_machine_code) = count_gongjian(cur_machine_code) + 1;
    
    if cur_gongxu==1 %当前工件的首个工序
        if release_time(cur_machine_code)>Global.Ai(cur_gongjian) %当前几床被占用
            T_start(cur_gongjian,cur_gongxu) = release_time(cur_machine_code);
            T_need(cur_gongjian,cur_gongxu) = Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,2)) ...
                + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3);
            release_time(cur_machine_code) = release_time(cur_machine_code) + T_need(cur_gongjian,cur_gongxu);
        else %当前机床没有被占用
            T_start(cur_gongjian,cur_gongxu) = Global.Ai(cur_gongjian);
            T_need(cur_gongjian,cur_gongxu) = Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,2))  ...
                + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3);
            P_kongxian = P_kongxian + (T_start(cur_gongjian,cur_gongxu)-release_time(cur_machine_code))*Global.m_power(cur_machine,1);
            T_kongxian = T_kongxian+(T_start(cur_gongjian,cur_gongxu)-release_time(cur_machine_code));
            release_time(cur_machine_code) = T_start(cur_gongjian,cur_gongxu) + T_need(cur_gongjian,cur_gongxu);
        end
        T_jiagong = T_jiagong+Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,2));
        T_duidao = T_duidao+Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3));
        P_jiagong = P_jiagong + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,1)*Global.Ni(cur_gongjian);
        P_duidao = P_duidao + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3)* ...
            Global.m_power(cur_machine_code,2)*Global.Ni(cur_gongjian);
        T_end(cur_gongjian,cur_gongxu) = T_start(cur_gongjian,cur_gongxu) + T_need(cur_gongjian,cur_gongxu);
        
    else %不是首个工序
        if release_time(cur_machine_code)>T_end(cur_gongjian,cur_gongxu-1) %当前几床被占用
            T_start(cur_gongjian,cur_gongxu) = release_time(cur_machine_code);
            T_need(cur_gongjian,cur_gongxu) = Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,2)) ...
                + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3);
            release_time(cur_machine_code) = release_time(cur_machine_code) + T_need(cur_gongjian,cur_gongxu);
        else
            T_start(cur_gongjian,cur_gongxu) = T_end(cur_gongjian,cur_gongxu-1);
            T_need(cur_gongjian,cur_gongxu) = Global.Ni(cur_gongjian)*sum(info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,2)) ...
                + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,3);
            P_kongxian = P_kongxian + (T_start(cur_gongjian,cur_gongxu)-release_time(cur_machine_code))*Global.m_power(cur_machine,1);
            T_kongxian = T_kongxian+(T_start(cur_gongjian,cur_gongxu)-release_time(cur_machine_code));
            release_time(cur_machine_code) = T_start(cur_gongjian,cur_gongxu) + T_need(cur_gongjian,cur_gongxu);
        end
        T_jiagong = T_jiagong+T_need(cur_gongjian,cur_gongxu);
        P_jiagong = P_jiagong + info(cur_gongjian).gongxu(cur_gongxu).data(cur_machine,1)*Global.Ni(cur_gongjian);
        T_end(cur_gongjian,cur_gongxu) = T_start(cur_gongjian,cur_gongxu) + T_need(cur_gongjian,cur_gongxu);
    end
end

non_use = Global.M-numel(find(count_gongjian)==0);

T_total = max(release_time);
P_total = P_jiagong + P_duidao + P_kongxian;
xishu = Global.xishu;
y = sum([T_total P_total].*xishu) + non_use*1000000000;

最后,博主专注于论文的复现工作,有兴趣的同学可以私信共同探讨。相关代码已经上传到资源共享,点击我的空间查看分享代码。

  • 15
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 36
    评论
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

运筹不帷幄

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值