查看: 168|回复: 0|关注: 0

[未答复] matlab遗传算法的交叉

[复制链接]

新手

5 麦片

财富积分


050


1

主题

1

帖子

0

最佳答案
发表于 2020-7-10 14:26:46 | 显示全部楼层 |阅读模式
clear
char i j;
a=[1 2 3 3 4 1 1 2 3 4 1 2 3 4;2 4 3 1 3 1 1 4 2 3 3 2 4 1;2 1 3 4 1 3 1 2 4 3 2 1 4 3;
    2 3 4 1 3 1 1 4 2 3 3 4 2 1;3 1 3 4 1 2 1 1 2 2 3 3 4 4;2 3 4 1 1 3 1 2 4 3 4 2 1 3;
    1 2 4 3 1 3 2 2 4 4 3 3 1 1;1 4 1 2 3 3 2 4 1 1 3 3 4 2;1 3 2 3 4 1 1 4 4 2 2 3 3 1;
    2 3 1 3 4 1 1 4 2 3 1 4 2 3;1 2 3 3 1 4 1 4 2 3 1 2 3 4;1 3 3 4 1 2 4 4 3 3 1 1 2 2];
b1=a;
b=zeros(12,14);
b2=zeros(12,14);
b3=zeros(12,14);
b4=zeros(1,12);
b5=zeros(1,12);
r=randperm(3);
r1=rand(1,2);
pc=1;

%定点交叉变异
%对原染色体子串进行排序,使得满足装配要求的组合在子串前面,不满足的在后面
k=0;
k1=0;
  %%判断原染色体中哪些是满足装配条件的,满足的放在b矩阵中,并且在原矩阵赋0,并且存放在c1中  
for m=1:4
for i=1:14
    if a(3*m-2,i)+a(3*m-1,i)+a(3*m,i)<=7 && a(3*m-2,i)+a(3*m-1,i)+a(3*m,i)>=4
        b(3*m-2,i)=a(3*m-2,i);
        b(3*m-1,i)=a(3*m-1,i);
        b(3*m,i)=a(3*m,i);
        a(3*m-2:3*m,i)=0;
    end
end
end
c=b;%合格的部分
c1=a;%不合格的部分
%将c中的非0列(也就是装配合格的部分转移到矩阵的前面),存入b22矩阵中
for j=1:4
    for i=1:14
        if c(3*j-2,i)~=0
            k=k+1;
            b2(3*j-2:3*j,k)=c(3*j-2:3*j,i);
        end
    end
    k=0;
end
b22=b2;
%将c1中的非0列(也就是装配不合格的部分转移到矩阵的前面),存入b33矩阵中
for j=1:4
    for i=1:14
        if c1(3*j-2,i)~=0
            k1=k1+1;
            b3(3*j-2:3*j,k1)=c1(3*j-2:3*j,i);
        end
    end
    k1=0;
end
b33=b3;
%统计b22每一行有几个非0元素(有多少个就说明有几个装配合格),存入b4中
for j=1:12

    for i=1:14
        if b22(j,i)==0
          b4(1,j)=i-1;

            break;
        end
    end
end
%统计b33每一行有几个非0元素(有多少个就说明有几个装配不合格),存入b5中
for j=1:12
    for i=1:14
        if b33(j,i)==0
            b5(1,j)=i-1;
            break;
        end
    end
end
%根据b4和b5,以及b22,b33可以对原来的染色体重新排列,使得每对染色体前面部分是装配合格的,后面部分是装配不合格的
B=zeros(12,14);
for j=1:4
    B(3*j-2:3*j,1:b4(1,3*j-2))=b22(3*j-2:3*j,1:b4(1,3*j-2));%前面部分合格
    B(3*j-2:3*j,b4(1,3*j-2)+1:14)=b33(3*j-2:3*j,1:b5(1,3*j-2));%后面部分不合格
end
B1=B;%经过重新排序后的染色体
%交叉操作
for m=1:2
    if r1(1,m)<=pc %判断是否可以交叉
        sub1=B1(r(1,m),1:b4(1,3*m-2));%取出该行装配合格的部分作为子串
        sub2=B1(r(1,m)+3,1:b4(1,3*m-2));%在下一对染色体相同的地方取出同样长度的子串
    else
        sub1=B1(r(1,m),:);%取出的子串为该行整体
        sub2=B1(r(1,m),:);%取出的子串为该行整体
    end
    f1=sub1;
    f2=sub2;
    n=numel(sub1);%记录子串的长度
    %交叉方式为将取出的sub1与父体2逐一比较,如果父体2与sub1有相同元素,则在该位置赋值0
    for i=1:n
        for j=1:14
            if B1(r(1,m)+3,j)==sub1(1,i)
                B1(r(1,m)+3,j)=0;
                break
            end
        end
    end
    A1=B1(r(1,m)+3,:);%将赋值0后的父体2存入A1
    A2=B1(r(1,m),:);%记录父体1的初始值
    A1(find(A1==0))=[];%去除A1中的0元素
    A1=A1(1,1:14-n);
    B1(r(1,m),:)=[sub1,A1];%将A1接在sub1的后面,形成交叉后的父体1
    %下面是相同的方法得到交叉后的父体2
    for i=1:n
        for j=1:14
            if A2(1,j)==sub2(1,i)
                A2(1,j)=0;
                break
            end
        end
    end
    A2(find(A2==0))=[];
    A2=A2(1,1:14-n);
    B1(r(1,m)+3,:)=[sub2,A2];
end
B2=B1;%经过交叉后的染色体
       %%%我的问题是我现在只实现了一次交叉,如果我想用第一次交叉后的染色体作为第二次交叉的初始值,这样以此类推循环下去,请问怎么做?求哪位大神赐教

回复主题 已获打赏: 0 积分

举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

快速回复 返回顶部 返回列表