⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ga.m.m

📁 遗传算法的小程序
💻 M
📖 第 1 页 / 共 2 页
字号:
% GA.m
% 生成初始种群
tic
M=[1	2	3	4	5	6	7	8	9	10;1	3	5	10	4	2	7	6	8	9;2	1	4	3	9	6	8	7	10	5;2	3	1	5	7	9	8	4	10	6;3	1	2	6	4	5	9	8	10	7;
    3	2	6	4	9	10	1	7	5	8;2	1	4	3	7	6	10	9	8	5;3	1	2	6	5	7	9	10	8	4;1	2	4	6	3	10	7	8	5	9;2	1	3	7	9	10	6	4	5	8];
       % M为各工件工序对应的机器号矩阵
pt=[29	78	9	36	49	11	62	56	44	21 ;43 90	75	11	69	28	46	46	72	30;91 85	39	74	90	10	12	89	45	33;81 95 71	99	9	52	85	98	22	43;14  6 22	61	26	69	21	49	72	53;
    84  2 52	95	48	72	47	65	6	25;46 37 61	13	32	21	32	89	30	55;31 86 46	74	32	88	19	48	36	79;
    76 69 76	51	85	11	40	89	26	74 ;85	13	61	7	64	76	7	52	90	45 ];    % pt为各工件工序对应的加工时间矩阵
[n,m]=size(M);                                        % n为工件数  % m为机器数
solution=zeros(1,n*m);                                % 给定第一个染色体,并以此来生成染色体种群
remainwork=zeros(1,n);
times=zeros(1,n);
for i=1:n
    remainwork(i)=sum(pt(i,:));
end
for j=1:n*m                          %选用优先规则MWKR(即剩余工作量最多的工件优先)来生成初始解
    for i=1:n 
        if remainwork(i)==max(remainwork)
            solution(j)=i;
            times(i)=times(i)+1;
            remainwork(i)= remainwork(i)-pt(i,times(i));
            break;
        end
    end
end         
L=length(solution);
popsize=100;                                      % popsize为种群规模
Nchange=200;                                      % Nchange为生成初始种群时第一个染色体的基因随即交换次数        
chrompop=repmat(solution,popsize,1);              % chrompop为初始种群
for i=2:popsize
    for t=1:Nchange                              % 将chrom_1中的基因随机交换Nchange次得到一个新的染色体
        changerand=ceil(L*rand(1,2));            % 生成随机数来生成染色体种群
        temp=chrompop(i,changerand(1));
        chrompop(i,changerand(1))=chrompop(i,changerand(2));
        chrompop(i,changerand(2))=temp;
    end
end

% 给出迭代步数,调用decomyque.m对每个染色体解码,求得适应度值

iteration=100;                                        % iteration为总迭代次数
fitness=zeros(1,popsize);                             % fitness为chrompop中染色体的适应值数组
maxfitness=zeros(1,iteration);
MAKESPAN=zeros(1,iteration);
const_a=2;
const_b=0.01;
for s=1:popsize
    fitness(s)=decomyque(chrompop(s,:),M,pt);
