platypus.core module

class platypus.core.AdaptiveGridArchive(capacity, nobjs, divisions, dominance=<platypus.core.ParetoDominance object>)

A bounded archive using density to truncate solutions.

The objective space is partitioned into a grid containing math.pow(divisions, nobjs) cells. Please note that this can quickly result in a large internal array or an integer overflow as either divisions or nobjs grows.

The density of each cell is measured by counting the number of solutions within the cell. When the archive exceeds the desired capacity, a solution is removed from the densest cell(s).

Parameters

capacityint

The maximum capacity of this archive.

nobjsint

The number of objectives.

divisionsint

The number of divisions in objective space

dominanceDominance

The dominance criteria (default is Pareto dominance).

adapt_grid()

Adapts the grid by updating the bounds and density.

add(solution)

Try adding a solution to this archive.

Three outcomes can occur when adding a solution: 1. The solution is non-dominated. The new solution is added to the

archive.

  1. The solution dominiates one or more members of the archive. The dominated solutions are removed and the new solution added.

  2. The solution is dominated by one or more members of the archive. The new solution is rejected and the archive is unchanged.

Parameters

solutionSolution

The solution to add.

Returns

True if the solution is non-dominated and added to the archive, False otherwise.

find_densest()

Finds the grid cell index with the highest density.

find_index(solution)

Returns the grid cell index of the given solution.

pick_from_densest()

Picks a solution from the densest grid cell(s).

remove(solution)

Try removing the solution from this archive.

Parameters

solutionSolution

The solution to remove.

Returns

True if the solution was removed from this archive, False otherwise.

class platypus.core.Algorithm(problem, evaluator=None, log_frequency=None, **kwargs)

Base class for all optimization algorithms.

Parameters

problemProblem

The problem being optimized.

evaluatorEvaluator

The evalutor used to evaluate solutions. If None, the default evaluator defined in PlatypusConfig is selected.

log_frequencyint

The frequency to log evaluation progress. If None, the default log frequency defined in PlatypusConfig is selected.

Attributes

nfeint

The current number of function evaluations (NFE)

result: list or Archive

The current result, which is updated after each iteration.

evaluate_all(solutions)

Evaluates all of the given solutions.

Subclasses should prefer using this method to evaluate solutions, ideally providing an entire population to leverage parallelization, as it tracks NFE.

Parameters

solutionslist of Solution

The solutions to evaluate.

run(condition, callback=None)

Runs this algorithm until the termination condition is reached.

Parameters

conditionint or TerminationCondition

The termination condition. Providing an integer value is converted into the MaxEvaluations condition.

callbackCallable, optional

Callback function that is invoked after every iteration. The callback is passed this algorithm instance.

abstract step()

Performs one logical step of the algorithm.

In most contexts, the first invocation to step should initialize the algorithm, usually generating an initial population randomly. All subsequent calls to step evolve the population one “generation”.

Each step is expected to geneate and evaluate at least one solution in order to avoid looping indenfinitely. Any termination conditions and callbacks are called after each step.

class platypus.core.Archive(dominance=<platypus.core.ParetoDominance object>)

An archive containing only non-dominated solutions.

Since an archive stores non-dominated solutions, its size can potentially grow unbounded. Consider using one of the subclasses that provide truncation.

Parameters

dominanceDominance

The dominance criteria (default is Pareto dominance).

add(solution)

Try adding a solution to this archive.

Three outcomes can occur when adding a solution: 1. The solution is non-dominated. The new solution is added to the

archive.

  1. The solution dominiates one or more members of the archive. The dominated solutions are removed and the new solution added.

  2. The solution is dominated by one or more members of the archive. The new solution is rejected and the archive is unchanged.

Parameters

solutionSolution

The solution to add.

Returns

True if the solution is non-dominated and added to the archive, False otherwise.

append(solution)

Append a solution to this archive.

This is similar to add() except no result is returned.

Parameters

solutionSolution

The solution to append.

extend(solutions)

Appends a list of solutions to this archive.

Parameters

solutionsiterable of Solution

The solutions to append.

remove(solution)

Try removing the solution from this archive.

Parameters

solutionSolution

The solution to remove.

Returns

True if the solution was removed from this archive, False otherwise.

class platypus.core.AttributeDominance(getter, larger_preferred=True)

Dominance based on the value of an attribute.

The referenced attribute must be numeric, typically either an int or float.

Parameters

getterCallable

Function that reads the value of the attribute from each solution.

larger_preferredbool

Determines if larger or smaller values are preferred.

