Как построить многоцелевую границу Парето с помощью DEAP в Python

Для проекта, над которым я работал, я поставил 3 разные цели в качестве цели оптимизации в DEAP: эволюционная структура, основанная на Python< /а>.

Он может справиться с многокритериальной задачей, используя такой алгоритм, как NSGA-II. Есть ли способ создать поверхность границы Парето для визуализации результатов.


person Han Zhengzu    schedule 03.05.2016    source источник


Ответы (2)


Чтобы рассчитать Точки Парето, которые вы можете сделать:

def simple_cull(inputPoints, dominates):
    paretoPoints = set()
    candidateRowNr = 0
    dominatedPoints = set()
    while True:
        candidateRow = inputPoints[candidateRowNr]
        inputPoints.remove(candidateRow)
        rowNr = 0
        nonDominated = True
        while len(inputPoints) != 0 and rowNr < len(inputPoints):
            row = inputPoints[rowNr]
            if dominates(candidateRow, row):
                # If it is worse on all features remove the row from the array
                inputPoints.remove(row)
                dominatedPoints.add(tuple(row))
            elif dominates(row, candidateRow):
                nonDominated = False
                dominatedPoints.add(tuple(candidateRow))
                rowNr += 1
            else:
                rowNr += 1

        if nonDominated:
            # add the non-dominated point to the Pareto frontier
            paretoPoints.add(tuple(candidateRow))

        if len(inputPoints) == 0:
            break
    return paretoPoints, dominatedPoints

def dominates(row, candidateRow):
    return sum([row[x] >= candidateRow[x] for x in range(len(row))]) == len(row)  

import random
inputPoints = [[random.randint(70,100) for i in range(3)] for j in range(500)]
paretoPoints, dominatedPoints = simple_cull(inputPoints, dominates)

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dp = np.array(list(dominatedPoints))
pp = np.array(list(paretoPoints))
print(pp.shape,dp.shape)
ax.scatter(dp[:,0],dp[:,1],dp[:,2])
ax.scatter(pp[:,0],pp[:,1],pp[:,2],color='red')

import matplotlib.tri as mtri
triang = mtri.Triangulation(pp[:,0],pp[:,1])
ax.plot_trisurf(triang,pp[:,2],color='red')
plt.show()

, вы заметите, что последняя часть применяет триангуляцию к точкам Парето и изображает ее в виде треугольной поверхности. Результат таков (где красная фигура — это фронт Парето):

Фронт Парето в matplotlib

EDIT: Также вы можете взглянуть на это (хотя кажется, для 2D-пространств).

person armatita    schedule 03.05.2016

Также вы можете взглянуть на эту ссылку, которая реализует более эффективный способ решения двумерных границ Парето с помощью блочного вложенного цикла (BNL). Это в 30 раз быстрее, чем описанный выше метод грубой силы.

person PatRiot    schedule 21.10.2019
comment
Ссылки на внешние ресурсы приветствуются, но, пожалуйста, добавьте контекст вокруг ссылки, чтобы ваши коллеги-пользователи имели некоторое представление о том, что это такое и почему оно там. Всегда цитируйте наиболее релевантную часть важной ссылки на случай, если целевой сайт недоступен или навсегда отключится. См.: Как ответить. - person Eduardo Baitello; 21.10.2019
comment
Обновленная ссылка: maxhalford.github.io/blog/skyline-queries - person jdpipe; 13.11.2020