Creating individuals on a 2D-manifold

73 views
Skip to first unread message

Julian Eßer

unread,
Mar 10, 2021, 7:07:12 AM3/10/21
to deap-users
Dear all,

Thanks for providing and maintaining this great tool! I've started two days ago and am already impressed by it's flexibility.

I would like to solve an optimization problem where the decision variables are p lists of n points with coordinates x and y each. Concretely, the individual's structure is supposed to look like: 
[[x_11, y_11], [x_12, y_12], ... [x_1n, y_1n],
[x_21, y_21], [x_22, y_22], ... [x_2n, y_2n],
....
[x_p1, y_p1], [x_p2, y_p2], ... [x_pn, y_pn]]

Currently I've successfully implemented an individual with the first row structure, i.e.
[[x_11, y_11], [x_12, y_12], ... [x_1n, y_1n]]
via:
toolbox.register("attr_x", random.uniform, 0, x_dim)
toolbox.register("attr_y", random.uniform, 0, y_dim)
toolbox.register("individual", tools.initCycle, creator.Individual,
(toolbox.attr_x, toolbox.attr_y), n)

Question: How can I extend the individual's structure to the p-dimension?

Best,
Julian





Rachel

unread,
Mar 10, 2021, 3:31:25 PM3/10/21
to deap-users
Hi Julian,

If I well understood you need a list of lists of lists like:

[[[x_11, y_11], [x_12, y_12], ... [x_1n, y_1n]],
[[x_21, y_21], [x_22, y_22], ... [x_2n, y_2n]],
....
[[x_p1, y_p1], [x_p2, y_p2], ... [x_pn, y_pn]]]


An alternative is customizing your initial individuals like this example below: 

# Create a list of individuals
creator.create("Individual", listfitness=creator.FitnessMin)

import random

# Initialize your parameters: 
x_dim = 10 
y_dim = 20

range_n = 15 # n dimension
range_p = 10 # p dimension


def initFunction(icls):

    l_length = []
    for p in range(0, range_p):
        l_width=[]
        for n in range(0, range_n): 
            ind = [random.uniform(0, x_dim), random.uniform(0, y_dim)]
            l_width.append(ind)

        l_length.append(l_width)

    return icls(l_length)

    
toolbox.register("individual", initFunction, creator.Individual)

I hope it solves your problem.

Julian Eßer

unread,
Mar 19, 2021, 1:50:39 PM3/19/21
to deap-users
Hi Rachel,

Thanks a lot for your helpful answer, this kind of customization is exactly what I was looking for.

Are there performance improvements to be expected when using "array.array"

creator.create("Individual", array.arrayfitness=creator.FitnessMin)

instead of "list" for creating the individual?

Rachel

unread,
Mar 22, 2021, 2:30:05 PM3/22/21
to deap-users
Good question. I do not know. I've never checked the difference of performance between both. 

Derek Tishler

unread,
Apr 4, 2021, 11:21:50 AM4/4/21
to deap-users
Julian,

The performance question depends on a few things I think; specifically user specific actions in particular cases will affect how awesome things perform when using array or numpy arrays.

Deap(check out numpy tutorial) allows us to register eval and operators that can then utilize an array; out of the bag I don't think you get a real performance boost with this(can check out the code in selection and other operators to see the for loops). In fact it can slow things down such as np.sign(list) may be slower than np.sign(numpy_array) due to overhead of casting and looping over many individuals in the case of eval of a list vs array.

I would treat it like a python Numba or compiled code and work with similar types to gain performance boosts. So if you can utilize numpy or array operations in your operators(eval, crossover, etc) then you can see major speed improvements when scaling up the evolution using arrays.

In this specific case/question of creating the pop: the creation of the individual may be sped up via a numpy call vs forming of a 2d list via loops(but use what you are more comfortable with unless speed is a real issue).

Example pseudocode:
creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)
def createInd(icls):
    # return 2d array of random uniform in range
    return icls( numpy.random.uniform(low=0, high=x_dim, size=(y_dim, x_dim)) )

def eval(ind):
    # Reduce the 2d array to a single fitness via np ops
    return np.sum(ind.axis=1).mean(), 


Docs:
https://deap.readthedocs.io/en/master/tutorials/advanced/numpy.html
https://deap.readthedocs.io/en/master/examples/ga_onemax_numpy.html
Reply all
Reply to author
Forward
0 new messages