end
bestfitness=max(fitness);
s=find(fitness==bestfitness);
best_solution=chrompop(min(s),:);
for K=1:iteration
    maxfitness(K)=max(fitness);
    MAKESPAN(K)=-log(maxfitness(K)/const_a)/const_b;
    
    % 以下为选择操作
    selectset=zeros(popsize,L);                 % 定义选择操作后染色体种群为selectset
    selectfitness=zeros(1,popsize);
    sumfitness=sum(fitness);                                
    cumsumfitness=cumsum(fitness);
    dividesum=cumsumfitness/sumfitness;
    selectrand=rand(1,popsize);                 % 随机生成popsize个随机数,从chrompop中选出染色体
    for s=1:popsize
        if  selectrand(s)<dividesum(1)
          selectset(s,:)=chrompop(1,:);
          selectfitness(s)=fitness(1);
        end
        for s_1=2:popsize
            if dividesum(s_1-1)<selectrand(s)&selectrand(s)<dividesum(s_1)
               selectset(s,:)=chrompop(s_1,:);
               selectfitness(s)=fitness(s_1);
               break;
            end
        end
    end
    if  bestfitness<max(selectfitness)
        bestfitness=max(selectfitness);
        s=find(selectfitness==max(selectfitness));
        best_solution=selectset(min(s),:);
    else
        randnumber=ceil(rand*popsize);
        selectset(randnumber,:)=best_solution;
        selectfitness(randnumber)=bestfitness;
    end
    
    % 以下为交叉操作
    crossset=zeros(popsize,L);                                     %定义交叉后染色体群为crossset
    crossfitness=zeros(1,popsize);
    average_fitness=sum(selectfitness)/popsize;
    diversity=sum((selectfitness-average_fitness).^2)/(popsize-1);
    if diversity>400
        poscross=0.7;
    else poscross=0.9-0.0005*diversity;
    end
  if K<ceil(iteration/3)                                          %前面1/3次迭代全部采用双性交叉
    matchrand=randperm(popsize);                                   %生成随机数以便于染色体配对
    crossrand=rand(1,popsize/2);                                   %生成随机数,决定是否交叉
    for s=1:popsize/2
        if crossrand(s)>=poscross                                  %若随机数大于交叉概率则不交叉,直接放入crossset中    
            crossset(s,:)=selectset(matchrand(s),:);
            crossfitness(s)=selectfitness(matchrand(s));
            crossset(popsize+1-s,:)=selectset(matchrand(popsize+1-s),:);
            crossfitness(popsize+1-s)=selectfitness(matchrand(popsize+1-s));
        else                                                       %若随机数小于交叉概率则进行交叉
            crossset(s,:)=selectset(matchrand(s),:);
            crossset(popsize+1-s,:)=selectset(matchrand(popsize+1-s),:);
            elementrand=randperm(L);                               %生成随机数,定义前后交叉点
            x1=min(elementrand(1:2));                               
            x2=max(elementrand(1:2));
            A=crossset(s,x1:x2);                                    %将染色体分别赋给A,B
            B=crossset(popsize+1-s,x1:x2);
            binarycross;                                            %调用函数binarycross.m进行双性交叉
            crossset(s,x1:x2)=A;
            crossset(popsize+1-s,x1:x2)=B;
            crossfitness(s)=decomyque(crossset(s,:),M,pt);
            crossfitness(popsize+1-s)=decomyque(crossset(popsize+1-s,:),M,pt);
        end
    end
