# NSGA2快速非支配排序實現-python

``` 1 import numpy as np
2
3
4 def compare(p1, p2):
5     # return 0同層 1 p1支配p2
6     # 每個維度越小越優秀
7     # 計D次
8     D = len(p1)
9     p1_dominate_p2 = True  # p1 更小
10     p2_dominate_p1 = True
11     for i in range(D):
12         if p1[i] > p2[i]:
13             p1_dominate_p2 = False
14         if p1[i] < p2[i]:
15             p2_dominate_p1 = False
16
17     if p1_dominate_p2 == p2_dominate_p1:
18         return 0
19     return 1 if p1_dominate_p2 else -1
20
21
22 def fast_non_dominated_sort(P):
23     # 成員編號爲 0 ~ P_size-1
24     P_size = len(P)
25     # 被支配數
26     n = np.full(shape=P_size, fill_value=0)
27     # 支配的成員
28     S = []
29     # 每層包含的成員編號們
30     f = []  # 0 開始
31     # 所處等級
32     rank = np.full(shape=P_size, fill_value=-1)
33
34     f_0 = []
35     for p in range(P_size):
36         n_p = 0
37         S_p = []
38         for q in range(P_size):
39             if p == q:
40                 continue
41             cmp = compare(P[p], P[q])
42             if cmp == 1:
43                 S_p.append(q)
44             elif cmp == -1:  # 被支配
45                 n_p += 1
46         S.append(S_p)
47         n[p] = n_p
48         if n_p == 0:
49             rank[p] = 0
50             f_0.append(p)
51
52     f.append(f_0)  # 這時候f[0]必存在
53
54     i = 0
55     while len(f[i]) != 0:  # 可能還有i+1層
56         Q = []
57         for p in f[i]:  # i層中每個個體
58             for q in S[p]:  # 被p支配的個體
59                 n[q] -= 1
60                 if n[q] == 0:
61                     rank[q] = i + 1
62                     Q.append(q)
63         i += 1
64         f.append(Q)
65     return rank, f
66
67
68 import matplotlib.pyplot as plt
69
70 if __name__ == '__main__':
71     P = np.random.random(size=(200, 2))
72     rank, f = fast_non_dominated_sort(P)
73     f.pop()
74     # print(rank)
75     # print(f)
76
77     # 繪圖
78     for t in f:
79         # 每level
80         x = P[t][:, 0]
81         y = P[t][:, 1]
82         plt.scatter(x, y, s=15)  # s 點的大小  c 點的顏色 alpha 透明度
83
84     plt.show()```