多目标优化拥挤距离计算

多目标优化拥挤距离计算

觉得有用的话,欢迎一起讨论相互学习~

我的微博我的github我的B站

  • 拥挤距离主要是维持种群中个体的多样性。具体而言,一般来说是指种群按照支配关系进行非支配排序后,单个Rank层中个体的密集程度。常用于支配关系的多目标算法中,例如NSGA-II.

  • 主要步骤如下:

    1. 取单个前沿中个体按照一个目标上的值从小到大排序
    2. 将最大目标值作为max,最小目标值保留作为min。并且这两个极值点的拥挤距离都被设置为inf即无穷大。 因此注意,一个层中可能有多个具有inf的点,即如果层中有多个点在至少一个目标上相等,并且最大或最小,那么这些点的拥挤距离都是无穷大!!因为目标上呈现垂直的关系也是属于非支配的关系!!如果出现这种情况,说明你算法的多样性很烂!~或者在某些算法早期可能出现这种情况
    3. 在这个目标上计算每个个体最相邻个体之间的距离,即i-1和i+1的目标值的差。并使用max和min对次值进行归一化。
    4. 遍历目标,将目标上已经归一化的拥挤距离相加。
    5. 进入下一层front前沿
    6. 拥挤距离越大越好,最后按照拥挤距离重新排序各层,进而排序种群

matlab

function CrowdDis = CrowdingDistance(PopObj)
% Calculate the crowding distance of each solution in the same front

    [N,M]    = size(PopObj);

    CrowdDis = zeros(1,N);
    Fmax     = max(PopObj,[],1);
    Fmin     = min(PopObj,[],1);
    for i = 1 : M
        [~,rank] = sortrows(PopObj(:,i));
        CrowdDis(rank(1))   = inf;
        CrowdDis(rank(end)) = inf;
        for j = 2 : N-1
            CrowdDis(rank(j)) = CrowdDis(rank(j))+(PopObj(rank(j+1),i)-PopObj(rank(j-1),i))/(Fmax(i)-Fmin(i));
        end
    end
end

jmetal

public void crowdingDistanceAssignment(SolutionSet solutionSet, int nObjs) {
        int size = solutionSet.size();

        if (size == 0)
            return;

        if (size == 1) {
            solutionSet.get(0).setCrowdingDistance(Double.POSITIVE_INFINITY);
            return;
        } // if

        if (size == 2) {
            solutionSet.get(0).setCrowdingDistance(Double.POSITIVE_INFINITY);
            solutionSet.get(1).setCrowdingDistance(Double.POSITIVE_INFINITY);
            return;
        } // if

        // Use a new SolutionSet to evite alter original solutionSet
        SolutionSet front = new SolutionSet(size);
        for (int i = 0; i < size; i++) {
            front.add(solutionSet.get(i));
        }

        for (int i = 0; i < size; i++)
            front.get(i).setCrowdingDistance(0.0);

        double objetiveMaxn;
        double objetiveMinn;
        double distance;

        for (int i = 0; i < nObjs; i++) {
            // Sort the population by Obj n
            front.sort(new ObjectiveComparator(i));
            objetiveMinn = front.get(0).getObjective(i);
            objetiveMaxn = front.get(front.size() - 1).getObjective(i);

            // Set de crowding distance
            front.get(0).setCrowdingDistance(Double.POSITIVE_INFINITY);
            front.get(size - 1).setCrowdingDistance(Double.POSITIVE_INFINITY);

            for (int j = 1; j < size - 1; j++) {
                distance = front.get(j + 1).getObjective(i) - front.get(j - 1).getObjective(i);
                distance = distance / (objetiveMaxn - objetiveMinn);
                distance += front.get(j).getCrowdingDistance();
                front.get(j).setCrowdingDistance(distance);
            } // for
        } // for
    } // crowdingDistanceAssing
posted @ 2020-04-17 01:42  WUST许志伟  阅读(2392)  评论(0编辑  收藏  举报