Decsion Variable Types

Real

Real valued variables are expressed as floating-point numbers between some minimum and maximum bounds. For example, in the following, we configure the bounds as [-10, 10]:

from platypus import NSGAII, Problem, Real

def schaffer(x):
    return [x[0]**2, (x[0]-2)**2]

problem = Problem(1, 2)
problem.types[:] = Real(-10, 10)
problem.function = schaffer

algorithm = NSGAII(problem)
algorithm.run(10000)

Binary

Binary variables store a “binary string”. Traditionally, this is represented as 0 and 1, but in Platypus, it is stored as an array of False and True values. The knapsack problem demonstrates the binary representation, where an item is selected when the binary value is True. The goal, then, is to maximize the profit of the selected items while being constrained by the total capacity.

from platypus import GeneticAlgorithm, Problem, Constraint, Binary, nondominated, unique

# This simple example has an optimal value of 15 when picking items 1 and 4.
items = 7
capacity = 9
weights = [2, 3, 6, 7, 5, 9, 4]
profits = [6, 5, 8, 9, 6, 7, 3]

def knapsack(x):
    selection = x[0]
    total_weight = sum([weights[i] if selection[i] else 0 for i in range(items)])
    total_profit = sum([profits[i] if selection[i] else 0 for i in range(items)])

    return total_profit, total_weight

problem = Problem(1, 1, 1)
problem.types[0] = Binary(items)
problem.directions[0] = Problem.MAXIMIZE
problem.constraints[0] = Constraint("<=", capacity)
problem.function = knapsack

algorithm = GeneticAlgorithm(problem)
algorithm.run(10000)

for solution in unique(nondominated(algorithm.result)):
    print(solution.variables, solution.objectives)

Integer

The integer variable is a mix between Real and Binary. The variable is constructed with minimum and maximum bounds, but is internally represented as a Gray-coded binary variable. The Gray-coding ensures each adjacent integer value can be produced by a single bit mutation.

Permutation

The permutation variable creates a permutation of a list of items. That is, each item must appear in the list, but the ordering can change. Here we construct a permutaton of the numbers 0 through 10 using the range functon. However, note that the items is not limited to a list of integers, any collection of objects can be provided.

from platypus import GeneticAlgorithm, Problem, Permutation, nondominated, unique

def ordering(x):
    # x[0] is the permutation, this calculates the difference between the permutation and an ordered list
    return sum([abs(p_i - i) for i, p_i in enumerate(x[0])])

problem = Problem(1, 1)
problem.types[0] = Permutation(range(10))  # Permutation of elements [0, 1, ..., 9]
problem.function = ordering

algorithm = GeneticAlgorithm(problem)
algorithm.run(10000)

for solution in unique(nondominated(algorithm.result)):
    print(solution.variables, solution.objectives)

# Output:
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] [0]

Subset

Lastly we have the subset. Similar to the mathematical choose(n, k) operation, a subset variable represents a fixed-size selection of size k from a collection of n items.