该源文件中就包含一个函数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。
该函数的具体算法流程如下:
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 ;
}
{
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 ;
}