Given this dictionary:
gene_space = [
{"name": "length",'high':110,'low':10,'step':10},
{"name": "emaLength",'high':34,'low':1,'step':2},
{"name": "averageLength",'high':110,'low':10,'step':10},
{"name": "factor",'high':0.5,'low':0.02,'step':0.02},
{"name": "criticalValue",'high':60,'low':-50,'step':10},
]
...how can I create a population of genes that are randomly selected among those ranges so that they can be used with Deap?
You can see my attempts below:
# Define a maximizing fitness function
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
# We'll create a list of the current population
creator.create("Individual", list, fitness=creator.FitnessMax)
# Create toolbox instance
toolbox = base.Toolbox()
list_of_attrs = []
# Iterate through the gene space
for i in range(len(gene_space)):
# Register the current gene attribute (by name), which is just a np.arange between low and high, steping each way
# Attempt 1 - Doesn't work as the "population" later is just the actual ranges, not selections from the range
# toolbox.register(gene_space[i]["name"], np.arange, gene_space[i]['low'], gene_space[i]['high'], gene_space[i]['step'])
# Attempt 2 - Getting better, however this now only selects 1 random choice for the population, and I want more.
# Defined n=10 below, but doesn't work?
# toolbox.register(gene_space[i]["name"], random.choice, np.arange(gene_space[i]['low'], gene_space[i]['high'], gene_space[i]['step']))
# Attempt 3 - Tried to make several random selections which is more in line with what I want, but get the error:
# TypeError: Population must be a sequence or set. For dicts, use list(d).
toolbox.register(gene_space[i]["name"], random.sample, np.arange(gene_space[i]['low'], gene_space[i]['high'], gene_space[i]['step']), 10)
list_of_attrs.append(gene_space[i]["name"])
# Register the individual (full of the attributes)
toolbox.register("individual", tools.initCycle, creator.Individual, (getattr(toolbox, key) for key in list_of_attrs), n=10) # n=10 here does nothing?
# Now register the population
toolbox.register("population", tools.initRepeat, list, toolbox.individual, n=10)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.1)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", evaluate)
I need the population to be the same class type that Deap uses from their examples. I've modified their "main" algorithm to generate the population I need as a list of lists, but then it runs into more errors later because then each gene is just a list, and not a deap class object. Hoping to resolve this using one of the attempts above before I start re-coding a new main method.
Looks like the way to do this is like so (inspiration taken from here):
dataset = []
for _ in range(300):
current_chromosome = []
for j in range(len(gene_space)):
current_chromosome.append(random.choice(np.arange(gene_space[j]['low'], gene_space[j]['high'], gene_space[j]['step'])))
dataset.append(current_chromosome)
# toolbox.register("random_sampling", random.sample, dataset, 1)
toolbox.register("random_sampling", lambda x,y: random.sample(x,y)[0], dataset, 1)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.random_sampling)