elseif K>ceil(iteration/3)&K<ceil(2*iteration/3)                    %中间1/3次迭代中将要双性交叉和单性交叉混用
    matchrand=randperm(popsize);                                   %生成随机数以便于染色体配对
    crossrand=rand(1,popsize/2);                                   %生成随机数,决定是否交叉
    yescross=find(crossrand<poscross);
    nocross=find(crossrand>=poscross);
    if length(yescross)==0                                          %表明此时没有一对染色体要交叉                                           
        crossset=selectset;
        crossfitness=selectfitness;
    elseif length(nocross)==0                                        %表明此时所有染色体均要交叉(一半采用单性交叉,一半双性交叉)
        for s=1:ceil(0.5*(popsize/2))                                    %这半部分采用单性交叉
            crossset(s,:)=selectset(matchrand(s),:);
            crossset(popsize+1-s,:)=selectset(matchrand(popsize+1-s),:);
        r_1=randperm(L);
            r_2=randperm(L);
            r_1(5:L)=[];
            r_2(5:L)=[];
            for s_1=1:3                                            
                for s_2=(1+s_1):4
                    if r_1(s_1)>r_1(s_2)
                        temp=r_1(s_1);
                        r_1(s_1)=r_1(s_2);
                        r_1(s_2)=temp;
                    end
                end
            end
            for s_1=1:3
                for s_2=(1+s_1):4
                    if r_2(s_1)>r_2(s_2)
                        temp=r_2(s_1);
                        r_2(s_1)=r_2(s_2);
                        r_2(s_2)=temp;
                    end
                end
            end
            tempset_1=crossset(s,r_1(1):r_1(2));
            if r_1(3)-r_1(2)==1
                crossset(s,r_1(1):(r_1(1)+r_1(4)-r_1(3)))=crossset(s,r_1(3):r_1(4));
                crossset(s,r_1(1)+r_1(4)-r_1(3)+1:r_1(4))=tempset_1;
            else
                tempset_2=crossset(s,r_1(2)+1:r_1(3)-1);
                crossset(s,r_1(1):(r_1(1)+r_1(4)-r_1(3)))=crossset(s,r_1(3):r_1(4));
                crossset(s,(r_1(1)+r_1(4)-r_1(3)+1):(r_1(1)+r_1(4)-r_1(2)-1))=tempset_2;
                crossset(s,(r_1(1)+r_1(4)-r_1(2)):r_1(4))=tempset_1;
            end
            tempset_1=crossset(popsize+1-s,r_2(1):r_2(2));
            if r_2(3)-r_2(2)==1
                crossset(popsize+1-s,r_2(1):(r_2(1)+r_2(4)-r_2(3)))=crossset(popsize+1-s,r_2(3):r_2(4));
                crossset(popsize+1-s,(r_2(1)+r_2(4)-r_2(3)+1):r_2(4))=tempset_1;
            else
                tempset_2=crossset(popsize+1-s,r_2(2)+1:r_2(3)-1);
                crossset(popsize+1-s,r_2(1):(r_2(1)+r_2(4)-r_2(3)))=crossset(popsize+1-s,r_2(3):r_2(4));
                crossset(popsize+1-s,(r_2(1)+r_2(4)-r_2(3)+1):(r_2(1)+r_2(4)-r_2(2)-1))=tempset_2;
                crossset(popsize+1-s,(r_2(1)+r_2(4)-r_2(2)):r_2(4))=tempset_1;
            end
            crossfitness(s)=decomyque(crossset(s,:),M,pt);
            crossfitness(popsize+1-s)=decomyque(crossset(popsize+1-s,:),M,pt);
        end
        for s=(ceil(0.5*(popsize/2))+1):popsize/2                 %这部分采用双性交叉
            crossset(s,:)=selectset(matchrand(s),:);
            crossset(popsize+1-s,:)=selectset(matchrand(popsize+1-s),:);
            elementrand=randperm(L);                                %生成随机数,定义前后交叉点
            x1=min(elementrand(1:2));                               
            x2=max(elementrand(1:2));
            A=crossset(s,x1:x2);                                    %将染色体分别赋给A,B
            B=crossset(popsize+1-s,x1:x2);
            binarycross;                                            %调用函数binarycross.m进行双性交叉
            crossset(s,x1:x2)=A;
            crossset(popsize+1-s,x1:x2)=B;
            crossfitness(s)=decomyque(crossset(s,:),M,pt);
            crossfitness(popsize+1-s)=decomyque(crossset(popsize+1-s,:),M,pt);
        end
    else                                                           %此时一部分将要进行交叉,另一部分不交叉 
        if length(yescross)==1                                     %此时只有一对染色体将要进行交叉,采用双性交叉方式
            crossset(yescross(1),:)=selectset(matchrand(yescross(1)),:);
            crossset(popsize+1-yescross(1),:)=selectset(matchrand(popsize+1-yescross(1)),:);
            elementrand=randperm(L);                           %生成随机数,定义前后交叉点
            x1=min(elementrand(1:2));                               
            x2=max(elementrand(1:2));
            A=crossset(yescross(1),x1:x2);                                    %将染色体分别赋给A,B
            B=crossset(popsize+1-yescross(1),x1:x2);
            binarycross;
            crossset(yescross(1),x1:x2)=A;
            crossset(popsize+1-yescross(1),x1:x2)=B;
            crossfitness(yescross(1))=decomyque(crossset(yescross(1),:),M,pt);
            crossfitness(popsize+1-yescross(1))=decomyque(crossset(popsize+1-yescross(1),:),M,pt);
            for s=1:length(nocross)
                crossset(nocross(s),:)=selectset(matchrand(nocross(s)),:);
                crossset(popsize+1-nocross(s),:)=selectset(matchrand(popsize+1-nocross(s)),:);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -