0

我正在使用遗传算法开发护士排班工具 im matlab,而不使用 GA 工具箱。
个人是每周计划,并表示为一个二维数组,其中行等于护士的数量,七列,因为它是每周计划。
适应度函数获取整个种群并返回一个大小等于包含适应度值的种群大小的数组。

适应度函数应该最小化,所以最好的调度是具有最低适应度值的调度。我的健身功能是:

function fitness_values =Fitness_Function( thePopulation)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here
[Ar1 Ar2 popsize num_nur]  = Return_Data( 0,0,0,0 );
[prev_sched OffArr]=Return_Data1(0,0);
constraints=cell(popsize,1);
fitness_values=zeros(popsize,1); 
size=[1 7];
c1=zeros(popsize,1);
c1values=cell(popsize,1);
W1=0.25; %hard
W2=0.25; %hard
W3=0.25; %hard
W4=0.125; %soft
W5=0.125; %soft

for i=1: popsize
c1values{i}=zeros(size);
end
% Checking Constraint c1 (the difference between night and day shifts in
% each day of the schedule 
for i=1:popsize
for j=1:7
day_sum=0;
night_sum=0;
    for k=1:num_nur
      if thePopulation{i}(k,j)==1
          day_sum=day_sum+1;
      elseif thePopulation{i}(k,j)==2
          night_sum=night_sum+1;
      end
    end 
    abs_diff=abs(day_sum-night_sum);
    c1values{i}(1,j)=abs_diff.^2;
end
c1(i)=sum(c1values{i}(1,:));


%celldisp(c1values);
%defining the array that will hold the result of multiplying the number of
%violations with the correspondig weight,a cell array where each cell
%containts num_nur rows and 4 columns for c2, c3,c4 and c5.

nurse_fitness=zeros(num_nur,1);
for in=1:popsize
constraints{in}=zeros(num_nur,4);
end

for j=1:num_nur
      v2=0;
      v3=0;
      v4=0;
      %check violations with the previous schedule(the last day of the
      %previous schedule with the first day of the evaluated schedule
      % c2
      if prev_sched(j,7)==2 && thePopulation{i}(j,1)==1
          v2=v2+1;
      end
      % c3
      %check the last day of the previous schedule
       if prev_sched(j,7)==1 && thePopulation{i}(j,1)==1 && thePopulation{i}(j,2)~=3
              v3=v3+1;
       %check the last 2 days of the previous schedule       
       elseif prev_sched(j,6)==1 &&prev_sched(j,7)==1 && thePopulation{i}(j,2)~=3
              v3=v3+1;
       end
       %c4
       %check the last day of the previous schedule
       if prev_sched(j,7)==2 && thePopulation{i}(j,1)==3 &&thePopulation{i}(j,2)==1
              v4=v4+1;
       %check the last 2 days of the previous schedule       
       elseif prev_sched(j,6)==2 &&prev_sched(j,7)==3 && thePopulation{i}(j,2)==1
              v4=v4+1;
       end
       %check violations of constraints c2,c3 and c4 in the
       %evaluated schedule
       for k=1:6 
       %check violations of c2 N->N or N->O (hard)
       if thePopulation{i}(j,k)==2 &&  thePopulation{i}(j,k+1)==1 
          v2=v2+1;
       end
       end
       %check violations of c3 D->D->O     (hard)
      for k=1:5
          if thePopulation{i}(j,k)==1 && thePopulation{i}(j,k+1)==1 && thePopulation{i}(j,k+2)~=3
              v3=v3+1;
          end
       %check violations of c4 N->O->N or N->O->O (soft)
          if thePopulation{i}(j,k)==2 && thePopulation{i}(j,k+1)==3 && thePopulation{i}(j,k+2)==1
              v4=v4+1;
          end
      end
      constraints{i}(j,1)=v2*W2;
      constraints{i}(j,2)=v3*W3;
      constraints{i}(j,3)=v4*W4;
      %check violations of c5 (perefrences of each nurse)
      offdays=find(thePopulation{i}(j,:)==3);
      %disp(offdays);
      %disp(OffArr(j,:));
      %find intersection between the perefreces and the days off in the
      %schedule of each nurse
      inters=intersect(offdays,OffArr(j,:));
      num_inters=length(inters);
      if(length(offdays)==1)
      %for head nurse
      if num_inters==1
      constraints{i}(j,4)=0;
      else
      constraints{i}(j,4)=3*W5;
      end
      else
      penalty=3-num_inters;
      constraints{i}(j,4)=penalty*W5;
      end
      nurse_fitness(j)=sum(constraints{i}(j,:));
   end 
  %calculating the fitness value for the whole schedule 

  fitness_values(i)=W1*c1(i)+sum(nurse_fitness);
   end
  end

我将总结它是如何工作的:它需要一个单元格数组(人口)每个单元格包含一个表示为矩阵的时间表,其中行=护士数和 7 列(每周时间表),问题有 3 个硬约束和 2 个软约束, 所以适应度会在每个时间表中检查这些约束的违反情况, 违规的惩罚是通过将每个护士的违反次数乘以相应的约束权重, 所以最终的适应度值是每个护士的惩罚值的总和. 最后,评估计划的适应度值保存在适应度值数组中(与评估计划存储在总体数组中的索引相同)。

我的问题是什么是合适的选择算子来为交叉和变异算子选择父母?

4

1 回答 1

1

您的问题中缺少的要点:

  • “个人”数组中的值是什么意思?
  • 可以违反哪些限制条件?
  • “个体”是否意味着基因型和表型?

我想你也可以用一个简单的例子来说明这些,为了其他人的最佳理解,你可以使用GA 术语吗?

到目前为止,我只能给出一个笼统的答案。一般来说,我认为最好通过非违规个人进行搜索。我要做的不是使用复杂的拟合函数。我宁愿让表型始终是一种非违规解决方案,可以从(可能违规的)基因型快速计算出来。也许基因型不应该掌握整个问题,只需为一个简单的分配算法提供一个起点,该算法可以进行表型。

如果您有非违规染色体,则突变应该轻微影响,从而导致类似的解决方案。您的染色体可能是某种排列,而突变可能是这些上的一些转座。交叉出生的孩子应该跳出父母的解决方案,保留他们的一些特征。对于置换型染色体,您可以找到标准的交叉运算符。

于 2012-12-02T16:28:15.667 回答