SortPopulation
SortPopulation
function [pop, F] = SortPopulation(pop)

    % Sort Based on Crowding Distance
    [~, CDSO] = sort([pop.CrowdingDistance], 'descend');
    pop = pop(CDSO);
    
    % Sort Based on Rank
    [~, RSO] = sort([pop.Rank]);
    pop = pop(RSO);
    
    % Update Fronts
    Ranks = [pop.Rank];
    MaxRank = max(Ranks);
    F = cell(MaxRank, 1);
    for r = 1:MaxRank
        F{r} = find(Ranks == r);
    end

end
这个MATLAB函数 `SortPopulation` 用于对一个种群进行排序。这个函数将种群按两个标准进行排序:拥挤距离(Crowding Distance)和等级(Rank),然后根据等级将种群划分为不同的前沿(Fronts)。以下是详细的代码解读:

输入参数

  • pop: 一个结构数组,表示种群,其中每个个体有两个属性 CrowdingDistanceRank

输出参数

  • pop: 按照拥挤距离和等级排序后的种群。
  • F: 一个细胞数组,其中每个元素表示一个前沿的索引集合。

代码详解

function [pop, F] = SortPopulation(pop)

定义了函数 SortPopulation,输入是 pop,输出是 popF

1. 按拥挤距离降序排序

    [~, CDSO] = sort([pop.CrowdingDistance], 'descend');
    pop = pop(CDSO);
  • [pop.CrowdingDistance]pop 中每个个体的拥挤距离提取出来,形成一个数组。
  • sort(..., 'descend') 按照拥挤距离降序排序,并返回排序的索引 CDSO
  • pop = pop(CDSO) 根据索引 CDSOpop 进行重排,使得拥挤距离大的个体排在前面。

2. 按等级升序排序

    [~, RSO] = sort([pop.Rank]);
    pop = pop(RSO);
  • [pop.Rank]pop 中每个个体的等级提取出来,形成一个数组。
  • sort(...) 按照等级升序排序,并返回排序的索引 RSO
  • pop = pop(RSO) 根据索引 RSOpop 进行重排,使得等级低的个体排在前面。

3. 更新前沿

    Ranks = [pop.Rank];
    MaxRank = max(Ranks);
    F = cell(MaxRank, 1);
    for r = 1:MaxRank
        F{r} = find(Ranks == r);
    end
  • [pop.Rank] 获取排序后的种群的等级数组。
  • MaxRank = max(Ranks) 找出最高等级(即前沿的数量)。
  • F = cell(MaxRank, 1) 初始化一个细胞数组 F,其中每个单元格将存储一个前沿。
  • for r = 1:MaxRank 循环从1到最高等级:
    • F{r} = find(Ranks == r) 找出等级为 r 的个体索引,并将这些索引存储在 F{r} 中。

代码总结

函数 SortPopulation 的作用是先按照拥挤距离对种群进行降序排序,再按照等级进行升序排序,然后将种群划分为不同的前沿。最终输出的是排序后的种群和前沿的索引集合。

代码优化

要优化这个函数,可以从多个方面入手,包括减少冗余计算、优化排序操作等。以下是优化版本的 SortPopulation 函数:

function [pop, F] = SortPopulation(pop)

    % Extract Rank and CrowdingDistance arrays
    Ranks = [pop.Rank];
    CrowdingDistances = [pop.CrowdingDistance];

    % Sort based on Rank and Crowding Distance
    [~, sortedIndices] = sortrows([Ranks(:), -CrowdingDistances(:)], [1 2]);
    pop = pop(sortedIndices);

    % Update Fronts
    MaxRank = max(Ranks);
    F = cell(MaxRank, 1);
    for r = 1:MaxRank
        F{r} = find(Ranks(sortedIndices) == r);
    end

end

详细优化步骤

  1. 提取 RankCrowdingDistance 数组

    • 减少重复访问 pop 结构体的次数,提取出 RankCrowdingDistance 数组。
    Ranks = [pop.Rank];
    CrowdingDistances = [pop.CrowdingDistance];
    
  2. 同时排序 RankCrowdingDistance

    • 使用 sortrows 函数对 RankCrowdingDistance 数组进行多列排序。这样可以在一次排序中同时满足两个排序条件。
    • sortrows([Ranks(:), -CrowdingDistances(:)], [1 2]) 按照 Rank 升序和 CrowdingDistance 降序进行排序。
    [~, sortedIndices] = sortrows([Ranks(:), -CrowdingDistances(:)], [1 2]);
    pop = pop(sortedIndices);
    
  3. 更新前沿

    • 使用排序后的索引数组 sortedIndices 来更新前沿。这样可以避免多次计算相同的排序结果。
    MaxRank = max(Ranks);
    F = cell(MaxRank, 1);
    for r = 1:MaxRank
        F{r} = find(Ranks(sortedIndices) == r);
    end
    

性能优化分析

  • 减少冗余计算:通过一次性提取 RankCrowdingDistance 数组,减少对结构体数组 pop 的多次访问。
  • 优化排序操作:使用 sortrows 函数一次性完成基于两个标准的排序,减少排序次数。
  • 简化前沿更新:直接使用排序后的索引数组进行前沿更新,避免了在排序后再次访问未排序的数组。

这个优化版本在计算效率上更高,代码也更简洁清晰。

posted on 2024-06-04 10:19  白茶木  阅读(16)  评论(0编辑  收藏  举报