精华内容
下载资源
问答
  • 遗传算法解决多目标分配的MATLAB代码,感觉很有用,希望可以帮到有需要的朋友
  • 两阶段进化目标粒子群算法目标武器目标分配问题
  • 针对复杂三维环境中无人机协同多目标分配问题,在飞行代价函数建模的基础上,提出了一种改进遗传算法。首先通过引入启发式信息和采用随机生成的方法构造初始种群,保证了初始种群的多样性和高适应性;然后构造适应...
  • 匈牙利算法多目标分配中的应用 ...牙利算法对一对“的最优目标分配指派问题进行求解,并把芭推广至“列垅的多目标分配中。仿真结果表明向牙刺算法对于 此类多目标分配指派问题的求解是十分有效的。
  • 考虑动态的负荷需求和多种燃料资源,以经济成本和环境成本为优化指标,建立动态燃料经济环境负荷分配多目标优化模型,并提出一种多目标粒子群优化算法求解该类优化模型.模型采用动态负荷需求和多种燃料资源,更有利...
  • 针对波束卫星系统中资源分配序列决策的多目标优化(MOP)问题,为了在提升卫星系统性能的同时,提高用户业务需求的满意度,提出了一种基于深度增强学习(DRL)的DRL-MOP 算法。所提算法基于DRL和MOP 技术,动态...
  • 针对传统的目标分配算法未考虑作战过程的实时变化情况,只按分配时刻的作战态势对多目标进行分配,导致火力单元分配过多或过少的问题。本文提出一种基于强化学习与深度神经网络的动态目标分配算法,根据不同想定剧情...
  • 为了解决认知车辆网络的吞吐量和公平性低的问题,我们建立了一个多目标频谱分配模型,以最大化认知车辆网络的平均吞吐量和公平性。 通过将杜鹃搜索算法(CS)与基于分解的多目标优化(MOEA / D)混合,将多目标问题...
  • 针对用户协作中继系统中的功率最小化问题,提出了一种基于联合子载波配对及分配的资源分配算法。首先根据不同用户的目标速率要求及平均信道增益进行子载波数目的分配;然后以信道条件最佳为准则,提出了一种联合子...
  • 基于竞价拍卖理论,定义了基于竞价拍卖的认知无线网络频谱分配摸型,提出了基于双向拍卖的多目标频谱分配算法,并且该算法在频谱分配效率和收益等方面进行了实验仿真。仿真结果表明,该算法在提高频谱利用率的基础上...
  • 遗传算法求解目标分配问题的代码,感觉挺有用的,希望能够帮助到有需要的朋友
  • 行业分类-设备装置-目标优化差分进化算法的传感器目标分配方法及系统.zip
  • 分析了传感器管理的目标分配问题各种解算方法的特点及存在的问题,结合蚁群算法思想,提出了一种新型的目标分配算法模型,并进行了算法仿真。仿真结果表明,基于蚁群算法思想的目标分配算法是有效的,特别是问题规模...
  • 根据目标威胁矩阵和敌优势矩阵,以最大程度保存自己为目标,按照以优攻劣的原则建立了目标分配算法。以一个算例,利用建立的算法模型某空战态势进行了计算,计算结果验证了该模型的可用性和有效性。
  • 基本萤火虫优化算法进行了改进,给出了新的萤火虫更新策略,引入了局部搜索及全局信息交换机制,并将萤火虫优化算法与混合蛙跳算法融合,实现了智能群体共同进化,提出了一种基于群体改进萤火虫优化算法的UCAV目标...
  • 基于混合帕累托算法多目标资源分配问题
  • 装备维修任务分配问题是典型的约束/多目标/非线性规划问题, 利用传统方法无法求解, 因此提出了一种约束多目标粒子群算法, 并运用该算法对装备维修任务分配问题进行了优化求解。仿真结果表明, 约束多目标粒子群算法...
  • 一种针对多目标跟踪的多基雷达系统聚类与功率联合分配算法.pdf
  • 基于深度增强学习和多目标优化改进的卫星资源分配算法.pdf
  • 【路径规划】遗传算法求解考虑分配次序的无人机协同目标分配问题matlab源码.md
  • 利用粒子群优化算法(particle swarm optimization algorithm,PSO)在多目标优化方面的优势,提出基于PSO的多目标优化频谱分配算法PSOSA。PSOSA算法不仅考虑频谱之间的差异,而且重新定义PSO的粒子及粒子的3种运算...
  • 提出一种改进的多目标微粒群优化算法来求解人力资源分配问题。通过种群进行正交初始化,保证了个体在整个可行解空间上的均匀分散,使得算法能够在整个可行解空间上进行均匀搜索; 通过基于网格技术的外部存档非劣...
  • 基于多目标MSQPSO算法的UAVS协同任务分配
  • 基于分解和动态资源分配策略的多目标多因素优化算法
  • 求解多目标分配问题的改进自适应PSO算法研究
  • SORT 多目标跟踪算法笔记

    万次阅读 多人点赞 2019-04-21 15:20:46
    sort 是一种简单的在线实时多目标跟踪算法。文章要点为: 以 IoU 作为前后帧间目标关系度量指标; 利用卡尔曼滤波器预测当前位置; 通过匈牙利算法关联检测框到目标; 应用试探期甄别虚检; 使用 Faster R-...

    SORT 是一种简单的在线实时多目标跟踪算法。文章要点为:

    • 以 IoU 作为前后帧间目标关系度量指标;
    • 利用卡尔曼滤波器预测当前位置;
    • 通过匈牙利算法关联检测框到目标;
    • 应用试探期甄别虚检;
    • 使用 Faster R-CNN,证明检测好跟踪可以很简单。

    技术方案

    SORT 算法以检测作为关键组件,传播目标状态到未来帧中,将当前检测与现有目标相关联,并管理跟踪目标的生命周期。

    检测

    跟踪框架使用 Faster R-CNN 并应用其在 PASCAL VOC 挑战中的默认参数,只输出概率大于50%的行人检测结果而忽略其他类。
    文章在实验中替换 MDP 和所提方法的检测,发现检测质量对跟踪性能有显著影响。在这里插入图片描述

    估计模型

    目标模型,即用于将目标身份传播到下一帧的表示和运动模型。SORT 算法用一个独立于其他物体和相机运动的线性等速模型来近似每个物体的帧间位移。每个目标的状态建模为:

    x = [ u , v , s , r , u ˙ , v ˙ , s ˙ ] T , \mathbf{x} = [u,v,s,r,\dot{u},\dot{v},\dot{s}]^T, x=[u,v,s,r,u˙,v˙,s˙]T,

    其中 u u u v v v 分别代表目标中心的水平和垂直像素位置,而 s s s r r r 分别代表目标边界框的比例(面积)和纵横比。注意,纵横比被认为是常数。关联检测到目标后,用检测到的边界框更新目标状态,其中速度分量通过卡尔曼滤波器框架进行优化求解。如果没有与目标相关的检测,则使用线性速度模型简单地预测其状态而不进行校正。

    数据关联

    在将检测分配给现有目标时:

    • 预测每个目标在当前帧中的新位置,估计其边界框形状;
    • 由每个检测与现有目标的所有预测边界框之间的交并比(IoU)计算分配成本矩阵;
    • 使用匈牙利算法对分配进行优化求解;
    • 拒绝检测与目标重叠小于 I O U m i n IOU_{min} IOUmin 的分配。

    文章发现边界框的 IoU 距离隐式处理由目标经过引起的短时遮挡。具体地说,当遮挡物盖过目标时,只检测到遮挡物。尽管隐藏目标离检测框中心更近,但 IoU 距离更倾向于具有相似比例的检测。这使得可以在不影响覆盖目标的情况下,通过检测对遮挡目标进行校正。

    创建和删除轨迹标识

    当目标进入和离开图像时,需要相应地创建或销毁唯一标识。对于创建跟踪程序,文中认为任何重叠小于 I o U m i n IoU_{min} IoUmin 的检测都表示存在未跟踪的目标。使用速度设置为零的边界框信息初始化跟踪器。由于此时无法观测到速度,因此速度分量的协方差用较大的值初始化,反映出这种不确定性。此外,新的跟踪器将经历一个试用期,其中目标需要与检测相关联以积累足够的证据以防止误报的跟踪。

    如果 T L o s t T_{Lost} TLost 帧未检测到,则终止轨迹。这可以防止跟踪器数量的无限增长以及由于无检测校正下预测时间过长而导致的定位错误。在所有实验中, T L o s t T_{Lost} TLost 设为1有以下原因:

    • 首先,等速模型对真实动力学的预测能力较差;
    • 其次,我们主要关注逐帧跟踪,目标重识别超出本工作范畴;
    • 此外,早期删除丢失的目标有助于提高效率。如果目标重新出现,跟踪将在新标识下隐式恢复。

    sort.py

    算法和程序都比较简单。程序依赖 scikit-learn 所提供的 linear_assignment 实现匈牙利匹配。KalmanFilterFilterPy 提供。

    matplotlib.pyplot.ion() 打开交互模式。

      # all train
      sequences = ['PETS09-S2L1','TUD-Campus','TUD-Stadtmitte','ETH-Bahnhof','ETH-Sunnyday','ETH-Pedcross2','KITTI-13','KITTI-17','ADL-Rundle-6','ADL-Rundle-8','Venice-2']
      args = parse_args()
      display = args.display
      phase = 'train'
      total_time = 0.0
      total_frames = 0
      colours = np.random.rand(32,3) #used only for display
      if(display):
        if not os.path.exists('mot_benchmark'):
          print('\n\tERROR: mot_benchmark link not found!\n\n    Create a symbolic link to the MOT benchmark\n    (https://motchallenge.net/data/2D_MOT_2015/#download). E.g.:\n\n    $ ln -s /path/to/MOT2015_challenge/2DMOT2015 mot_benchmark\n\n')
          exit()
        plt.ion()
        fig = plt.figure() 
      
      if not os.path.exists('output'):
        os.makedirs('output')
    

    对于每个序列,创建一个 SORT 跟踪器实例。
    加载序列的检测数据。检测框格式为[x1,y1,w,h]

      for seq in sequences:
        mot_tracker = Sort() #create instance of the SORT tracker
        seq_dets = np.loadtxt('data/%s/det.txt'%(seq),delimiter=',') #load detections
        with open('output/%s.txt'%(seq),'w') as out_file:
          print("Processing %s."%(seq))
          for frame in range(int(seq_dets[:,0].max())):
            frame += 1 #detection and frame numbers begin at 1
            dets = seq_dets[seq_dets[:,0]==frame,2:7]
            dets[:,2:4] += dets[:,0:2] #convert to [x1,y1,w,h] to [x1,y1,x2,y2]
            total_frames += 1
    

    skimage.io.imread 从文件加载图像。

            if(display):
              ax1 = fig.add_subplot(111, aspect='equal')
              fn = 'mot_benchmark/%s/%s/img1/%06d.jpg'%(phase,seq,frame)
              im =io.imread(fn)
              ax1.imshow(im)
              plt.title(seq+' Tracked Targets')
    

    update 由检测框更新轨迹。trackers命名有问题。

            start_time = time.time()
            trackers = mot_tracker.update(dets)
            cycle_time = time.time() - start_time
            total_time += cycle_time
    

    matplotlib.axes.Axes.add_patch 将补丁p添加到轴补丁列表中;剪辑框将设置为 Axes 剪切框。 如果未设置变换,则将其设置为 transData。返回补丁。
    matplotlib.axes.Axes.set_adjustable 定义 Axes 将更改哪个参数以实现给定面。

            for d in trackers:
              print('%d,%d,%.2f,%.2f,%.2f,%.2f,1,-1,-1,-1'%(frame,d[4],d[0],d[1],d[2]-d[0],d[3]-d[1]),file=out_file)
              if(display):
                d = d.astype(np.int32)
                ax1.add_patch(patches.Rectangle((d[0],d[1]),d[2]-d[0],d[3]-d[1],fill=False,lw=3,ec=colours[d[4]%32,:]))
                ax1.set_adjustable('box-forced')
    
            if(display):
              fig.canvas.flush_events()
              plt.draw()
              ax1.cla()
    
      print("Total Tracking took: %.3f for %d frames or %.1f FPS"%(total_time,total_frames,total_frames/total_time))
      if(display):
        print("Note: to get real runtime results run without the option: --display")
    

    Sort

    Sort 是一个多目标跟踪器,管理多个 KalmanBoxTracker 对象。

      def __init__(self,max_age=1,min_hits=3):
        """
        Sets key parameters for SORT
        """
        self.max_age = max_age
        self.min_hits = min_hits
        self.trackers = []
        self.frame_count = 0
    

    update

    参数dets:格式为[[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]的 numpy 检测数组。
    要求:即使空检测,也必须为每个帧调用此方法一次。返回一个类似的数组,其中最后一列是对象 ID。

    注意:返回的对象数可能与提供的检测数不同。

    update 的输入参数dets为 numpy.array,然而 KalmanBoxTracker 要求的输入为列表。

    Created with Raphaël 2.2.0 update dets KalmanBoxTracker.predict associate_detections_to_trackers KalmanBoxTracker.update KalmanBoxTracker tracks End

    从现有跟踪器获取预测位置。
    predict 推进状态向量并返回预测的边界框估计。

    在当前帧逐个预测轨迹位置,记录状态异常的跟踪器索引。trks存储跟踪器的预测,不幸与下面的跟踪器重名。

        self.frame_count += 1
        #get predicted locations from existing trackers.
        trks = np.zeros((len(self.trackers),5))
        to_del = []
        ret = []
        for t,trk in enumerate(trks):
          pos = self.trackers[t].predict()[0]
          trk[:] = [pos[0], pos[1], pos[2], pos[3], 0]
          if(np.any(np.isnan(pos))):
            to_del.append(t)
    

    numpy.ma.masked_invalid 屏蔽出现无效值的数组(NaN 或 inf)。
    numpy.ma.compress_rows 压缩包含掩码值的2-D 数组的整行。这相当于np.ma.compress_rowcols(a, 0),有关详细信息,请参阅 extras.compress_rowcols
    reversed 返回反向 iterator. seq 必须是具有 __reversed__() 方法的对象,或者支持序列协议(__len__() 方法和 __getitem__() 方法,整数参数从0开始)。

    逆向删除异常的跟踪器,防止破坏索引。压缩能够保证在数组中的位置不变。
    associate_detections_to_trackers 将检测分配给跟踪对象(均以边界框表示)。返回3个列表:matchesunmatched_detectionsunmatched_trackers

        trks = np.ma.compress_rows(np.ma.masked_invalid(trks))
        for t in reversed(to_del):
          self.trackers.pop(t)
        matched, unmatched_dets, unmatched_trks = associate_detections_to_trackers(dets,trks)
    

    使用分配的检测更新匹配的跟踪器。为什么不通过matched存储的索引选择跟踪器?
    update 使用观测边界框更新状态向量。

        #update matched trackers with assigned detections
        for t,trk in enumerate(self.trackers):
          if(t not in unmatched_trks):
            d = matched[np.where(matched[:,1]==t)[0],0]
            trk.update(dets[d,:][0])
    

    由未匹配的检测创建和初始化新的跟踪器。

        #create and initialise new trackers for unmatched detections
        for i in unmatched_dets:
            trk = KalmanBoxTracker(dets[i,:]) 
            self.trackers.append(trk)
    

    get_state 返回当前边界框估计值。
    ret格式为[[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]

    自后向前遍历,仅返回在当前帧出现且命中周期大于self.min_hits(除非跟踪刚开始)的跟踪结果;如果未命中时间大于self.max_age则删除跟踪器。
    hit_streak忽略目标初始的若干帧。

        i = len(self.trackers)
        for trk in reversed(self.trackers):
            d = trk.get_state()[0]
            if((trk.time_since_update < 1) and (trk.hit_streak >= self.min_hits or self.frame_count <= self.min_hits)):
              ret.append(np.concatenate((d,[trk.id+1])).reshape(1,-1)) # +1 as MOT benchmark requires positive
            i -= 1
            #remove dead tracklet
            if(trk.time_since_update > self.max_age):
              self.trackers.pop(i)
    
        if(len(ret)>0):
          return np.concatenate(ret)
        return np.empty((0,5))
    

    associate_detections_to_trackers

    这里命名不准确,应该是将检测框关联到跟踪目标(objects)或者轨迹(tracks),而不是跟踪器(trackers)。
    跟踪器数量为0则直接构造结果。

      if(len(trackers)==0):
        return np.empty((0,2),dtype=int), np.arange(len(detections)), np.empty((0,5),dtype=int)
      iou_matrix = np.zeros((len(detections),len(trackers)),dtype=np.float32)
    

    iou 不支持数组计算。
    逐个计算两两间的交并比,调用 linear_assignment 进行匹配。

      for d,det in enumerate(detections):
        for t,trk in enumerate(trackers):
          iou_matrix[d,t] = iou(det,trk)
      matched_indices = linear_assignment(-iou_matrix)
    

    记录未匹配的检测框及轨迹。

      unmatched_detections = []
      for d,det in enumerate(detections):
        if(d not in matched_indices[:,0]):
          unmatched_detections.append(d)
      unmatched_trackers = []
      for t,trk in enumerate(trackers):
        if(t not in matched_indices[:,1]):
          unmatched_trackers.append(t)
    

    过滤掉 IoU 低的匹配。

      #filter out matched with low IOU
      matches = []
      for m in matched_indices:
        if(iou_matrix[m[0],m[1]]<iou_threshold):
          unmatched_detections.append(m[0])
          unmatched_trackers.append(m[1])
        else:
          matches.append(m.reshape(1,2))
    

    初始化用列表,返回值用 Numpy.array。

      if(len(matches)==0):
        matches = np.empty((0,2),dtype=int)
      else:
        matches = np.concatenate(matches,axis=0)
    
      return matches, np.array(unmatched_detections), np.array(unmatched_trackers)
    

    KalmanBoxTracker

    此类表示观测目标框所对应跟踪对象的内部状态。
    定义等速模型。
    内部使用 KalmanFilter,7个状态变量,4个观测输入。
    F是状态变换模型,H是观测函数,R为测量噪声矩阵,P为协方差矩阵,Q为过程噪声矩阵。
    状态转移矩阵A根据运动学公式确定
    x = [ u , v , s , r , u ˙ , v ˙ , s ˙ ] T , \mathbf{x} = [u,v,s,r,\dot{u},\dot{v},\dot{s}]^T, x=[u,v,s,r,u˙,v˙,s˙]T,
    F = [ 1 0 0 0 Δ u 0 0 0 1 0 0 0 Δ v 0 0 0 1 0 0 0 Δ s 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ] F=\begin{bmatrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; \Delta u &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; \Delta v &amp; 0 \\ 0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; \Delta s \\ 0 &amp; 0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 1 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 1 \end{bmatrix} F=1000000010000000100000001000Δu0001000Δv0001000Δs0001

    H = [ 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ] H=\begin{bmatrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 1 &amp; 0 &amp; 0 &amp; 0 \end{bmatrix} H=1000010000100001000000000000

      count = 0
      def __init__(self,bbox):
        """
        Initialises a tracker using initial bounding box.
        """
        #define constant velocity model
        self.kf = KalmanFilter(dim_x=7, dim_z=4)
        self.kf.F = np.array([
        [1,0,0,0,1,0,0],
        [0,1,0,0,0,1,0],
        [0,0,1,0,0,0,1],
        [0,0,0,1,0,0,0],  
        [0,0,0,0,1,0,0],
        [0,0,0,0,0,1,0],
        [0,0,0,0,0,0,1]])
        self.kf.H = np.array([
        [1,0,0,0,0,0,0],
        [0,1,0,0,0,0,0],
        [0,0,1,0,0,0,0],
        [0,0,0,1,0,0,0]])
    
        self.kf.R[2:,2:] *= 10.
        self.kf.P[4:,4:] *= 1000. #give high uncertainty to the unobservable initial velocities
        self.kf.P *= 10.
        self.kf.Q[-1,-1] *= 0.01
        self.kf.Q[4:,4:] *= 0.01
    
        self.kf.x[:4] = convert_bbox_to_z(bbox)
        self.time_since_update = 0
        self.id = KalmanBoxTracker.count
        KalmanBoxTracker.count += 1
        self.history = []
        self.hits = 0
        self.hit_streak = 0
        self.age = 0
    

    update

    使用观察到的目标框更新状态向量。filterpy.kalman.KalmanFilter.update 会根据观测修改内部状态估计self.kf.x
    重置self.time_since_update,清空self.history

        self.time_since_update = 0
        self.history = []
        self.hits += 1
        self.hit_streak += 1
        self.kf.update(convert_bbox_to_z(bbox))
    

    predict

    推进状态向量并返回预测的边界框估计。
    将预测结果追加到self.history。由于 get_state 直接访问 self.kf.x,所以self.history没有用到。

        if((self.kf.x[6]+self.kf.x[2])<=0):
          self.kf.x[6] *= 0.0
        self.kf.predict()
        self.age += 1
        if(self.time_since_update>0):
          self.hit_streak = 0
        self.time_since_update += 1
        self.history.append(convert_x_to_bbox(self.kf.x))
        return self.history[-1]
    

    get_state

    get_state
    convert_x_to_bbox

    返回当前边界框估计值。

        return convert_x_to_bbox(self.kf.x)
    

    iou

    @numba.jit 即时编译修饰函数以生成高效的机器代码。所有参数都是可选的。

    @jit
    def iou(bb_test,bb_gt):
      """
      Computes IUO between two bboxes in the form [x1,y1,x2,y2]
      """
      xx1 = np.maximum(bb_test[0], bb_gt[0])
      yy1 = np.maximum(bb_test[1], bb_gt[1])
      xx2 = np.minimum(bb_test[2], bb_gt[2])
      yy2 = np.minimum(bb_test[3], bb_gt[3])
      w = np.maximum(0., xx2 - xx1)
      h = np.maximum(0., yy2 - yy1)
      wh = w * h
      o = wh / ((bb_test[2]-bb_test[0])*(bb_test[3]-bb_test[1])
        + (bb_gt[2]-bb_gt[0])*(bb_gt[3]-bb_gt[1]) - wh)
      return(o)
    
    

    convert_bbox_to_z

    [x1,y1,x2,y2]形式的检测框转为滤波器的状态表示形式[x,y,s,r]。其中xy是框的中心,s是比例/区域,r是宽高比。

      w = bbox[2]-bbox[0]
      h = bbox[3]-bbox[1]
      x = bbox[0]+w/2.
      y = bbox[1]+h/2.
      s = w*h    #scale is just area
      r = w/float(h)
      return np.array([x,y,s,r]).reshape((4,1))
    

    convert_x_to_bbox

    [cx,cy,s,r]的目标框表示转为[x_min,y_min,x_max,y_max]的形式。

      w = np.sqrt(x[2]*x[3])
      h = x[2]/w
      if(score==None):
        return np.array([x[0]-w/2.,x[1]-h/2.,x[0]+w/2.,x[1]+h/2.]).reshape((1,4))
      else:
        return np.array([x[0]-w/2.,x[1]-h/2.,x[0]+w/2.,x[1]+h/2.,score]).reshape((1,5))
    

    改进思路

    Sort 算法受限于在线的定位,直接忽略了所有目标的考察期输出。这未免有些因噎废食。对于目标的甄别期较短,可以考虑延时判断后再行输出。

    参考资料:

    展开全文
  • 提出一种多目标遗传算法用于求解该模型,算法中采用染色体组的方式表示可行解,给出了个约束条件下的交叉算子运算规则,个体的各目标值结合岸桥分配启发式算法求得,并应用Pareto分级方法进行适应度值评价;...
  • 改进算法在电力系统多目标负荷分配中的应用.pdf
  • 基于聚类的多目标遗传算法在类职责分配中的应用.pdf
  • 多目标优化-NSGAII算法

    千次阅读 2020-07-04 22:42:26
    NSGA-II学习笔记 ...从学长那里得知,NSGA-II和MOEAD是多目标优化算法的经典算法,不了解这两个讲点算法,相当于白学了多目标优化算法,很多算法也是基于NSGA-II和MOEAD来进行改进和拓展,从而衍生出一系列算法

    NSGA-II学习笔记

    阅读文献:A Fast and Elitist Multiobjective Genetic Algorithm:
    NSGA-II
    有兴趣的话可以阅读中文翻译版本:https://wenku.baidu.com/view/61daf00d0508763230121235.html

    简介

    从学长那里得知,NSGA-II和MOEAD是多目标优化算法的经典算法,不了解这两个讲点算法,相当于白学了多目标优化算法,很多算法也是基于NSGA-II和MOEAD来进行改进和拓展,从而衍生出一系列算法。
    下面我先介绍一下NSGA-II
    NSGA-II 是由Deb跟他的学生在2000年提出了NSGA的改进版本。NSGA2采用快速非支配排序以及拥挤距离的策略,时间复杂度在O(MN2)。由于其速度及效果上的优势,许多年来NSGA2都被作为对比算法。

    下面来说一下,NSGA-II相比于NSGA有以下三点改进:

    1.提出快速非支配排序算法,是计算复杂度由计算复杂度O(MN^3 )降低为O(MN^2 )

    2.引入精英策略,扩大采样空间。将父代种群与其产生的子代种群组合,共同竞争产生下一代种群,有利于保持父代中的优良个体进入下一代,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度。并通过对种群中所有个体的分层存放,使得最佳个体不会丢失,有效提高种群水平。

    3.采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。

    具体

    1.大体算法流程

    	确定种群大小 n,交叉概率 t,迭代次数 g
    
    ​	随机产生 n 个个体,它们整体视为种群 P
    
    ​	for i = 1 to g
    
     		  P’ = ∅ 
    
      		 for j = 1 to n
    
    ​            产生一个 [0,1] 的随机数 a
    
    ​      	 if (a<t)
    
    ​         	从 P 中随机选出两个个体作为父母,交叉产生一个新的个体并放入 P’ 中
    
    ​     	  else
    
    ​         	从 P 中随机选出一个个体,变异产生一个新的个体并放入 P’ 中
    
    ​       	end
    
       end
    
       利用非支配排序和拥挤距离,从 P∪P’ 中选出 n 个个体, 代替 P
    
    end
    输出最终种群 P 中的**非支配个体**
    
    

    在这里插入图片描述

    2.快速非支配排序

    传统的NSGA排序方法:计算复杂度O(MN3) ,M为目标个数,N为种群大小。计算第一帕累托前沿时,每个解都要与其他N-1个解比较M次,即比较次数为M*(N-1)*N,则计算的复杂度为O(MN2),
    如果按照最坏的打算来看的话,即每个解占一个前沿,每个前沿中只有一个解的时候,则计算的复杂度是O(MN3)。
    在经过改进的NSGA-II的快速非支配算法中,计算的复杂度为O(MN2).
    在上篇博客已经写到支配和非支配之间的关系以及表示形式,不熟悉的可以看上一篇博客。
    在这里插入图片描述

    符号含义:
    •种群:P(大写)
    •个体:p,q
    •NP:支配个体p的个体数量
    •SP:被个体p支配的个体集合
    在这里插入图片描述
    根据上图我们可以分析到对于每个种群P而言,p是属于P中的,SP所支配的集合不为空,NP一开始为0,如果p支配于q,那么个体q将并入Sp集合中,如果p被q支配,那么NP自动加一,如果NP为0,那么将是帕累托第一前沿,将p并入F1(第一帕累托前沿)。接着,访问帕累托最优解中S的集合中的解,对每个个体p被访问后,则所支配的个体q,Nq减一,Qrank=i+1。其中若有解对应n值为0,则保存至下一前沿面Frank+1 ,重复上一步骤,直到所有解都划分到对应的前沿面中。在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    同理可得出以下的4.5.6.7.8.9各个点支配情况
    在这里插入图片描述
    我们可以看出1,2,3号点并没有被支配,所以为第一帕累托前沿Np为0,同理可得,4号点被1,2号支配,Np为2,以此类推,N5=3,N6=2,N7=5,N8=6,N9=5。通过下面这张图,通过这张可以非常直观的看到NP和SP的具体情况。
    在这里插入图片描述
    对于4号点,当1号点进行确定后,则1号多支配的4,5,7,8,9的NP-1
    在这里插入图片描述
    以此类推,则可以看到下图,以及Frank的情况
    在这里插入图片描述

    3.拥挤比较算子

    拥挤度

    目的 同一层非支配个体集合中,为了保证解的个体能均匀分配在Pareto前沿,就需要使同一层中的非支配个体具有多样性,否则,个体都在某一处“扎堆”。NSGA—II采用了拥挤度策略,即计算同一非支配层级中某给定个体周围其他个体的密度。

    计算 每个个体的拥挤距离是通过计算与其相邻的两个个体在每个子目标函数上的距离差之和来求取
    在这里插入图片描述
    在这里插入图片描述
    就是在目标变量空间,两个个体在每个子目标函数上的距离差之和来求取拥挤距离。
    在这里插入图片描述
    经过快速非支配排序和拥挤度计算之后,种群中每个个体拥有两个属性:非支配等级ⅈrank和拥挤度id
    定义偏序<n如下:
    在这里插入图片描述

    4.精英策略

    在这里插入图片描述
    在父代种群p和t代产生的新种群Q中,通过非支配排序可以选择出帕累托最优解靠前的前沿面Z1,Z2,对于Z3来说,整体数量已经超过N,可以通过拥挤度比较算子来选择比较优越的个体,从而淘汰不够优越的个体,最终使得父代获得一个整体为N 的个体数量。

    总结

    这是我个人理解的NSGA-II算法大概思想,希望能够帮到大家,也是初学多目标优化算法,如果有一些不对的地方还请大佬们进行批评指正,同时也借鉴了https://blog.csdn.net/qq_35414569/article/details/79639848 这篇博客,使我受益匪浅。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 219,445
精华内容 87,778
关键字:

多对多目标分配算法