2

firs of all I apologize if my approach is too dumb or simplistic, I am an economist trying very hard to get into programming, therefore I lack some specific skills. Anyways, I have the following code:

population = [[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [1], [0]],
 [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]],
 [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]],
 [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [3], [3]]]

def ProbabilityList(population):
    fitness = chromosome[2] for chromosome in population
    manipulated_fitness = fitness + 1
    total_weight=sum(manipulated_fitness)
    relative_fitness= [chromosome[1]/total_weight for chromosome in population]
    probabilities= [sum(relative_fitness) for i in range(len(relative_fitness))]
    return (probabilities)

The logic of the population is [[[individual1],[fitness][counter]],[individual3],[fitness][counter]], and so on... the counter is just a number so I can order the individuals.

So what I need in this case is to create a selection probability list based on the total fitness. I also need to add 1 to the basic fitness, since in the future the value might be zero and I cant use a deterministic selection method (that is, no individuals can have 0 probabilities)

Would anyone know a correct approach to deal with it like this?

Håken Lid
  • 22,318
  • 9
  • 52
  • 67
vferraz
  • 441
  • 4
  • 17
  • `fitness = chromosome[2] for chromosome in population` what is this means ? What is the logic for assigning fitness ? – Sandeep Lade Nov 04 '17 at 18:57
  • It means that its the second item inside the individual list, actually its supposed to be [1], I will fix it. Is the logic for assigning it relevant? Because its part of something else – vferraz Nov 04 '17 at 19:40
  • do you mean you want to select a member of your population at random, but with higher likelihood if the member's fitness is higher? – Johannes Wachs Nov 04 '17 at 19:58
  • @JohannesWachs, exaclty, from what I understood this have to be broken down into 2 parts, first generating probabilities and second create a selection function, this would be the first part. – vferraz Nov 04 '17 at 19:59

1 Answers1

1

One library you might consider is numpy which has a function that does exactly what you are asking for: A weighted version of random.choice

Edit: here is one way to do it based on your code.

from numpy.random import choice    
def ProbabilityList(population):
    #manipulated fitness in one line
    manipulated_fitness = [chromosome[1]+1 for chromosome in population]
    total_weight=sum(manipulated_fitness)
    #define probabilities - note we should use +1 here too otherwise we won't get a proper distribution
    relative_fitness= [(chromosome[1]+1)/total_weight for chromosome in population]
    #get a list of the ids
    ids = [chromosome[2] for chromosome in population]
    #choose one id based on their relative fitness
    draw = choice(ids, 1, p=relative_fitness)
    #return your choice
    return draw
    #if you want to return the probability distribution you can just return relative_fitness

Let me also make two suggestions for slightly more complicated data structures/methods you could read about that may make your life a bit easier: dictionaries or classes.

Edit: What I meant by this is to do something like:

chromosome_dict={id1:{fitness:4,chromosome:[0,1,1,1,0]},
                 id2:{fitness:3,chromosome:[0,0,0,1,1]}}

This is not for any computational reason, but because it would be easier to read and manipulate.

Johannes Wachs
  • 1,270
  • 11
  • 15
  • I tried creating a dictionary for the items above, like {"0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1":1}, so I can map the number inside the lists, because I really think the problem is that I cant index the numbers into this list structure properly, anyways I also couldnt make it work – vferraz Nov 04 '17 at 20:29
  • @vferraz: If you have another problem, you should submit a new question. – Håken Lid Nov 12 '17 at 18:42