带多处理器的混合流水车间调度matlab程序
- 格式:wps
- 大小:42.50 KB
- 文档页数:6
如何在Matlab中进行多目标优化问题求解如何在Matlab中进行多目标优化问题求解?多目标优化问题是指存在多个目标函数,且这些目标函数之间相互矛盾或者无法完全同时满足的问题。
在实际应用中,多目标优化问题非常常见,例如在工程设计中寻求最佳平衡点、在金融投资中追求高收益低风险等。
而Matlab作为一种强大的数值计算工具,提供了丰富的优化算法和工具箱,可以帮助我们解决多目标优化问题。
一、多目标优化问题数学建模在解决多目标优化问题之前,首先需要将实际问题转化为数学模型。
假设我们需要优化一个n维的向量x,使得目标函数f(x)同时最小化或最大化。
其中,n为自变量的个数,f(x)可以表示为多个目标函数f1(x)、f2(x)、...、fm(x)的向量形式:f(x) = [f1(x), f2(x), ..., fm(x)]其中,fi(x)(i=1,2,...,m)即为待优化的目标函数。
在多目标优化问题中,一般没有单一的最优解,而是存在一个解集,称为"帕累托前沿(Pareto Frontier)"。
该解集中的每个解被称为"非支配解(Non-Dominated Solution)",即不能被其他解所优化。
因此,多目标优化问题的目标就是找到帕累托前沿中的最佳解。
二、Matlab中的多目标优化算法Matlab提供了多种多目标优化算法和工具箱,包括paretosearch、gamultiobj、NSGA-II等等。
这些算法基于不同的思想和原理,可以根据问题的特点选择合适的算法进行求解。
1. paretosearch算法paretosearch算法采用遗传算法的思想,通过迭代更新种群来寻找非支配解。
该算法适用于求解中小规模的多目标优化问题。
使用paretosearch算法求解多目标优化问题可以按照以下步骤进行:(1)定义目标函数编写目标函数fi(x)(i=1,2,...,m)的代码。
Gurobi多目标问题在Matlab中的解决一、Gurobi简介Gurobi是一款强大的商业数学建模工具,广泛应用于优化领域。
它提供了多种优化算法,能够高效地解决线性规划、整数规划、二次规划等各种优化问题。
在实际工程和科学研究中,经常遇到多目标优化问题,即需要同时优化多个目标函数。
本文将介绍如何使用Gurobi在Matlab中解决多目标优化问题。
二、多目标优化问题的定义在多目标优化问题中,我们需要最小化或最大化多个目标函数,而且这些目标函数之间往往存在相互矛盾的关系。
在生产计划中,一个目标函数可能是最大化产量,另一个目标函数可能是最小化成本。
在实际应用中,我们需要找到一组可行的解,使得所有目标函数都达到一个较好的平衡。
三、Gurobi在Matlab中的调用在Matlab中调用Gurobi需要先安装Gurobi的Matlab接口。
安装完成后,我们可以在Matlab命令窗口中输入命令"gurobi"来验证是否成功安装。
接下来,我们需要在Matlab中编写代码,定义优化问题的目标函数、约束条件和变量类型。
在定义目标函数时,我们需要考虑多个目标函数之间的相关性,以及它们之间的权重关系。
在定义约束条件和变量类型时,我们需要考虑多目标函数之间可能存在的约束条件和变量之间的相互制约关系。
四、多目标优化问题的解决方法Gurobi提供了多种解决多目标优化问题的方法,包括加权法、约束法和Pareto最优解法等。
在加权法中,我们将多个目标函数进行线性组合,并引入权重因子来平衡各个目标函数之间的重要性。
在约束法中,我们将多个目标函数作为多个约束条件,通过逐步添加约束条件来找到最优解。
在Pareto最优解法中,我们寻找一组可行解,使得没有其他可行解能比它在所有目标函数上都更好。
五、案例分析以生产计划为例,假设我们需要同时考虑最大化产量和最小化成本两个目标。
我们可以先使用加权法,通过调整权重因子来平衡这两个目标的重要性,找到一个较好的解。
车间调度算法是指为了优化车间生产调度而设计的算法。
下面介绍几种常见的车间调度算法:先来先服务(First-Come, First-Served,FCFS)算法:
工作按照到达顺序排队执行,先到先服务。
缺点是没有考虑工作的执行时间和紧急程度,可能导致长作业时间和低效率。
最短作业优先(Shortest Job Next,SJN)算法:
按照工作的执行时间进行排序,选择执行时间最短的工作优先执行。
可以最大程度地减少平均等待时间和周转时间,但可能导致长作业等待时间过长。
最高优先级优先(Highest Priority First,HPF)算法:
给每个工作分配一个优先级,优先级高的工作优先执行。
可以根据工作的紧急程度进行调度,但可能导致低优先级工作长时间等待。
轮转法(Round Robin,RR)算法:
将时间划分为时间片,每个工作在一个时间片内执行一定的时间,然后切换到下一个工作。
公平地分配处理器时间,避免长作业占用时间过长,但可能导致响应时间较长。
最早截止时间优先(Earliest Deadline First,EDF)算法:
按照工作的截止时间进行排序,选择最早截止时间的工作优先执行。
可以确保紧急工作及时完成,但需要准确估计截止时间。
启发式算法:
基于经验和启发规则进行调度决策,如遗传算法、模拟退火算法等。
可以根据具体问题的特点和需求进行调度,但可能不保证获得最优解。
不同的车间调度算法适用于不同的生产环境和问题需求。
选择适合的算法需要考虑生产特点、工作性质、优先级和调度目标等因素,并综合考虑平均等待时间、周转时间、资源利用率、紧急程度等指标。
如何使用Matlab进行多目标优化使用Matlab进行多目标优化概述:多目标优化是在现实问题中常见的一种优化方法,即需要优化多个目标函数,而非只有一个目标函数。
这篇文章将介绍如何使用Matlab进行多目标优化,包括问题建模、求解方法和实例分析。
1. 问题建模在进行多目标优化之前,需要将实际问题建模为数学模型。
首先,明确问题的决策变量和目标函数。
决策变量是需要优化的参数或变量,而目标函数是需要最小化或最大化的指标。
例如,我们要优化一个生产系统的成本和产量,可以将成本设为一个目标函数,产量设为另一个目标函数。
2. 目标权重设定由于多目标优化存在矛盾或折衷的情况,需要设定目标函数的权重。
权重反映了各个目标函数的重要性,较高的权重意味着对应的目标更重要。
例如,在上述生产系统的例子中,如果成本比产量更重要,可以给成本赋予较高的权重。
3. 多目标优化求解方法Matlab提供了多种多目标优化求解方法,常用的有基于进化算法的优化方法,例如遗传算法、粒子群优化算法等。
这些方法通过不断迭代搜索解空间,逐步找到最优解。
以下是使用Matlab进行多目标优化的一般步骤:a) 定义优化问题的问题函数,包括目标函数和约束条件。
b) 设定优化问题的求解选项,例如优化算法、迭代次数和收敛准则等。
c) 运行优化求解器,获得最优解或近似最优解。
d) 对求解结果进行分析和评价。
4. 多目标优化实例分析为了更好地理解如何使用Matlab进行多目标优化,我们以一个简单的例子进行分析。
假设有一个三维空间内的旅行商问题,即找到一条路径,使得旅行距离最短、花费最少以及时间最短。
我们可以将问题建模为一个三目标优化问题:目标一:最小化旅行距离。
目标二:最小化旅行花费。
目标三:最小化旅行时间。
通过定义目标函数和约束条件,我们可以使用Matlab的多目标优化求解器,如gamultiobj函数,来获得近似最优解。
在求解过程中,可以通过设置收敛准则、种群大小等选项来调节求解参数。
Matlab多线程计算及多核⼼计算应⽤说明关于Matlab多线程计算和多核⼼计算1.关于多线程计算Matlab是基于单线程单核⼼的⼀款软件,在近⼏年多核⼼,多线程处理器⼤规模部署后,其程序设计师才逐步改善matlab内核,让某些常⽤函数逐步⽀持多线程运算。
在matlab6.5-matlab 2007b这些版本中,fft, fft2, fftn, ifft, ifft2, ifftn是默认⽀持多线程运算的,即只要调⽤这些函数,系统在运算时会开启多线程(计算机硬件须⽀持)在matlab 2008a-matlab 2009a这些版本中,增加了prod, sum, max, min这⼏个函数的多线程运算功能,但是matlab内核版本不同会导致这些函数在多线程执⾏时效率不同。
按照其官⽅⽂档的说法,在⽀持多线程计算的matlab版本中,同样的fft运算可以提速50%。
但是多线程运算有⼀个缺点:在函数体或程序内部需要调⽤其他⾮多线程运算的函数时,执⾏效率会⽐较低,基本和不开启多线程运算差不多,也就是说,使⽤这些⽀持多线程的函数时,最好不要进⾏嵌套。
结论:matlab中多线程计算受限于版本以及特定的函数,在运算指定函数时效率较⾼,建议拥有多核⼼处理器的机器开启。
开启多线程⽅法:在命令⾏下输⼊:maxNumCompThreads(),括号内为需要开启的线程个数2.关于多核⼼计算(并⾏计算和分布式计算)2.1并⾏计算功能(Parallel Computing Toolbox)Parallel Computing Toolbox是matlab 2008 a开始拥有的新功能,之前的版本仅拥有Distributed Computing Toolbox。
并⾏计算⼯具箱⾥⾯包含了parfor,spmd,pmode,下⾯⼀⼀介绍(这些功能在分布式计算的应⽤暂不涉及)2.1.1 Parfor这个是matlab提供的并⾏计算的for循环,需要matlab pool的⽀持。
基于遗传算法的流水车间调度问题中文摘要流水车间调度问题是研究多个工件在若干个机器上的加工次序的问题,有效的调度算法对企业提高生产效率有着重要作用。
本文使用遗传算法求解流水车间调度问题,把一个染色体编码成若干个自然数,表示相应工件的排序权值;通过简单交换两个父代的若干相同位置的基因,产生能够继承父代优良特性的子代;并且采用均匀变异,更好地保持种群中的基因的多样性。
实验表明,该方法能取得较好的效果。
关键字:遗传算法,流水车间调度方法,实数编码,基因链码,群体,适应度。
外文摘要Abstract: Flow-shop scheduling problem study the problem the processing sequence of A plurality of workpieces on some working machine,and it makes good effects on proving production efficiency to the industries with effective methods.In the case,we deal with flow-shop scheduling problem using a algorithm,the Genetic Algorithm.There is a chromosome we've just coded into some natural numbers to represent the weight order of these workpieces; exchanging simply two fathers' places of some gene to produce new children that carried good feature on two fathers;we also use the Uniform Mutation,and it keeps its diversity of gene on the population.This experiment show this method can achieve good results.Key Words: Genetic Algorithm, Flow-shop scheduling problem,natural number coding,genic bar code,group,fitness.目录中文摘要 (1)外文摘要 (2)目录 (3)1 引言 (4)1.1 论文的发展背景及重要性 (4)1.1.1 时代背景 (4)1.1.2 论文研究的重要性 (4)1.2 论文的研究问题及解决方法 (4)2 FSP问题描述 (5)2.1 排序问题的基本概念 (5)2.1.1 名词术语 (5)2.1.2 条件假设 (5)2.2车间作业排序问题的特点 (6)2.3 车间作业排序问题 (6)2.3.1 目标函数 (6)2.3.2 车间调度问题的分类 (7)3 遗传算法理论 (7)3.1 遗传算法的产生和发展 (7)3.2 遗传算法的基本思想 (8)3.2.1 基本概念 (8)3.2.2 遗传算法的基本思想 (9)4 基于遗传算法的流水车间调度方法 (11) 4.1 问题的提出 (11)4.2 遗传算法基本步骤 (11)4.2.1 编码 (11)4.2.2 初始群体生成 (12)4.2.3 适应度计算 (12)4.2.4 选择 (14)4.2.5 交叉 (15)4.2.6 变异 (17)4.2.7 终止 (19)5. 研究成果 (20)5.1 算法求解与分析 (20)5.2 实验结果 (21)参考文献 (22)附录 (23)1 引言1.1 论文的发展背景及重要性1.1.1 时代背景从第一次工业革命起,由于科技的进步人类社会就开始了一个经济腾飞的大时代。
CDS启发式算法及Matlab程序--Campbell H,Dudek R, Simth M. A heuristic algorithm for the n-job m-machinesequencing problem.用于求解n-job,m-machine的流水作业调度问题;即n项作业都需要顺序进行m个工序,m个工序中,每道工序仅有一台机器,如何安排n项作业的加工先后关系。
CDS(Campbell-Dudek-Simth):是Johnson算法的扩展,被认为是好的具有鲁棒性的启发式算法;算法步骤:1、将m台机器分组,产生m-1个两台机器问题的集合;2、然后利用Johnson算法获得m-1个加工顺序(每个两台机器问题获得一个加工顺序);3、选取这m-1个加工顺序中考核指标最好(一般为Makespan最短)的加工顺序作为近似最优调度解;分组及每组组合加工时间示意表示例:现在有四项作业需要在6台机器上加工,时间数据如下(n行m列),试使用CDS方法获取最优调度,即最短加工时间Makespan。
2 2 12 12 10 739 7 17 6 2 54 3 16 19 2 3010 8 4 4 5 4CDS法求解结果如下:Makespan =106Schedule =3 1 2 43 1 2 43 1 2 43 1 2 4可以看出,分组后的5(m-1)组两机器问题中,通过Johnson法获取的最优调度中,有4组获得了最优调度: 3 1 2 4也验证了CDS法具有较高的Matlab程序--CDS.mfunction [Makespan,Schedule]=CDS(PT)[n,m]=size(PT);if n<=1error('The job qty must large than 2')endPT=double(PT);%Create new 2-stage-machine timeNewPT(1:n,1:2,1:m-1)=0.0;for i=1:m-1for j=1:iNewPT(:,1,i)=NewPT(:,1,i)+PT(:,j);NewPT(:,2,i)=NewPT(:,2,i)+PT(:,m-j+1);endend%Calculate the m-1 group 2-machine problem using Johnson Rulefor i=1:m-1[MidMakespan(i),MidSchedule(i,:)]=Johnson(NewPT(:,:,i)');end%Calculate the Makespan of the m-1 MidSchedulefor i=1:m-1StartTime(1:m,1:n)=0;StartTime(1,MidSchedule(i,1))=0;for j=2:nStartTime(1,MidSchedule(i,j))=StartTime(1,MidSchedule(i,j-1))+PT(MidSchedule(i,j-1),1);endfor k=2:mStartTime(k,MidSchedule(i,1))=StartTime(k-1,MidSchedule(i,1))+PT(MidSchedule(i,1),k-1);for j=2:nStartTime(k,MidSchedule(i,j))=max(StartTime(k,MidSchedule(i,j-1))+PT(MidSchedule(i,j-1),k),...StartTime(k-1,MidSchedule(i,j))+PT(MidSchedule(i,j),k-1));endendMMidMakespan(i)=StartTime(m,MidSchedule(i,n))+PT(MidSchedule(i,n),m); end% Sort the Makespan and obtain the optimal Schedule[Best,BestIndex]=sort(MMidMakespan);OptNum=1;Makespan=MMidMakespan(BestIndex(1));Schedule=MidSchedule(BestIndex(1),:);%Statistic the total optimal shedulesfor i=2:m-1if MMidMakespan(BestIndex(i))==MMidMakespan(BestIndex(1))OptNum=OptNum+1;Schedule(OptNum,:)=MidSchedule(BestIndex(i),:);endend。
使用MATLAB Engine实现与C混合编程(五)引擎应用程序1、简介引擎应用程序的实质是把MATLAB做为一个引擎,它允许从你自己的C++程序调用这个引擎。
在运行时,引擎作为一个进程单独运行,你的C++程序也作为一个进程单独运行,二者可以通过进程间的通信机制进行交互。
2、引擎库MATLAB引擎库包含了若干个控制MATLAB引擎的函数,如下所示:engOpen 启动MATLAB引擎engClose 关闭MATLAB引擎engGetArray 从MATLAB引擎中获取一个MATLAB矩阵engPutArray 向MATLAB引擎发送一个MA TLAB矩阵engEvalString 执行于一个MATLAB命令engOutputBuffer 创建一个存储MATLAB文本输出的缓冲区同时,引擎应用程序还可以使用前面提到的API函数。
3、一个例子从这个示例中,我们看出引擎应用程序是如何编制的:/** engdemo.c* This is a simple program that illustrates how to call the* MATLAB engine functions from a C program.*/#include#include#include#include "engine.h"#define BUFSIZE 256int main(){Engine *ep;mxArray *T = NULL, *result = NULL;char buffer[BUFSIZE];double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,8.0, 9.0 };8.0, 9.0 };6-6/** Start the MATLAB engine locally by executing the string* "matlab".* To start the session on a remote host, use the name of* the host as the string rather than \0* For more complicated cases, use any string with whitespace,* and that string will be executed literally to start MATLAB.*/if (!(ep = engOpen("\0"))) {fprintf(stderr, "\nCan't start MATLAB engine\n");return EXIT_FAILURE;} /*启动MATLAB引擎*//** PART I* For the first half of this demonstration, we will send data* to MATLAB, analyze the data, and plot the result.* Create a variable for our data.*/T = mxCreateDoubleMatrix(1, 10, mxREAL); /*创建一个矩阵*/mxSetName(T, "T"); /*设置矩阵的名字为“T”*/memcpy((void *)mxGetPr(T), (void *)time, sizeof(time)); /*向矩阵“T”赋值*//** 把矩阵“T”置入MATLAB引擎*/engPutArray(ep, T)/** Evaluate a function of time, distance = (1/2)g.*t.^2* (g is the acceleration due to gravity).*/engEvalString(ep, "D = .5.*(–9.8).*T.^2;");/*执行MATLAB 命令:D = .5.*(–9.8).*T.^2;*//** 绘制图象.*/engEvalString(ep, "plot(T,D);"); /*执行MA TLAB命令:绘图*/engEvalString(ep, "title('Position vs. Time for a fallingobject');"); /*执行MATLAB命令:给图象加标题*/engEvalString(ep, "xlabel('Time (seconds)');"); /*执行MATLAB命令:设置X轴坐标*/ engEvalString(ep, "xlabel('Time (seconds)');"); /*执行MATLAB命令:设置X轴坐标*/ engEvalString(ep, "ylabel('Position (meters)');"); /*执行MATLAB命令:设置Y轴坐标*//** Use fgetc() to make sure that we pause long enough to be* able to see the plot.*/printf("Hit return to continue\n\n");fgetc(stdin);/** We're done for Part I! Free memory, close MATLAB engine.*/printf("Done for Part I.\n");mxDestroyArray(T); /*从内存中撤销矩阵“T”*/engEvalString(ep, "close;"); /*关闭刚才显示图象的窗口*//** PART II* For the second half of this demonstration, we will request* a MATLAB string, which should define a variable X. MATLAB* will evaluate the string and create the variable. We* will then recover the variable, and determine its type.*//** Use engOutputBuffer to capture MATLAB output, so we can* echo it back.*/engOutputBuffer(ep, buffer, BUFSIZE); /*构建MATLAB文本输入缓冲区*/while (result == NULL) {char str[BUFSIZE];/** Get a string input from the user.*/printf("Enter a MATLAB command to evaluate. Thiscommand should\n");printf("create a variable X. This program will thendetermine\n");printf("what kind of variable you created.\n");printf("For example: X = 1:5\n");printf(">> "); /*要求用户输入一个MATLAB命令*/fgets(str, BUFSIZE–1, stdin); /*获得用户输入*//** Evaluate input with engEvalString.*/engEvalString(ep, str); /*执行用户输入的MATLAB命令*/engEvalString(ep, str); /*执行用户输入的MATLAB命令*//** Echo the output from the command. First two characters* are always the double prompt (>>).*/printf("%s", buffer+2); /*显示该MATLAB命令的执行情况*//** Get result of computation.*/printf("\nRetrieving X...\n");if ((result = engGetArray(ep,"X")) == NULL)/*判断是否可以从MATLAB 引擎中获得矩阵“X”*/printf("Oops! You didn't create a variable X.\n\n");elseprintf("X is class %s\t\n", mxGetClassName(result));/*显示矩阵“X”的类型*/} /* while(result==NULL)*//** We're done! Free memory, close MATLAB engine and exit.*/printf("Done!\n");mxDestroyArray(result); /*从内存中撤销矩阵“T”*/engClose(ep); /*关闭MATLAB引擎*/return EXIT_SUCCESS; /*返回*/}4、引擎应用程序的编译对于象上例中的控制台程序,可以在MATLAB命令行中直接使用带-f参数的mex命令编译。
一、程序流程图
二、过程简介
1、初始化参数:族群60,循环500次,交叉0。
8 变异0。
6 代沟0。
9
2、初始化群:按调度优先级编码,比如3个零件,每个零件3个工序,就初始化:
1、3、4、5、6、7、8、9、2
2、1、
3、
4、
5、
6、
7、
8、9 等等
3、计算适应值:解码成工序序列,计算时间
4、选择:在原族群中,按轮盘法选择出60*0。
9(代沟)=54个个体组成新族群。
5、交叉:对选择出来的新族群进行交叉,在新族群中,随机选择2个个体(选择过的个体将不在选择,保证所有个体都选择),随机生成有一个数,如果大于交叉概率,就进行2点交叉。
2点交叉位置每次都是随机的
比如1、2、3、5、6、7、8、4、9
2、1、
3、5、6、
4、9、7、8
如果交叉位置在2和5
先生成0、2、3、5、6、0、0、0
然后按下面的数据删除2、3、5、6后写入就是1、2、3、5、6、4、9、7、8
6、变异:对交叉出来的新族群进行变异,在新族群中,对每个个体,随机生成有一个数,如果大于变异概率,随机生成2个位置数据,将2个位置的数据进行交换
7、替换:新的族群个体是54个,原来的族群为60,保留6个适应值好的,其他代替54个。
三、计算效果图
200
400600
800
1000
1200
1400
012345678910。
function [Zp,Y1p,Y2p,Y3p,Xp,LC1,LC2]=JSPGA(M,N,Pm,T,P)T=[8 90 0 0 0 0 0 0 0 0;0 0 99 62 0 0 0 0 0 0;0 0 0 0 76 94 0 0 0 0;0 0 0 0 0 0 14 68 0 0;0 0 0 0 0 0 0 0 88 27];P=[2;1;4;2;4;1;1;2;4;2];N=100;M=400;Pm=0.75;%--------------------------------------------------------------------------% JSPGA.m% 流水线型车间作业调度遗传算法% 输入参数列表% M 遗传进化迭代次数% N 种群规模(取偶数)% Pm 变异概率% T m×n的矩阵,存储m个工件n个工序的加工时间% P 1×n的向量,n个工序中,每一个工序所具有的机床数目% 输出参数列表% Zp 最优的Makespan值% Y1p 最优方案中,各工件各工序的开始时刻,可根据它绘出甘特图% Y2p 最优方案中,各工件各工序的结束时刻,可根据它绘出甘特图% Y3p 最优方案中,各工件各工序使用的机器编号% Xp 最优决策变量的值,决策变量是一个实数编码的m×n矩阵% LC1 收敛曲线1,各代最优个体适应值的记录% LC2 收敛曲线2,各代群体平均适应值的记录% 最后,程序还将绘出三副图片:两条收敛曲线图和甘特图(各工件的调度时序图)%第一步:变量初始化[m,n]=size(T);%m是总工件数,n是总工序数Xp=zeros(m,n);%最优决策变量LC1=zeros(1,M);%收敛曲线1LC2=zeros(1,N);%收敛曲线2%第二步:随机产生初始种群farm=cell(1,N);%采用细胞结构存储种群for k=1:NX=zeros(m,n);for j=1:nfor i=1:mX(i,j)=1+(P(j)-eps)*rand;endendfarm{k}=X;endcounter=0;%设置迭代计数器while counter<M%停止条件为达到最大迭代次数%第三步:交叉newfarm=cell(1,N);%交叉产生的新种群存在其中Ser=randperm(N);for i=1:2:(N-1)A=farm{Ser(i)};%父代个体B=farm{Ser(i+1)};%父代相邻个体Manner=unidrnd(2);%随机选择交叉方式if Manner==1cp=unidrnd(m-1);%随机选择交叉点%双亲双子单点交叉a=[A(1:cp,:);B((cp+1):m,:)];%子代个体b=[B(1:cp,:);A((cp+1):m,:)];elsecp=unidrnd(n-1);%随机选择交叉点a=[A(:,1:cp),B(:,(cp+1):n)];%双亲双子单点交叉 b=[B(:,1:cp),A(:,(cp+1):n)];endnewfarm{i}=a;%交叉后的子代存入newfarmnewfarm{i+1}=b;end%新旧种群合并FARM=[farm,newfarm];%第四步:选择复制FITNESS=zeros(1,2*N);fitness=zeros(1,N);plotif=0;for i=1:(2*N)X=FARM{i};Z=COST(X,T,P,plotif);%调用计算费用的子函数FITNESS(i)=Z;end%选择复制采取两两随机配对竞争的方式,具有保留最优个体的能力 Ser=randperm(2*N);for i=1:Nf1=FITNESS(Ser(2*i-1));f2=FITNESS(Ser(2*i));if f1<=f2farm{i}=FARM{Ser(2*i-1)};fitness(i)=FITNESS(Ser(2*i-1));elsefarm{i}=FARM{Ser(2*i)};fitness(i)=FITNESS(Ser(2*i));endend%记录最佳个体和收敛曲线minfitness=min(fitness);meanfitness=mean(fitness);LC1(counter+1)=minfitness;%收敛曲线1,各代最优个体适应值的记录 LC2(counter+1)=meanfitness;%收敛曲线2,各代群体平均适应值的记录 pos=find(fitness==minfitness);Xp=farm{pos(1)};%第五步:变异for i=1:Nif Pm>rand;%变异概率为PmX=farm{i};I=unidrnd(m);J=unidrnd(n);X(I,J)=1+(P(J)-eps)*rand;farm{i}=X;endendfarm{pos(1)}=Xp;counter=counter+1;end%输出结果并绘图figure(1);plotif=1;X=Xp;[Zp,Y1p,Y2p,Y3p]=COST(X,T,P,plotif);figure(2);plot(LC1);figure(3);plot(LC2);function [Zp,Y1p,Y2p,Y3p]=COST(X,T,P,plotif)% JSPGA的内联子函数,用于求调度方案的Makespan值% 输入参数列表% X 调度方案的编码矩阵,是一个实数编码的m×n矩阵% T m×n的矩阵,存储m个工件n个工序的加工时间% P 1×n的向量,n个工序中,每一个工序所具有的机床数目% plotif 是否绘甘特图的控制参数% 输出参数列表% Zp 最优的Makespan值% Y1p 最优方案中,各工件各工序的开始时刻% Y2p 最优方案中,各工件各工序的结束时刻% Y3p 最优方案中,各工件各工序使用的机器编号%第一步:变量初始化[m,n]=size(X);Y1p=zeros(m,n);Y2p=zeros(m,n);Y3p=zeros(m,n);%第二步:计算第一道工序的安排Q1=zeros(m,1);Q2=zeros(m,1);R=X(:,1);%取出第一道工序Q3=floor(R);%向下取整即得到各工件在第一道工序使用的机器的编号%下面计算各工件第一道工序的开始时刻和结束时刻for i=1:P(1)%取出机器编号pos=find(Q3==i);%取出使用编号为i的机器为其加工的工件的编号lenpos=length(pos);if lenpos>=1Q1(pos(1))=0;if lenpos>=2for j=2:lenposQ1(pos(j))=Q2(pos(j-1));Q2(pos(j))=Q2(pos(j-1))+T(pos(j),1);endendendendY1p(:,1)=Q1;Y3p(:,1)=Q3;%第三步:计算剩余工序的安排for k=2:nR=X(:,k);%取出第k道工序Q3=floor(R);%向下取整即得到各工件在第k道工序使用的机器的编号%下面计算各工件第k道工序的开始时刻和结束时刻for i=1:P(k)%取出机器编号pos=find(Q3==i);%取出使用编号为i的机器为其加工的工件的编号lenpos=length(pos);if lenpos>=1EndTime=Y2p(pos,k-1);%取出这些机器在上一个工序中的结束时刻POS=zeros(1,lenpos);%上一个工序完成时间由早到晚的排序for jj=1:lenposPOS(jj)=ppp(1);EndTime(ppp(1))=Inf;end%根据上一个工序完成时刻的早晚,计算各工件第k道工序的开始时刻和结束时刻Q1(pos(POS(1)))=Y2p(pos(POS(1)),k-1);Q2(pos(POS(1)))=Q1(pos(POS(1)))+T(pos(POS(1)),k);%前一个工件的结束时刻if lenpos>=2for j=2:lenposQ1(pos(POS(j)))=Y2p(pos(POS(j)),k-1);%预定的开始时刻为上一个工序的结束时刻if Q1(pos(POS(j)))<Q2(pos(POS(j-1)))%如果比前面的工件的结束时刻还早Q1(pos(POS(j)))=Q2(pos(POS(j-1)));endendendendendY1p(:,k)=Q1;Y2p(:,k)=Q2;Y3p(:,k)=Q3;end%第四步:计算最优的Makespan值Y2m=Y2p(:,n);Zp=max(Y2m);%第五步:绘甘特图if plotiffor i=1:mfor j=1:nmPoint1=Y1p(i,j);mPoint2=Y2p(i,j);mText=m+1-i;PlotRec(mPoint1,mPoint2,mText);Word=num2str(Y3p(i,j));%text(0.5*mPoint1+0.5*mPoint2,mText-0.5,Word);hold onx1=mPoint1;y1=mText-1;x2=mPoint2;y2=mText-1;x4=mPoint1;y4=mText;%fill([x1,x2,x3,x4],[y1,y2,y3,y4],'r');fill([x1,x2,x3,x4],[y1,y2,y3,y4],[1,0.5,1]);text(0.5*mPoint1+0.5*mPoint2,mText-0.5,Word);endendendfunction PlotRec(mPoint1,mPoint2,mText)% 此函数画出小矩形% 输入:% mPoint1 输入点1,较小,横坐标% mPoint2 输入点2,较大,横坐标% mText 输入的文本,序号,纵坐标vPoint = zeros(4,2) ;vPoint(1,:) = [mPoint1,mText-1];vPoint(2,:) = [mPoint2,mText-1];vPoint(3,:) = [mPoint1,mText];vPoint(4,:) = [mPoint2,mText];plot([vPoint(1,1),vPoint(2,1)],[vPoint(1,2),vPoint(2,2)]); hold on ;plot([vPoint(1,1),vPoint(3,1)],[vPoint(1,2),vPoint(3,2)]); plot([vPoint(2,1),vPoint(4,1)],[vPoint(2,2),vPoint(4,2)]); plot([vPoint(3,1),vPoint(4,1)],[vPoint(3,2),vPoint(4,2)]);。