compare(solution1, solution2)

Compare two solutions for dominance.

Parameters

solution1Solution

The first solution.

solution2Solution

The second solution.

Returns

-1 if the first solution dominates the second, 1 if the second solution dominates the first, or 0 if the two solutions are mutually non-dominated.

class platypus.core.Constraint(op, value=None)

Defines an constraint on an optimization problem.

A constraint can be defined in several ways. First, with a given operator and value:

Constraint("<=", 10)

Second, by providing a string with the operator and value together:

Constraint("<= 10")

Third, by providing a function to compute the constraint value, where any non-zero value is considered a constraint violation:

Constraint(lambda x : 0 if x <= 10 else math.abs(10 - x))
class platypus.core.Dominance

Compares two solutions for dominance.

abstract compare(solution1, solution2)

Compare two solutions for dominance.

Parameters

solution1Solution

The first solution.

solution2Solution

The second solution.

Returns

-1 if the first solution dominates the second, 1 if the second solution dominates the first, or 0 if the two solutions are mutually non-dominated.

class platypus.core.EpsilonBoxArchive(epsilons)

Archive based on epsilon-box dominance.

Uses EpsilonDominance to limit the size of the archive. This avoids adding many non-dominated solutions that are similar to one another, as controlled by the provided epsilons.

Parameters

epsilonslist of float

The epsilons that control the size of the epsilon boxes.

Attributes

improvementsint

Tracks the number of epsilon-box improvements, which by definition counts the number of new solutions accepted into this archive.

add(solution)

Try adding a solution to this archive.

Three outcomes can occur when adding a solution: 1. The solution is non-dominated. The new solution is added to the

archive.

  1. The solution dominiates one or more members of the archive. The dominated solutions are removed and the new solution added.

  2. The solution is dominated by one or more members of the archive. The new solution is rejected and the archive is unchanged.

Parameters

solutionSolution

The solution to add.

Returns

True if the solution is non-dominated and added to the archive, False otherwise.

class platypus.core.EpsilonDominance(epsilons)

Epsilon dominance.

Similar to Pareto dominance except if the two solutions are contained within the same epsilon-box, the solution closer to the optimal corner of the box is preferred.

Parameters

epsilonslist of float

The epsilons that define the sizes of the epsilon-box.

compare(solution1, solution2)

Compare two solutions for dominance.

Parameters

solution1Solution

The first solution.

solution2Solution

The second solution.

Returns

-1 if the first solution dominates the second, 1 if the second solution dominates the first, or 0 if the two solutions are mutually non-dominated.

same_box(solution1, solution2)

Determines if the two solutions exist in the same epsilon-box.

Parameters

solution1Solution

The first solution.

solution2: Solution

The second solution.

Returns

True if the two solutions are in the same epsilon-box, False otherwise.

class platypus.core.FitnessArchive(fitness, dominance=<platypus.core.ParetoDominance object>, larger_preferred=True, getter=<function fitness_key>)

A bounded archive that uses fitness to truncate solutions.

Fitness is a generic term, simply referring to numeric attributes assigned to a solution. For instance, below we use crowding_distance() to assign the crowding_distance attribute, and crowding_distance_key() to read those values:

FitnessArchive(crowding_distance, getter=crowding_distance_key)

Refer to truncate_fitness() for more details.

Parameters

fitnessCallable

Function for calculating and assigning a fitness attribute to all members of the archive.

dominanceDominance

The dominance criteria (default is Pareto dominance).

larger_preferredbool

Determines if larger or smaller fitness values are preferred during truncation.

getterCallable

Function that reads the fitness attribute from a solution. This should match the attribute assigned by the fitness function.

truncate(size)

Truncates the archive to the given size.

Parameters

sizeint

The desired size of this archive.

class platypus.core.Generator

Abstract class for generating initial populations.

abstract generate(problem)

Generates a single, random solution for the problem.

Parameters

problemProblem

The problem being optimized.

class platypus.core.Indicator

Abstract class for performance indicators.

abstract calculate(set)

Calculates and returns the indicator value.

Parameters

setiterable of Solution

The collection of solutions against which the indicator value is computed.

class platypus.core.MaxEvaluations(nfe)

Termination condition based on the maximum number of function evaluations.

Parameters

nfeint

The maximum number of function evaluations to run the algorithm.

initialize(algorithm)

Initializes this termination condition.

This method is called once at the start of a run, and should be used to record any initial state. Also consider that users can call run multiple times, where each invocation continues the execution of the run from where it left off.

