NSGA2代码分析——rank.c

介绍了一种用于多目标优化的算法,该算法通过对种群进行Pareto分级排序并计算个体间的拥挤距离来实现种群多样性的保持。
    该源文件中就包含一个函数assign_rank_and_crowding_distance (population *new_pop), 主要功能是对种群new_pop里的个体进行Pareto分级排序,同时计算出每个个体的拥挤距离。
    该函数的具体算法流程如下:
1。初始化一个双向链表orig,含有pop_num个节点。每个节点包含三个域:索引、前续节点指针、后续节点指针。每个节点的索引(index)对应着new_pop的第index个个体。
2。从orig中找出所有的非支配个体,并存储在cur链表中。
    (1).取orig中对应的第一个节点,插入到cur链表中。i = 1+1。
    (2).对orig中的第i个节点对应的个体同cur链表中所有节点对应的个体进行Pareto比较,并根据比较结果调整orig和cur链表中的节点。
    (3).如果没有到达orig的最后一个节点,则转入(2)。
3。对cur链表中的个体计算其拥挤距离。(调用assign_crowding_distance_list ()函数,定义在crowdist.c文件中)
4。删除cur链表中所有的节点,即清除当前的所有非支配个体。
5。如果orig还有节点,则转入2。
void assign_rank_and_crowding_distance (population *new_pop)
{
    
int flag;                                //两个个体的Pareto比较结果
    int i;                                    //计数变量
    int end;                                //一轮个体的Pareto级别比较结束标志
    int front_size;                            //记录当前Pareot级别的集合中的个体数目
    int rank=1;                                //记录当前的Pareto级别
    list *orig;                                //记录种群中所有未排序的个体
    list *cur;                                //记录当前个体集中所有非支配个体
    list *temp1, *temp2;                    //临时节点指针,指向当前需要操作的节点
    orig = (list *)malloc(sizeof(list));    //orig链表的头节点
    cur = (list *)malloc(sizeof(list));        //cur链表的头节点
    front_size = 0;
    orig
->index = -1;
    orig
->parent = NULL;
    orig
->child = NULL;
    cur
->index = -1;
    cur
->parent = NULL;
    cur
->child = NULL;
    temp1 
= orig;

    
//初始化orig链表,链表中的节点的index对应于new_pop中的个体下标
    for (i=0; i<popsize; i++)
    {
        insert (temp1,i);
        temp1 
= temp1->child;
    }

    
//对new_pop中的所有个体进行Pareto级别排序
    do
    {
        
//如果orig中未排序的个体只有一个,则把这个个体的拥挤距离设置为INF。
        if (orig->child->child == NULL)
        {
            new_pop
->ind[orig->child->index].rank = rank;
            new_pop
->ind[orig->child->index].crowd_dist = INF;
            
break;
        }
        temp1 
= orig->child;
        insert (cur, temp1
->index);
        front_size 
= 1;
        temp2 
= cur->child;
        temp1 
= del (temp1);
        temp1 
= temp1->child;

        
//以下的do_while对应于步骤2。即找到当前所有未排序个体集合中的非支配个体
        do
        {
            temp2 
= cur->child;
            
do
            {
                end 
= 0;

                
//判断temp2和temp1对应个体的Pareto比较结果,并修改orig和cur链表
                flag = check_dominance (&(new_pop->ind[temp1->index]), &(new_pop->ind[temp2->index]));
                
if (flag == 1)
                {
                    insert (orig, temp2
->index);
                    temp2 
= del (temp2);
                    front_size
--;
                    temp2 
= temp2->child;
                }
                
if (flag == 0)
                {
                    temp2 
= temp2->child;
                }
                
if (flag == -1)
                {
                    end 
= 1;
                }
            }
            
while (end!=1 && temp2!=NULL);
            
if (flag == 0 || flag == 1)
            {
                insert (cur, temp1
->index);
                front_size
++;
                temp1 
= del (temp1);
            }
            temp1 
= temp1->child;
        }
        
while (temp1 != NULL);

        
//对cur链表所有当前的非支配个体的Pareto级别进行赋值
        temp2 = cur->child;
        
do
        {
            new_pop
->ind[temp2->index].rank = rank;
            temp2 
= temp2->child;
        }
        
while (temp2 != NULL);

        
//对当前Pareto级别的所有个体进行拥挤距离计算
        assign_crowding_distance_list (new_pop, cur->child, front_size);
        temp2 
= cur->child;

        
//清除cur链表中的所有当前的非支配个体
        do
        {
            temp2 
= del (temp2);
            temp2 
= temp2->child;
        }
        
while (cur->child !=NULL);
        rank
+=1;
    }
while (orig->child!=NULL);
    free (orig);
    free (cur);
    
return;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值