多目标优化按支配关系分层实现

多目标优化按支配关系分层实现

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

我的微博我的github我的B站

  • 在NSGA-II中,在对种群中的个体支配关系进行确定后,就要对种群中个体按照相互之间的支配关系进行分层。
  • 大体思想是挑选出种群中没有个体能支配的个体作为第0层,即Rank0,然后将受Rank0中个体支配的个体的被支配个数减一,如果此时有个体因为这个操作导致受支配的个数变成1。即除掉Rank0之中的个体以外,没有个体可以支配其。则将这种个体挑选出作为Rank1,依次进行。详细思路可以参见NSGA-II入门

matlab

front=0;
% count刚开始存储的是front0中解的个数
while count>0
    count=0;
    front=front+1;% 此时front从1开始计数
    for i=1:pop
        if population(i).front==front % 筛选当前front元素
            % 对于pop(i)支配的每个个体
            for j=1:population(i).dominatedsetlength
                % i支配个体的索引标记为ind
                ind=population(i).dominatedset(j);
                % ind个体被支配总数减去1
                population(ind).dominationcount=population(ind).dominationcount-1;
                % 如果个体被支配总数等于0,即是说没有个体再去支配她了
                if population(ind).dominationcount==0
                    % 这里没有使用专门的矩阵将不同的front存储,而是将每个个体的front存到属性中
                    population(ind).front=front+1;%将其front标记加1,可以认为把其放到当前层的下一层中
                    count=count+1;%count是一个局部变量,用于记载这个front中存在的个体数
                end
            end
        end
    end
    frontnumbers=[frontnumbers,count];% 记载front中的个体数量
end  

jmetal

  • 和以上实现方法不同的是,jmetal中使用一个列表存储了种群中的每个层,可以调用函数返回每个层中的个体。这里具体展示分层函数的具体实现。
public Ranking(SolutionSet solutionSet) {
		solutionSet_ = solutionSet;

		// dominateMe[i] contains the number of solutions dominating i
		int[] dominateMe = new int[solutionSet_.size()];

		// iDominate[k] contains the list of solutions dominated by k
		List<Integer>[] iDominate = new List[solutionSet_.size()];

		// front[i] contains the list of individuals belonging to the front i
		List<Integer>[] front = new List[solutionSet_.size() + 1];

		// flagDominate is an auxiliar encodings.variable
		int flagDominate;

		// Initialize the fronts
		for (int i = 0; i < front.length; i++)
			front[i] = new LinkedList<Integer>();

		// -> Fast non dominated sorting algorithm
		// Contribution of Guillaume Jacquenot
		for (int p = 0; p < solutionSet_.size(); p++) {
			// Initialize the list of individuals that i dominate and the number
			// of individuals that dominate me
			iDominate[p] = new LinkedList<Integer>();
			dominateMe[p] = 0;
		}
		for (int p = 0; p < (solutionSet_.size() - 1); p++) {
			// For all q individuals , calculate if p dominates q or vice versa
			for (int q = p + 1; q < solutionSet_.size(); q++) {
				flagDominate = constraint_.compare(solutionSet.get(p), solutionSet.get(q));
				if (flagDominate == 0) {
					flagDominate = dominance_.compare(solutionSet.get(p), solutionSet.get(q));
				}
				if (flagDominate == -1) {
					iDominate[p].add(q);
					dominateMe[q]++;
				} else if (flagDominate == 1) {
					iDominate[q].add(p);
					dominateMe[p]++;
				}
			}
			// If nobody dominates p, p belongs to the first front
		}
		for (int p = 0; p < solutionSet_.size(); p++) {
			if (dominateMe[p] == 0) {
				front[0].add(p);
				solutionSet.get(p).setRank(0);
			}
		}

		// Obtain the rest of fronts
		int i = 0;
		Iterator<Integer> it1, it2; // Iterators
		while (front[i].size() != 0) {
			i++;
			it1 = front[i - 1].iterator();
			while (it1.hasNext()) {
				it2 = iDominate[it1.next()].iterator();
				while (it2.hasNext()) {
					int index = it2.next();
					dominateMe[index]--;
					if (dominateMe[index] == 0) {
						front[i].add(index);
						solutionSet_.get(index).setRank(i);
					}
				}
			}
		}
		// <-

		ranking_ = new SolutionSet[i];
		// 0,1,2,....,i-1 are front, then i fronts
		for (int j = 0; j < i; j++) {
			ranking_[j] = new SolutionSet(front[j].size());
			it1 = front[j].iterator();
			while (it1.hasNext()) {
				ranking_[j].add(solutionSet.get(it1.next()));
			}
		}

	} // Ranking
posted @ 2020-04-16 18:55  WUST许志伟  阅读(632)  评论(0编辑  收藏  举报