Search code examples
pythonoptimizationdeap

python - Multi-Objective optimization with multiple variables using DEAP


I am trying to optimize two outputs of simulation software (I used random forest to train a model for fast prediction of outputs). There are seven input variables three are continuous, and the rest are discrete. I have used DEAP package for multi-objective optimization but only one variable or a set of related variables (something like knapsack). The mentioned seven variables are:

    n_rate = [0.1:0.5]
    estim = [1000, 1500, 2000]
    max_d = [1:20]
    ft = [None, "rel"]
    min_s = [2:1000]
    min_m = [1:1000]
    lim = [0:1]

Except ft, for all continues variables, it is possible to define several discrete numbers.

My question is how I can create different individuals for these inputs to define the population?


Solution

  • the way that you do this is by registering "attributes" that each individual can be created from. Here is what I use in my code:

    toolbox.register("attr_peak", random.uniform, 0.1,0.5)
    toolbox.register("attr_hours", random.randint, 1, 15)
    toolbox.register("attr_float", random.uniform, -8, 8)
    
    toolbox.register("individual", tools.initCycle, creator.Individual,
                     (toolbox.attr_float,toolbox.attr_float,toolbox.attr_float,
                      toolbox.attr_hours,
                      toolbox.attr_float, toolbox.attr_float, toolbox.attr_float,
                      toolbox.attr_hours,toolbox.attr_peak
                      ), n=1)
    

    In my code, I have three different "genes" or "attributes" as I have them registered in toolbox. In my example, I have two continuous variables and one integer constrained variable. For your example, this is how you would define your attributes:

    toolbox.register("n_rate", random.uniform, 0.1, 0.5)
    toolbox.register("estim", random.choice, [1000,1500,2000])
    toolbox.register("max_d", random.randint, 1, 20)
    toolbox.register("ft", random.choice, [None, 'rel'])
    toolbox.register("min_m", random.randint, 1, 1000)
    toolbox.register("min_s", random.randint, 2, 1000)
    toolbox.register("lim", random.randint, 0, 1)
    

    Then you would construct your individual similarly to how I have with initCycle.

    toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.your_attribute, toolbox.next_attribute, ... ), n=1)