用两个目标。最小成本和最大满意度用python写出NSGA2精英策略中的快速非支配排序函数和计算拥挤度函数dominatespopulationi populationj没写写出来
NSGA2是一种常用的多目标优化算法,其核心是快速非支配排序(Fast Non-dominated Sorting)和拥挤度计算(Crowding Distance Calculation)。下面是一个NSGA2的Python实现,包含快速非支配排序函数和拥挤度计算函数。
首先,我们定义一个目标函数类,包含两个目标:最小成本和最大满意度。
class ObjectiveFunction:
def __init__(self, cost, satisfaction):
self.cost = cost
self.satisfaction = satisfaction
def dominates(self, other):
return self.cost <= other.cost and self.satisfaction >= other.satisfaction
其中,dominates函数判断当前目标函数是否支配另一个目标函数。
接下来,我们实现快速非支配排序函数:
def fast_non_dominated_sort(population):
fronts = [[]]
dominated = {}
rank = {}
for i, p in enumerate(population):
dominated[i] = set()
rank[i] = 0
for j, q in enumerate(population):
if p.dominates(q):
dominated[i].add(j)
elif q.dominates(p):
rank[i] += 1
if rank[i] == 0:
fronts[0].append(i)
i = 0
while len(fronts[i]) > 0:
next_front = []
for p in fronts[i]:
for q in dominated[p]:
rank[q] -= 1
if rank[q] == 0:
next_front.append(q)
i += 1
fronts.append(next_front)
return fronts[:-1]
该函数将种群划分为多个前沿,每个前沿中的个体都是非支配的。该函数的输入为一个种群,输出为一个前沿列表,其中每个前沿都是一个个体的索引列表。
最后,我们实现拥挤度计算函数:
def crowding_distance(population, front):
distances = [0] * len(front)
for obj_func in ObjectiveFunction.__dict__.keys():
if obj_func.startswith("__"):
continue
sorted_front = sorted(front, key=lambda p: getattr(population[p], obj_func))
distances[0] = distances[-1] = float("inf")
for i in range(1, len(front) - 1):
distances[i] += getattr(population[sorted_front[i+1]], obj_func) - getattr(population[sorted_front[i-1]], obj_func)
return distances
该函数计算每个个体的拥挤度。对于每个目标函数,将当前前沿按照该目标函数的值进行排序,然后计算每个个体与其相邻个体之间的距离之和作为拥挤度。
完整代码如下:
class ObjectiveFunction:
def __init__(self, cost, satisfaction):
self.cost = cost
self.satisfaction = satisfaction
def dominates(self, other):
return self.cost <= other.cost and self.satisfaction >= other.satisfaction
def fast_non_dominated_sort(population):
fronts = [[]]
dominated = {}
rank = {}
for i, p in enumerate(population):
dominated[i] = set()
rank[i] = 0
for j, q in enumerate(population):
if p.dominates(q):
dominated[i].add(j)
elif q.dominates(p):
rank[i] += 1
if rank[i] == 0:
fronts[0].append(i)
i = 0
while len(fronts[i]) > 0:
next_front = []
for p in fronts[i]:
for q in dominated[p]:
rank[q] -= 1
if rank[q] == 0:
next_front.append(q)
i += 1
fronts.append(next_front)
return fronts[:-1]
def crowding_distance(population, front):
distances = [0] * len(front)
for obj_func in ObjectiveFunction.__dict__.keys():
if obj_func.startswith("__"):
continue
sorted_front = sorted(front, key=lambda p: getattr(population[p], obj_func))
distances[0] = distances[-1] = float("inf")
for i in range(1, len(front) - 1):
distances[i] += getattr(population[sorted_front[i+1]], obj_func) - getattr(population[sorted_front[i-1]], obj_func)
return distances
``
原文地址: https://www.cveoy.top/t/topic/ceZa 著作权归作者所有。请勿转载和采集!