Source code for opensbt.utils.fps

import itertools
import numpy as np
from scipy.spatial import Voronoi

from pymoo.core.sampling import Sampling
from pymoo.util.normalization import denormalize
from pymoo.util.misc import cdist

[docs] def fps_by_bounds(n_var, xl, xu, n_samples=1, verbose=False): # corners are added to the initial set corners = np.array(list(itertools.product(*np.array((xl, xu)).T.tolist()))) val = corners # the first inner point is chosen randomly and added to the initial set first_point = denormalize(np.random.random((1, n_var)), xl, xu) val = np.vstack((val, first_point)) # initialize the diagram vor = Voronoi(val, incremental=True) while val.shape[0] < n_samples: vertices = vor.vertices indices = np.array([np.all(vertice <= xu) and np.all(vertice >= xl) for vertice in vertices]).nonzero()[0] vertices = vertices[indices] # if none of the vertices are within the boundaries - choose a set of random points # the number of chosen points is the number of expected Voronoi vertices (obtained empirically) if vertices.size == 0: vertices = np.random.random((int(np.ceil(val.shape[0] * np.exp(-1.88 + n_var * 1.192))), n_var)) vertices = denormalize(vertices, xl, xu) if verbose: print("WARNING: None of the Voronoi vertices are within the boundaries.") dist_matrix = cdist(val, vertices) arg = dist_matrix.min(axis=0).argmax() val = np.vstack((val, vertices[arg])) try: vor.add_points([vertices[arg]], restart=True) # update the diagram except: vor = Voronoi(val, incremental=True) if verbose: print("WARNING: The diagram could not be updated. A new diagram was constructed.") if val.shape[0] > n_samples: if verbose: print("WARNING: The initial set is not complete.") val = val[0:n_samples] return val
[docs] def fps(problem, n_samples=1, verbose=False): return fps_by_bounds(problem.n_var, problem.xl, problem.xu, n_samples=n_samples, verbose=verbose)
[docs] class FPS(Sampling):
[docs] def _do(self, problem, n_samples, **kwargs): #verbose = kwargs["verbose"] return fps(problem, n_samples=n_samples, verbose=False)