Search code examples
pythonpython-3.xnumpygenetic-algorithmpython-itertools

Matrix of variable size [i x j] (Python, Numpy)


I am attempting to build a simple genetic algorithm that will optimize to an input string, but am having trouble building the [individual x genome] matrix (row n is individual n's genome.) I want to be able to change the population size, mutation rate, and other parameters to study how that affects convergence rate and program efficiency.

This is what I have so far:

import random
import itertools
import numpy as np
def evolve():


goal                = 'Hello, World!'                           #string to optimize towards
ideal = list(goal)

#converting the string into a list of integers
for i in range (0,len(ideal)):
    ideal [i]       = ord(ideal[i])


print(ideal)
popSize             = 10                                        #population size
genome              = len(ideal)                                #determineing the length of the genome to be the length of the target string
mut                 = 0.03                                      #mutation rate
S                   = 4                                         #tournament size
best                = float("inf")                              #initial best is very large
maxVal              = max(ideal)
minVal              = min(ideal)
print (maxVal)
i                   = 0                                         #counting variables assigned to solve UnboundLocalError
j                   = 0

print(maxVal, minVal)


#constructing initial population array (individual x genome)
pop = np.empty([popSize, len(ideal)])
for i, j in itertools.product(range(i), range(j)):
    pop[i, j] = [i, random.randint(minVal,maxVal)]
print(pop)

This produces a matrix of the population size with the correct genome length, but the genomes are something like:

[  6.91364167e-310   6.91364167e-310   1.80613009e-316   1.80613009e-316
5.07224590e-317   0.00000000e+000   6.04100487e+151   3.13149876e-120
1.11787892e+253   1.47872844e-028   7.34486815e+223   1.26594941e-118
7.63858409e+228]

I need them to be random integers corresponding to random ASCII characters .

What am I doing wrong with this method? Is there a way to make this faster?

I found my current method here: building an nxn matrix in python numpy, for any n

I found another method that I do not understand, but seems faster and simper, if I can use it here I would like to. Initialise numpy array of unknown length

Thank you for any assistance you can provide.


Solution

  • Your loop isn't executing because i and j are both 0, so range(i) and range(j) are empty. Also you can't assign a list [i,random] to an array value (np.empty defaults to np.float64). I've simply changed it to only store the random number, but if you really want to store a list, you can change the creation of pop to be pop = np.empty([popSize, len(ideal)],dtype=list)

    Otherwise use this for the last lines:

    for i, j in itertools.product(range(popSize), range(len(ideal))):
        pop[i, j] = random.randint(minVal,maxVal)