zoukankan      html  css  js  c++  java
  • 多目标遗传算法 ------ NSGA-II (部分源码解析) 拥挤距离计算 crowddist.c

     1 /* Crowding distance computation routines */
     2 
     3 # include <stdio.h>
     4 # include <stdlib.h>
     5 # include <math.h>
     6 
     7 # include "global.h"
     8 # include "rand.h"
     9 
    10 /* Routine to compute crowding distance based on ojbective function values when the population in in the form of a list */
    11 void assign_crowding_distance_list (population *pop, list *lst, int front_size)
    12 {
    13     int **obj_array;
    14     int *dist;
    15     int i, j;
    16     list *temp;
    17     temp = lst;
    18     if (front_size==1)
    19     {
    20         pop->ind[lst->index].crowd_dist = INF;
    21         return;
    22     }
    23     if (front_size==2)
    24     {
    25         pop->ind[lst->index].crowd_dist = INF;
    26         pop->ind[lst->child->index].crowd_dist = INF;
    27         return;
    28     }
    29     obj_array = (int **)malloc(nobj*sizeof(int));
    30     dist = (int *)malloc(front_size*sizeof(int));
    31     for (i=0; i<nobj; i++)
    32     {
    33         obj_array[i] = (int *)malloc(front_size*sizeof(int));
    34     }
    35     for (j=0; j<front_size; j++)
    36     {
    37         dist[j] = temp->index;
    38         temp = temp->child;
    39     }
    40     assign_crowding_distance (pop, dist, obj_array, front_size);
    41     free (dist);
    42     for (i=0; i<nobj; i++)
    43     {
    44         free (obj_array[i]);
    45     }
    46     free (obj_array);
    47     return;
    48 }
    49 
    50 /* Routine to compute crowding distance based on objective function values when the population in in the form of an array */
    51 void assign_crowding_distance_indices (population *pop, int c1, int c2)
    52 {
    53     int **obj_array;
    54     int *dist;
    55     int i, j;
    56     int front_size;
    57     front_size = c2-c1+1;
    58     if (front_size==1)
    59     {
    60         pop->ind[c1].crowd_dist = INF;
    61         return;
    62     }
    63     if (front_size==2)
    64     {
    65         pop->ind[c1].crowd_dist = INF;
    66         pop->ind[c2].crowd_dist = INF;
    67         return;
    68     }
    69     obj_array = (int **)malloc(nobj*sizeof(int));
    70     dist = (int *)malloc(front_size*sizeof(int));
    71     for (i=0; i<nobj; i++)
    72     {
    73         obj_array[i] = (int *)malloc(front_size*sizeof(int));
    74     }
    75     for (j=0; j<front_size; j++)
    76     {
    77         dist[j] = c1++;
    78     }
    79     assign_crowding_distance (pop, dist, obj_array, front_size);
    80     free (dist);
    81     for (i=0; i<nobj; i++)
    82     {
    83         free (obj_array[i]);
    84     }
    85     free (obj_array);
    86     return;
    87 }

    以上代码里的两个函数都为包装函数,最终的计算都是需要调用下面的函数

    assign_crowding_distance (population *pop, int *dist, int **obj_array, int front_size)  。

    其中,加入一定的判断过程,对一个层里面只有两个个体的情况直接对这两个个体的拥挤距离设定为无穷。

    距离计算的核心代码,如下:

     1 /* Routine to compute crowding distances */
     2 void assign_crowding_distance (population *pop, int *dist, int **obj_array, int front_size)
     3 {
     4     int i, j;
     5     for (i=0; i<nobj; i++)
     6     {
     7         for (j=0; j<front_size; j++)
     8         {
     9             obj_array[i][j] = dist[j];
    10         }
    11         quicksort_front_obj (pop, i, obj_array[i], front_size);
    12     }
    13     for (j=0; j<front_size; j++)
    14     {
    15         pop->ind[dist[j]].crowd_dist = 0.0;
    16     }
    17 
    18     for (i=0; i<nobj; i++)
    19     {
    20         pop->ind[obj_array[i][0]].crowd_dist = INF;
    21     }
    22 
    23     for (i=0; i<nobj; i++)
    24     {
    25         for (j=1; j<front_size-1; j++)
    26         {
    27             if (pop->ind[obj_array[i][j]].crowd_dist != INF)
    28             {
    29                 if (pop->ind[obj_array[i][front_size-1]].obj[i] == pop->ind[obj_array[i][0]].obj[i])
    30                 {
    31                     pop->ind[obj_array[i][j]].crowd_dist += 0.0;
    32                 }
    33                 else
    34                 {
    35                     pop->ind[obj_array[i][j]].crowd_dist += (pop->ind[obj_array[i][j+1]].obj[i] - pop->ind[obj_array[i][j-1]].obj[i])/(pop->ind[obj_array[i][front_size-1]].obj[i] - pop->ind[obj_array[i][0]].obj[i]);
    36                 }
    37             }
    38         }
    39     }
    40 
    41     for (j=0; j<front_size; j++)
    42     {
    43         if (pop->ind[dist[j]].crowd_dist != INF)
    44         {
    45             pop->ind[dist[j]].crowd_dist = (pop->ind[dist[j]].crowd_dist)/nobj;
    46         }
    47     }
    48     return;
    49 }

    5 行 到  12行,  初始化  多目标索引矩阵,并对其不同目标列进行索引排序(按照目标函数值的大小)。

    13行 到 16行, 个体的拥挤距离初始化。

    18行 到 21行, 对按照某目标函数排序后最小的个体的拥挤距离赋值为无穷(并没有对两端赋值无穷,而是最小端的个体)。

    27行,如果一个个体的拥挤距离已经被赋值为无穷,则对其不再计算。

    29行 到  32行,如果某目标函数的排序后所有个体的该目标函数值相同,则该目标函数贡献的距离为 0  。

    pop->ind[obj_array[i][j]].crowd_dist += (pop->ind[obj_array[i][j+1]].obj[i] - pop->ind[obj_array[i][j-1]].obj[i])/(pop->ind[obj_array[i][front_size-1]].obj[i] - pop->ind[obj_array[i][0]].obj[i]);

    35行代码,  某个个体在某一个目标函数上的拥挤距离  为 该个体在该目标函数上前后个体距离之差除以该层该目标的最大最小值之差。

    41 行  到   47行,  将拥挤距离不为无穷的所有个体的拥挤距离除以目标函数值个数(归一化操作)  。 

  • 相关阅读:
    网站优化记录
    在pc游览器端模拟移动端幻灯片
    jquery消息提示框
    开发jquery tab 插件
    js检测是否安装了flash插件
    javaweb项目下解决360兼容模式不能下载文件问题
    简单的excel上传解析和错误反馈信息下载
    sqlserver带游标存储过程及调用函数
    oracle带游标存储过程编写
    简单的spring+dubbo提供和消费方
  • 原文地址:https://www.cnblogs.com/devilmaycry812839668/p/6265021.html
Copyright © 2011-2022 走看看