我们现在假设n个工厂每天早上同时发出需求,即想要哪个工厂的多少货。然后进行统一分配,这样做能好做一些,后期我们再实现有单独的工厂发出订单,然后单独调度解决。目前代码只考虑总体所有工厂的调度。
1、首先是各个工厂(即节点)间的 距离(此例题中是8个节点)
2.然后是各个工厂想要的货量(我们之前想的是每个工厂对哪个工厂需求多少,但此题是针对物流中心的需求量,即不针对哪个特定的工厂要货)
3.第三个参数是物流中心到各个工厂节点的距离
其中每代他设置了80个样本,即80*8的二维矩阵
一共跑200代
每代这80个样本都要先交叉 变异一下
(感觉这地方有点暴力的意思)
1.首先种群初始化了80×8的矩阵
2.然后while200层循环,每层循环体里先进行交叉变异函数,具体函数在第三大模块
3.经过交叉后还是80*8 但是变异后变成132×8了 即132个样本了
4.然后通过size函数,并且变量设为1,即取得这个二维矩阵的行数 即132
5.然后对着132行进行for循环,每个样本都要进行解码和最短路程的计算,计算结果放到了Total_Dis,即这个矩阵是132×1
6.然后关键的更新种群,他把这个Total_Dis排了个升序(即找最短路程最少的80个),然后依照索引取出对应好的80个样本,然后放到下一代里,继续重复同样的操作
7.最后经过200代,持续淘汰,选出最后一代里80个子代中Total_Dis里最低的那个样本,即最后求出的结果(是一个所有车该先去哪个工厂送货,再去哪个)(然后根据这个结果逐一分配车辆就可以了-这个思路简单)(所以程序关键在于求出一个整体结果)
关于解码函数在下方,也需要转换为java程序
主程序
%算法参数 population_num=80;%种群规模 Max_gen=200;%迭代次数 Pc=0.9;%交叉概率 Pm=0.09;%变异概率 %% %问题参数 %车辆数量Car_num=2 %客户数量Customer_num=8 %车辆容量capacity_max=8 %行驶距离distance_max=50 Car_num=2; Customer_num=8; capacity_max=8; distance_max=50; load Demand %客户的需求 load Distance %客户间的距离 load X %物流中心到客户间的距离 %% %种群初始化 population=zeros(population_num,Customer_num); for i=1:population_num population(i,:)=randperm(Customer_num); end %% y=1;%循环计数器 while y<Max_gen %交叉 [new_pop_intercross]=Mating_pool(population_num,population,Pc); %变异 [new_pop_mutation]=Mutation(new_pop_intercross,Pm); %计算目标函数 mutation_num=size(new_pop_mutation,1); Total_Dis=[]; for k=1:mutation_num [Result]=decode(new_pop_mutation(k,:),distance_max,capacity_max); [Total_Dis(k,1)]=parameter(Result,Customer_num,Car_num); end %更新种群 new_pop_new=zeros(population_num,Customer_num); [Total_Dissort, index] = sort(Total_Dis); for k=1:population_num new_pop_new(k,:)=new_pop_mutation(index(k),:); end population=new_pop_new; %迭代次数加一 y=y+1; end Dis_min1=min(Total_Dis); for k=1:mutation_num if Total_Dis(k,1)==Dis_min1 position1= k; break end end X_Best=new_pop_mutation(position1,:) Y_Obj=Total_Dis(position1,1) t=toc;
交叉函数
function [new_pop_intercross]=Mating_pool(population_num,population,Pc) %% %输入:population,population_num,Pc %输出:1.new_popopulation_intercross % 2.c3,配对池:随机将种群population两两配对 % 3.pool %% pl=randperm(population_num); num=population_num/2; c3=zeros(2,num); pool=[]; new_pop_intercross=population; for kj=1:num c3(1,kj)=pl(2*kj-1); c3(2,kj)=pl(2*kj); end%生成“配对池c3” %%判断“配对池c3”每一对个体的随机数是否小于交叉概率Pc rd=rand(1,num); for kj=1:num if rd(kj)<Pc pool=[pool,c3(:,kj)]; end end %%判断配对池每一对个体的随机数是否小于交叉概率Pc,若小于,保存到“产子池pool” pool_num=size(pool,2); for kj=1:pool_num c1=population(pool(1,kj),:); c2=population(pool(2,kj),:); [new_c1,new_c2]=cross(c1,c2); new_pop_intercross(pool(1,kj),:)=new_c1; new_pop_intercross(pool(2,kj),:)=new_c2; end end
变异函数
function [Mut_Pop]=Mutation(Cross_Pop,Pm) Mut_Pop=Cross_Pop; Cross_Pop_num=size(Cross_Pop,1); for j=1:Cross_Pop_num A=Cross_Pop(j,:); A_1=A; n=size(A,2); r=rand(1,n); Pe=find(r<Pm);%可以引入变异概率 sum_Pe=size(Pe,2); for i=1:sum_Pe c=A(Pe(i)); A_1(Pe(i))=A_1(find(r==max(r))); A_1(find(r==max(r)))=c; Mut_Pop=[Mut_Pop;A_1]; end end
四、解码函数
decode.m
function [Result]=decode(T,distance_max,capacity_max) %distance_max=50; %capacity_max=8; load Demand load Distance load X WS=1;WT=1; a1=0;b1=0; for i=1:size(T,2) if WT==1 a1=2*X(T(i)); b1=Demand(T(i)); elseif WT==2 a1=X(T(i-1))+X(T(i))+Distance(T(i),T(i-1)); b1=Demand(T(i-1))+Demand(T(i)); else a1=0;b1=0; for j=i-WT+1:i-1 a1=a1+Distance(T(j+1),T(j)); b1=b1+Demand(T(j)); end b1=b1+Demand(T(i)); a1=a1+X(T(i-WT+1))+X(T(i)); end if (a1>distance_max)|(b1>capacity_max) a1=2*X(T(i)); b1=Demand(T(1)); WS=WS+1; Result(i,:)=[T(i),WS,a1,b1]; WT=2; else Result(i,:)=[T(i),WS,a1,b1]; WT=WT+1; end end
parameter.m
function [Total_Dis]=parameter(Result,Customer_num,Car_num) %% 解码 if Result(Customer_num,2)<=Car_num Current_Workstation=1; Total_Dis=0; for i=1:Customer_num if Result(i,2)==Current_Workstation; continue else Total_Dis=Total_Dis+Result(i-1,3); Current_Workstation=Current_Workstation+1; end end Total_Dis=Total_Dis+Result(Customer_num,3); else Total_Dis=10000;%引入罚函数 end