3

For the project I was working on, I set 3 different objectives as optimization target in DEAP, an evolution framework based on Python.

It can cope with multi-objectives problem using algorithm like NSGA-II. Is there anyway to generate the pareto frontier surface for the visualizing the results.

usernumber
  • 1,958
  • 1
  • 21
  • 58
Han Zhengzu
  • 3,694
  • 7
  • 44
  • 94

2 Answers2

8

Following a recipe in this link (not my own) to calculate the Pareto Points you could do:

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()

, you will notice that the last part is applying a triangulation to the Pareto points and plotting it as a triangular surface. The results is this (where the red shape is the Pareto front):

Pareto front in matplotlib

EDIT: Also you might want to take a look at this (although it seems to be for 2D spaces).

armatita
  • 12,825
  • 8
  • 48
  • 49
0

Also you might want to take a look at this Link, which implements a more efficient way to solve for 2D pareto frontiers via block nested loop (BNL). This is 30 times faster than the brute force method above.

PatRiot
  • 21
  • 3
  • Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. See: [How to anwser](https://stackoverflow.com/help/how-to-answer). – Eduardo Baitello Oct 21 '19 at 01:44
  • Updated link: https://maxhalford.github.io/blog/skyline-queries/ – jdpipe Nov 13 '20 at 10:04