基于遗传算法的matlab自动排班程序

#基于遗传算法的matlab自动排班程序
该代码生成排14个人每周值班一次的值班表。先统计14个人每周的无课情况,如图所示:
如第二行第二列的“245”表示该同学第一节课的周二周四周五没课
如:第二行第二列的“245”表示该同学第一节课的周二周四周五没课。
将14个同学进行编号处理,如:陈郭涛为1,潘荣为2,张加斌为3。
然后通过下列代码:

%%初始化
clc;
clear;
c=14;%值班人数
[NUM,TXT,RAW]=xlsread('wukebiao','B9:O12');
w=cell(1,c);

%%
%生成所有人这周的课表
for i=1:c
    w{1,i}=ones(4,5);
end
for j=1:c
    wk=w{1,j};
     x=zeros(4,5);
for i=1:4
    z=num2str(RAW{i,j});
    for k=1:size(z,2)
    x(i,k)=str2num(z(k));
    end
    for m=1:size(x,1)
        for n=1:size(x,2)
            if x(m,n)~=0
            wk(m,x(m,n))=0;
            end
        end
        
    end
    
end
w{1,j}=wk;
end


%%
%遗传算法初始化
m=10;%种群数目
zb=zeros(4,5);%值班表
p=cell(1,m);%初始化种群
for i=1:m
p{1,i}=randperm(20,14);%个体初始化
end
%%
pan=0;
zhiban=zeros(4,5);
%判断适应度是否等于1
while(1)
%计算初始时种群的所有适应度
for i=1:m
   h=p{1,i};
   y=judgment(w,h);
   b(i)=y;
end
%判断适应度是否等于1
for i=1:m
    if b(i)==1
        pan=1;
        disp('****值班表****')
        zhi=p{1,i};
        for i=1:14
            zhiban(zhi(i))=i;
        end
        disp(zhiban);
        
        break;
    end
end
if pan==1
    break;
end
l=select(b,m,p);%选择
v=cross1(l,m,b,w);%交叉
%变异
for i=1:m
    r=variation(v{1,i},m);
    v{1,i}=r;
end
p=v;
end
xlswrite('zhibanbiao',zhiban,'B3:F6');




%%
%建立适应度函数
function y=judgment(w,h)
y=0;
for i=1:14
    s=w{1,i};        %将值班人的课表导入s
    if s(h(i))==0    %判断该值班人在上述值班中是否有课
        y=y+1;       %无课,y++
    end
end
y=y/14;%适应度
end
%%
%应用轮盘选择
function l=select(b,m,p)
%b 为所有适应度的矩阵
%m 为种群的数目
%p 为种群的所有染色体矩阵
l=cell(1,10);
for i=1:m
    B(i)=b(i)/sum(b);%选中某个体的概率
end
C=[0 cumsum(B)];%确定转盘
%选择优质的染色体
for i=1:m
    y=rand(1);
    for j=1:m
        if y>C(j)&&y<=C(j+1)
            l{1,i}=p{1,j};%选中的染色体
        end
    end
end
end
%%
%交叉函数
function one=cross(x,y,m,w)
one1=x;
two1=y;
p=0;
for i=1:14  %取出x中有课的人的编号
s=w{1,i};
if s(x(i))==1
    p=p+1;
    k(p)=i;
end
end
for i=1:length(k)  %将x中有课的人与y交叉
    t=x(k(i));
    x(k(i))=y(k(i));
    y(k(i))=t;
end
one=x;
two=y;
%判断交叉后的染色体是否有重复的基因,若重复,不交叉
for i=1:m-1
    q=0;
    for j=1:m
    if x(i)==x(j)
        q=1;
        one=one1;
        two=two1;break;
    end
    end
    if q==1
        break;
    end
end
end
        
%%
%对染色体进行交叉,交叉率为100%
function v=cross1(l,m,b,w)
%l为选中的所有染色体矩阵
%m为种群的数目
[ones iz]=max(b);%取出最大的适应度的个体

for i=1:m
one=cross(l{1,iz},l{1,i},m,w);
        v{1,i}=one;
end
end

%%
%变异,其变异率为0.09:从一个染色体中随机选一个基因,将该基因变异成该染色体没有的基因
function r=variation(u,m)
%u为一个染色体
if rand(1)<=0.09
    y=randperm(14,1);
ks=0;
ut=[1:20];
%提取染色体中没有的基因
for i=1:14
    for j=1:20-i
        if u(i)==ut(j)
            ut(j)=[];break;
        end
    end
end
u(y)=ut(randperm(4,1));
r=u;
else
    r=u;
end
end
%%   

运行得出:

****值班表****
     0    12     3    14     1
     0     0     8     4    10
     5    13     0     2     0
     6     7    11     9     0

每个编号对应着一个同学,其0代表着没人值班。
这就完成了自动排班的程序。

  • 8
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sur丶JK

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

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

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

打赏作者

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

抵扣说明:

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

余额充值