构造非支配解集(Python)

前言

吃饱了撑的,玩玩多目标,顺便写几个算法。

本文基于《多目标进化优化》:郑金华,邹娟 著 P24 + 页面的内容。

案例数据

这里我们直接使用P28所构造的数据


Data = [(9,1),(7,2),(5,4),(4,5),(3,6),(2,7),(1,9),(10,1),(8,5),(7,6),
        (5,7),(4,8),(3,9),(10,5),(9,6),(8,7),(7,9),(10,6),(9,7),(8,9)
        ]

顺序就是C1-C20

答案是C1-C7

这里咱们在定义一个算法,判断A,B 当中A会不会被B支配。

def Compare(A:tuple,B:tuple):
    # 判断A是否被B支配,只要判断A是不是都大于B就ok了
    Flag = False
    count = 0
    for i in range(len(A)):
        if(A[i]>=B[i]):
            count+=1
    if(count==len(A)):
        Flag = not Flag
    return Flag


庄家法构造非支配解集

咱们先来个最简单实现的算法。这个算法,就是暴力求解,把每一个东西拿出来,然后对比,先把当前的庄家拿出来,如果庄家被支配了直接停止,如果被庄家支配了,就把那个被支配的干掉,走完一编,然后再来,最后选出一组不会被任何人支配的解集。


def ReMove(indexList,Data):
    counter = 0
    for index in indexList:
        index = index - counter
        Data.pop(index)
        counter += 1


def ZJF(Data:list):
    Res = []
    for _ in range(len(Data)):
        if(Data):
            zhuangjia = Data.pop(0)
            Flag = True
            remove_index = []
            for i in range(len(Data)):
                qita = Data[i]
                if(Compare(qita,zhuangjia)):
                    remove_index.append(i)
                elif(Compare(zhuangjia,qita)):
                    Flag = False
                    break
            ReMove(remove_index,Data)
            if(Flag):
                print(zhuangjia,"---->C",_+1)
                Res.append(zhuangjia)
    return Res




在这里插入图片描述

擂台赛法构造

这个擂台赛法和庄家法其实是类似的,区别在于,刚刚庄家如果被支配了我们就停止了,这里的话是这样的,如果庄家挂了,那么就把干掉庄家的家伙拿出来作为当前的庄家。这里需要被注意的是,如果当前产生了新的擂主,我们需要知道原来擂主没有支配的玩意,因为新的擂主可能会支配先前没有支配的玩意。

def BackDelete(no_zhipei:list,remove_index:list,Data:list,zhuangjia:tuple):
    # 负责把前面,上一个庄家可能支配不了的给看看
    if(no_zhipei):
        for no_index in no_zhipei:
            if(Compare(Data[no_index],zhuangjia)):
                remove_index.append(no_index)


def AP(Data:list):
    Res = []
    for _ in range(len(Data)):
        if(Data):
            zhuangjia = Data.pop(0)
            Flag = True
            remove_index = []
            no_zhipei = []
            for i in range(len(Data)):
                qita = Data[i]
                if(Compare(qita,zhuangjia)):
                    remove_index.append(i)
                elif(Compare(zhuangjia,qita)):
                    zhuangjia = qita
                    BackDelete(no_zhipei,remove_index,Data,zhuangjia)
                else:
            #         没有被支配的
                    no_zhipei.append(i)


            ReMove(remove_index,Data)
            if(Flag):
                print(zhuangjia,"---->C",_+1)
                Res.append(zhuangjia)
    return Res

Deb非支配解集构造

这个其实也简单,就是一个个比就ok了。

先假设A是ok的,然后让B过来,如果A被支配了,就留下B,A去了,如果都没有支配,那么A,B 留下,此时C进入,然后C比对。
那么最坏的情况下,第二个比1次,第N个比N-1次


def Deb(Data):
    Res = []
    Res.append(Data.pop(0))

    for _ in range(len(Data)):
        need_ =  Data.pop(0)
        Flag = True
        for i in range(len(Res)):
            if(i<len(Res)):
                if(Compare(need_,Res[i])):
                    Flag=False
                    break
                elif(Compare(Res[i],need_)):
                    Res.pop(i)
        if(Flag):
            Res.append(need_)

        print(Res)


在这里插入图片描述

基于排除法构建

这个方法我感觉是差不多的和DEB是类似的,因为一开始就是有一个NDSET非支配解集,也就是咱们的Res,如果这个Res是null,那么先把解集的某一个解x放到里面,然后此时NDSET有了一个非支配解(临时的)然后拿到第二个x,然后再来,这个x和NDSET的解(y) 比对

def PAICHU(Data:list):
    Res = []
    for _ in range(len(Data)):
        if(len(Res)==0):
            Res.append(Data.pop(0))
        else:
            need_ = Data.pop(0)
            Flag = True
            for i in range(len(Res)):
                if (i < len(Res)):
                    if (Compare(need_, Res[i])):
                        Flag = False
                        break
                    elif (Compare(Res[i], need_)):
                        Res.pop(i)
            if (Flag):
                Res.append(need_)
    print(Res)


在这里插入图片描述

后面还有几个,一个是基于递归的,一个是基于快排的,还有对快排优化的。明天可以玩玩~

猜你喜欢

转载自blog.csdn.net/FUTEROX/article/details/125212022