该算法需要计算种群P中每个个体i的两个参数ni(种群中支配个体i的个体数目)和si(种群中被个体i支配的个体集合)。
1、找出种群中所有ni=0的个体,保存在集合F1中(也就是第一层)。
2、对F1中的每个个体i,其所支配的个体集合为si,遍历si中每个个体L,nL=nL-1,若nL=0,将L保存在集合H中(第二层)。
3、以H为当前集合,重复2,直到整个种群被分层
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Test 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 var db = new List<Individual> 13 { 14 new Individual(new List<double>() {1, 8}), 15 new Individual(new List<double>() {2, 6}), 16 new Individual(new List<double>() {3, 4}), 17 new Individual(new List<double>() {2, 5}), 18 new Individual(new List<double>() {4, 9}) 19 }; 20 var result=NondominantSort.First_Nondominant_Sort(db); 21 } 22 } 23 public class NondominantSort 24 { 25 public static List<Tier> First_Nondominant_Sort(List<Individual> individuals) 26 { 27 var result = new List<Tier>(); 28 foreach (var p in individuals)//初始化所有个体的各个属性值 29 { 30 foreach (var q in individuals) 31 { 32 var paretoRelation = Pareto(p, q); 33 if (paretoRelation == 1) 34 p.MyDominant.Add(q); 35 else if (paretoRelation == 2) 36 { 37 p.DominantNumber += 1; 38 } 39 } 40 } 41 var tireF1 = GetTire(individuals);//获取第一层 42 43 var newTier = new Tier(); 44 newTier.Individuals.AddRange(tireF1); 45 46 result.Add(newTier); 47 var tire = GetH(tireF1); 48 while (tire.Count > 0) 49 { 50 var newTier1 = new Tier(); 51 newTier1.Individuals.AddRange(tire); 52 53 result.Add(newTier1); 54 tire = GetH(tire); 55 //tire.Clear(); 56 } 57 return result; 58 } 59 /// <summary> 60 /// 根据上一层 获取下一层H 61 /// </summary> 62 /// <returns></returns> 63 public static List<Individual> GetH(List<Individual> tire) 64 { 65 var result = new List<Individual>(); 66 foreach (var individual in tire) 67 { 68 foreach (var individual1 in individual.MyDominant) 69 { 70 individual1.DominantNumber -= 1; 71 if (individual1.DominantNumber == 0) 72 result.Add(individual1); 73 } 74 } 75 76 return result; 77 } 78 /// <summary> 79 /// 获取一层 80 /// </summary> 81 /// <param name="individuals"></param> 82 /// <returns></returns> 83 public static List<Individual> GetTire(List<Individual> individuals) 84 { 85 return individuals.Where(individual => individual.DominantNumber == 0).ToList(); 86 } 87 /// <summary> 88 /// individual1支配individual2返回1,individual2支配individual1返回2,互不支配返回3,返回4两个体相同(以最小值为例) 89 /// </summary> 90 /// <param name="individual1">个体1</param> 91 /// <param name="individual2">个体2</param> 92 /// <returns>支配关系</returns> 93 public static int Pareto(Individual individual1, Individual individual2) 94 { 95 var number1 = individual1.Numbers; 96 var number2 = individual2.Numbers; 97 var count = number1.Count; 98 var results = new int[count]; 99 for (int i = 0; i < count; i++) 100 { 101 if (number1[i] == number2[i]) 102 { 103 results[i] = 0; 104 } 105 else if (number1[i] < number2[i]) 106 results[i] = 1; 107 else 108 { 109 results[i] = 2; 110 } 111 } 112 if (results.Contains(1) && !results.Contains(2)) 113 { 114 return 1;//1支配2 115 } 116 else if (!results.Contains(1) && results.Contains(2)) 117 return 2;//2支配1 118 else if (results.Contains(1) && results.Contains(2)) 119 { 120 return 0;//互不支配 121 //throw new Exception("两个体为同一个个体"); 122 } 123 else 124 { 125 //完全相同的个体 126 return 4; 127 } 128 } 129 } 130 /// <summary> 131 /// 个体 132 /// </summary> 133 public class Individual 134 { 135 public Individual(IEnumerable<double> db) 136 { 137 this.Numbers = new List<double>(); 138 this.Numbers.AddRange(db); 139 this.MyDominant = new List<Individual>(); 140 this.DominantNumber = 0; 141 } 142 /// <summary> 143 /// 有DominantNumber个个体支配该个体 144 /// </summary> 145 public int DominantNumber { get; set; } 146 /// <summary> 147 /// 该个体支配其他个体的集合 148 /// </summary> 149 public List<Individual> MyDominant { get; set; } 150 /// <summary> 151 /// 该个体各个维度数值 152 /// </summary> 153 public List<double> Numbers { get; set; } 154 public void Clean() 155 { 156 this.Numbers.Clear(); 157 this.DominantNumber = 0; 158 this.MyDominant.Clear(); 159 } 160 } 161 /// <summary> 162 /// 非支配中的一层 163 /// </summary> 164 public class Tier 165 { 166 public Tier() 167 { 168 this.Individuals = new List<Individual>(); 169 } 170 public List<Individual> Individuals { get; set; } 171 } 172 }