function [Jlist]=GA() %函数名是GA,输出参数是Jlist,输入参数是GA后的
clear all %function[c]=C(a,t0)
clc
global N %工件数
global M %机器数
global a %恶化率
global t0 %开始时间
global PopSize
PopSize=60;%种群规模
MaxGen =100;%迭代次数
% N=input('输入工件数\n N=');%每条染色体中变量的个数
% M=input('输入机器数\n M=');
N=30;
M=10;
t2=cputime;%记录当前时间
% a=randi([1,10],N,M)/10; %恶化率 随机产生(0.1,1)之间的N行M列的矩阵值
% a=randi([1,3],N,M)/10;
% a=randi([4,6],N,M)/10;
a=randi([7,9],N,M)/10;
xlswrite('D:/a.xlsx', a);
t0=randperm(5,1);%开始时间定为1-5之间的任意一整数
x=xlsread('D:/a');%读取恶化率
a=x(1:N,1:M);
xlswrite('D:/t.xlsx', t0);
t0=xlsread('D:/t');
% t0=1;
%种群中每个染色体基因个数为n,一条染色体是n个互不相同的随机数组成的序列。
%重复执行popsize次得到初始种群
Chrom=zeros(PopSize,N);%随机产生N条染色体的初始种群 ---可改进
for i=1:PopSize
Chrom(i,:)=randperm(N);%染色体即工件编号 randperm就是random permutation随机序列,随机产生N个(1-N)整数的单行矩阵 循环得到n条染色体
end
%开始迭代求解
for k =1:MaxGen
for s =1:PopSize
[Object,Fintime]=fitness(Chrom(s,:));%得到种群每条染色体的适应度值
J(s)=Object;%保存当前种群所有染色体的适应度值
end
Fit0=1./J;%适应度矩阵
f_avg=sum(Fit0)/PopSize;
% f_max=max(max(Fit0));%双max 每列求最大后矩阵求最大 ??? 第一次求行,第二次求向量最值
% f_min=min(min(Fit0));
f_max=max(Fit0);%双max 每列求最大后矩阵求最大 ??? f1,f2...一条染色体对应一个f值
f_min=min(Fit0);
TempChrom0=Chrom;
%% 选择(经典轮盘赌原理选择优秀父代) 选取个体进入下一代
%个体适应度转为选中概率,相当于每次转轮盘指向哪那就被选中,适应度高的个体被选中的概率大
%先按个体选择概率产生一轮盘,然后产生一随机数,落在哪区域就选相应个体交叉。
% 后代产生个数和父代适应度大小成正比,早期容易早熟,后期适应度趋于一致,优秀个体优势不明显,种群进化停滞不前
totalfit = sum(Fit0); %所有染色体的适应值总和,一个数值-
fitvalue =cumsum(Fit0);%一个矩阵 前一列,前两列的和。。。
%[1 2 3 4]则sum的为10,cumsum的为[1 3。。]
%由条件选择一些染色体构成新种群
for newin =1:PopSize
fitin = 1;
temp = rand*totalfit;
while temp>fitvalue(fitin)
fitin = fitin +1;
end
TempChrom(newin,:) = Chrom(fitin,:);
end
Chrom=TempChrom;
%% 单点交叉后有重复的换去 个体间以一定概率交叉 字符串某一位置 其后的所有基因交换 会出现重复基因
%挑选两个个体进行交叉重组 产生新的染色体得到新种群
%可能由父代个体在子代组合成具有更高适合度的个体,
%区别其他传统优化方法的特点之一
for i=1:2:(PopSize-1)
temp =rand;%产生一个随机数
if temp<0.65%当随机数小于交叉概率0.6时-
m=randperm(N-1,1);%产生随机的1-(N-1)之间的一个数
% m= randint(1,1,[1 N-1]);%??
% m=randi([1 N-1],1,1);%随机产生一个数 ???
%randi([1 N-1],m,n) 产生m行n列的矩阵,每个数都是1-N-1可重复
% [ignore,p] = sort(rand(m,n));
% out=p'; 每个数不重复
Temp=Chrom(i,1:m);
Chrom(i,1:m)=Chrom(i+1,1:m);
Chrom(i+1,1:m)=Temp; %交换交叉点之前的染色体
for j=1:m
while(find(Chrom(i,m+1:N)==Chrom(i,j))) %找到重复的点并替换
temp0=find(Chrom(i,m+1:N)==Chrom(i,j));
Chrom(i,j)= Chrom(i+1,temp0+m);
end
while(find(Chrom(i+1,m+1:N)==Chrom(i+1,j)))
temp0=find(Chrom(i+1,m+1:N)==Chrom(i+1,j));
Chrom(i+1,j)= Chrom(i,temp0+m);
end
end
end
end
%% 基本倒位变异 以较小概率变异产生新种群 翻转两点之间的片段
for i =1:PopSize
temp =rand;%产生一个随机数
if temp<0.01 %当随机数小于变异概率时发生变异
%变异率不能取太大,取太大(大于0.5)会退化为随机搜索
%防止重要的单一信息丢失,一般选0.001左右
m=randperm(N,2);
%m=randint(1,1,[1 N-1]);%随机产生1行1列的数,从1到N-1 该2个数?
% m=randi([1 N-1],1,2); %1行2列的两个数
temp1=min(m);
temp2=max(m); %如果两数相同???继续下一轮?
Chrom(i,temp1:temp2)=fliplr(Chrom(i,temp1:temp2));%fliplr 元素左右翻转如[1 2 3]变成[3 2 1];[1 2 3 4]变为[4 3 2 1]
% rot90: 矩阵逆时针旋转n*90度。
%fliplr: 矩阵左右翻转。
%flipud: 矩阵上下翻转。
end
end
for i =1:PopSize
[Object11,Fintime]=fitness(Chrom(i,:));
[Object22,Fintime]=fitness(TempChrom0(i,:));
if Object22<Object11
Chrom(i,:)=TempChrom0(i,:);%如果交叉变异后的目标值比未变异的值小,则将为变异的染色体保留
end
end
% Jlist(k)=min(min(J));%保存每一代的最小值 双min ??
Jlist(k)=min(J);
P(k)=f_avg;
CPUTime=cputime-t2; %当前时间减去开始时系统时间得到整个过程的计算时间
if CPUTime>300
end
end
[value,BestId]=max(Fit0);
Result=Chrom(BestId,:);
[Object,Fintime]=fitness(Result);
% figure(1)
% % 系统自动从1,2,3,4...来建立图形,数字代表第几幅图形,figure(1),figure(2)就是第一第二副图的意思,
% % 在建立图形的时候,标题就是figure1或figure2等,一般建立新图只需要一个figure就行,系统自动建立新图,可以简单一点,当然要加上也可以
% % 另外一个相关的画图:多子图,就是一张图中有好多小图,也是有标号的,使用以下命令
% % subplot(m,n,k)
% % subplot('Position',[left bottom width height])
% % m表示画几行 n表示画几列 k表示现在画的是第几幅图
% plot(1:length(Jlist),Jlist,'r','linewidth',2)
% xlabel('迭代次数');
% ylabel('每代种群的最小值');
% title('遗传算法收敛曲线(目标函数值)')
% get(1)%返回参数的名称和当前值
% set(1)%返回参数的名称和其可能取的值
% figure(2)
% plot(1:length(P),P,'r','linewidth',2)
% xlabel('迭代次数');
% ylabel('每代种群的平均适应度值');
% title('平均适应度值曲线')
fprintf('-------------------------输出结果--------------------------------\n')
% fprintf('种群规模')
% PopSize
fprintf('工件数')
N
fprintf('机器数')
M
fprintf('各工件恶化率a')
digits(2)
a=vpa(a) %只显示两位小数,如0.2
fprintf('开始加工的时间')
t0
% fprintf('工件最优调度顺序')
% Result
% fprintf('各工件(第几个进行加工的顺序)在各机器上的加工完成时间')%按最优调度顺序,Cij表示第i个工件
% Fintime
fprintf('目标函数值(最后一个工件的完工时间)')
Object
fprintf('CPU时间')
CPUTime