Parameters

algorithmAlgorithm

The algorithm instance.

shouldTerminate(algorithm)

Checks if the algorithm should terminate.

This method is called after each iteration. The defintion of one “iteration” in specific to each algorithm. For example, a generational algorithm typically produces and evaluates multiple offspring each iteration. Consequently, a run might not stop exactly where the termination condition indicates.

Parameters

algorithmAlgorithm

The algorithm instance.

Returns

True if the termination condition is satisfied and the run should stop; False otherwise.

class platypus.core.MaxTime(max_time)

Termination condition based on the maximum elapsed time.

Parameters

max_timefloat

The duration, in seconds, to run the algorithm.

initialize(algorithm)

Initializes this termination condition.

This method is called once at the start of a run, and should be used to record any initial state. Also consider that users can call run multiple times, where each invocation continues the execution of the run from where it left off.

Parameters

algorithmAlgorithm

The algorithm instance.

shouldTerminate(algorithm)

Checks if the algorithm should terminate.

This method is called after each iteration. The defintion of one “iteration” in specific to each algorithm. For example, a generational algorithm typically produces and evaluates multiple offspring each iteration. Consequently, a run might not stop exactly where the termination condition indicates.

Parameters

algorithmAlgorithm

The algorithm instance.

Returns

True if the termination condition is satisfied and the run should stop; False otherwise.

class platypus.core.Mutation

Abstract class for mutation operators.

Mutation is just a special Variator with an arity of 1. While not required, mutation operators typically also produce a single offspring.

evolve(parents)

Evolves the parents to produce offspring.

Parameters

parentslist of Solution

The parent solutions.

Returns

The offspring.

abstract mutate(parent)

Mutates the given parent.

Parameters

parentSolution

The parent to mutate.

Returns

The offspring.

class platypus.core.ParetoDominance

Pareto dominance with constraints.

If either solution violates constraints, then the solution with a smaller constraint violation is preferred. If both solutions are feasible, then Pareto dominance is used to select the preferred solution.

compare(solution1, solution2)

Compare two solutions for dominance.

Parameters

solution1Solution

The first solution.

solution2Solution

The second solution.

Returns

-1 if the first solution dominates the second, 1 if the second solution dominates the first, or 0 if the two solutions are mutually non-dominated.

class platypus.core.Problem(nvars, nobjs, nconstrs=0, function=None)

Class representing a problem.

Attributes

nvars: int

The number of decision variables

nobjs: int

The number of objectives.

nconstrs: int

The number of constraints.

function: callable

The function used to evaluate the problem. If no function is given, it is expected that the evaluate method is overridden.

types: FixedLengthArray of Type

The type of each decision variable. The type describes the bounds and encoding/decoding required for each decision variable.

directions: FixedLengthArray of int

The optimization direction of each objective, either MINIMIZE (-1) or MAXIMIZE (1)

constraints: FixedLengthArray of Constraint

Describes the types of constraints as an equality or inequality. The default requires each constraint value to be 0.

evaluate(solution)

Evaluates the problem.

By default, this method calls the function passed to the constructor. Alternatively, a problem can subclass and override this method. When overriding, this method is responsible for updating the objectives and constraints stored in the solution.

Parameters

solution: Solution

The solution to evaluate.

class platypus.core.Selector

Abstract class for selection operators.

select(n, population)

Selects N members from the population.

This default implementation operates “with replacement”, meaning solutions can be selected multiple times. Subclasses are allowed to modify this behavior.

Parameters

nint

The number of solutions to select from the population.

population: list of Solution

The population of solutions.

abstract select_one(population)

Selects a single member from the population.

Parameters

population: list of Solution

The population of solutions.

class platypus.core.Solution(problem)

Class representing a solution to a problem.

Parameters

problem: Problem

The problem.

Attributes

variables: FixedLengthArray of objects

The values of the variables.

objectives: FixedLengthArray of float

The values of the objectives. These values will only be assigned after the solution is evaluated.

constraints: FixedLengthArray of float

The values of the constraints. These values will only be assigned after the solution is evaluated.

constraint_violation: float

The magnitude of the constraint violation.

feasible: bool

True if the solution does not violate any constraints; False otherwise.

evaluated: bool

True if the solution is evaluated; False otherwise.

evaluate()

Evaluates this solution.

class platypus.core.TerminationCondition

Abstract class for defining termination conditions.

initialize(algorithm)

Initializes this termination condition.

This method is called once at the start of a run, and should be used to record any initial state. Also consider that users can call run multiple times, where each invocation continues the execution of the run from where it left off.

Parameters

algorithmAlgorithm

The algorithm instance.

abstract shouldTerminate(algorithm)

Checks if the algorithm should terminate.

This method is called after each iteration. The defintion of one “iteration” in specific to each algorithm. For example, a generational algorithm typically produces and evaluates multiple offspring each iteration. Consequently, a run might not stop exactly where the termination condition indicates.

Parameters

algorithmAlgorithm

The algorithm instance.

Returns

True if the termination condition is satisfied and the run should stop; False otherwise.

class platypus.core.Variator(arity)

Abstract class for variation operators (crossover and mutation).

Variation operators must not modify the parents! Instead, create a copy of the parents, set evaluated to False, and make any modifications on the copy:

child = copy.deepcopy(parent)
child.evaluated = False

Parameters

arityint

The operator arity, or number of required parents.

abstract evolve(parents)

Evolves the parents to produce offspring.

Parameters

parentslist of Solution

The parent solutions.

Returns

The offspring.

platypus.core.crowding_distance(solutions)

Calculates crowding distance for a non-dominated front.

Computes the crowding distance for a single non-dominated front. It is assumed all solutions are non-dominated. This method assigns the attribute crowding_distance to all solutions.

Parameters

solutionsiterable of Solution

The collection of solutions

platypus.core.nondominated(solutions)

Filters the solutions to only include non-dominated.

Parameters

solutionsiterable of Solution

The solutions to filter.

Returns

The non-dominated solutions.

platypus.core.nondominated_prune(solutions, size)

Prunes a population using non-dominated sorting.

Similar to nondominated_truncate, except the crowding distance is recomputed after each solution is removed.

Parameters

solutionsiterable

The collection of solutions that have been non-domination sorted

size: int

The size of the truncated result

platypus.core.nondominated_sort(solutions)

Fast non-dominated sorting.

Performs fast non-dominated sorting on a collection of solutions. The solutions will be assigned the following attributes:

  1. rank - The index of the non-dominated front containing the solution. Rank 0 stores all non-dominated solutions.

  2. crowding_distance - The crowding distance of the given solution. Larger values indicate less crowding near the solution.

Parameters

solutionsiterable of Solution

The collection of solutions

platypus.core.nondominated_sort_cmp(x, y)

Compares two solutions using nondominated sorting results.

After processing a population with nondominated_sort(), this comparison function can be used to order solutions by their rank and crowding distance.

Parameters

xSolution

The first solution.

ySolution

The second solution.

Returns

-1, 0, or 1 to indicate if x is better, equal, or worse than y based on rank and crowding distance.

platypus.core.nondominated_split(solutions, size)

Identify the front that must be truncated.

When truncating a population to a fixed size using non-dominated sorting, identify the front N that can not completely fit within the truncated result. Returns a tuple (first, last), where first contains all solutions in the first N fronts (those solutions that will definitely remain after truncation), and the last is the front that must be truncated. last can be empty.

Parameters

solutionsiterable of Solution

The collection of solutions that have been non-dominated sorted

sizeint

The size of the truncated result

platypus.core.nondominated_truncate(solutions, size)

Truncates a population using non-dominated sorting.

Truncates a population to the given size. The resulting population is filled with the first N-1 fronts. The Nth front is too large and must be split using crowding distance.

Parameters

solutionsiterable

The collection of solutions that have been non-domination sorted

size: int

The size of the truncated result

platypus.core.normalize(solutions, minimum=None, maximum=None)

Normalizes the solution objectives.

Normalizes the objectives of each solution within the minimum and maximum bounds. If the minimum and maximum bounds are not provided, then the bounds are computed based on the bounds of the solutions.

Returns the minimum and maximum bounds used for normalization along with setting the ‘normalized_objectives’ attribute on each solution.

Parameters

solutionsiterable

The solutions to be normalized.

minimumfloat list

The minimum values used to normalize the objectives.

maximumfloat list

The maximum values used to normalize the objectives.

platypus.core.truncate_fitness(solutions, size, larger_preferred=True, getter=<function fitness_key>)

Truncates a population based on a fitness value.

Truncates a population to the given size based on fitness values. By default, the attribute fitness is used, but can be customized by specifying a custom attrgetter.

Parameters

solutionsiterable

The collection of solutions that have already been assigned fitness values

sizeint

The size of the truncated result

larger_preferredbool (default True)

If larger fitness values are preferred

gettercallable (default attrgetter("fitness"))

Retrieves the fitness value from a solution