-1
population=[[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [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], [1], [3]]]    

selected_chromosomes=[[[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]]]

child1=[0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]
child2=[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1]   



def PopulationAdjustment(population, selected_chromosomes):
    for game in range(0, len(selected_chromosomes)):
        if game in selected_chromosomes[game][2]==game in population[game][2]: 
            population.remove(game)
    return population  

So the objective here is to replace the parents for the children in a population (list), my approach was to delete the parents then append the children, based on the same counter. The structure of the list is [[chromosome],[fitness],[counter]], however they are not exactly the same since I manipulated the fitness during the selection to avoid 0 probabilities.

I am trying to index the items that have the same counter and delete them from the list, then the next step would be just to append the children.

Ive been trying some different ways but I couldnt get it working properly, any thoughts on how to fix that? Also, if there is a way of replacing them directly by the children without having to perform 2 steps (remove and append) it would be aslo very welcome. Thanks!!

vferraz
  • 441
  • 4
  • 17
  • 5
    some advice: shorten these lists to make it a little easier to comprehend, also, show the output that you're trying to get (compute it manually) – Paul H Nov 17 '17 at 13:32
  • 1
    FYI, there are three lists without a name to them under `population`. – timgeb Nov 17 '17 at 13:32
  • 1
    @timgeb, my mistake, its fixed – vferraz Nov 17 '17 at 13:35
  • @PaulH Thanks for the advice! Actually the outputs are kinda formatted to look the way it should, but I need the program to work with this structure for some other reasons, unfortunately. – vferraz Nov 17 '17 at 13:44
  • I'll try to rephrase the comment by @PaulH for you: we don't understand what you want because you did not provide the expected output. Your example lists are very long. Use shorter ones and provide the expected output for those. – timgeb Nov 17 '17 at 13:59
  • Its already shortened, the population has 4 "items" , the selected_chromosomes are 2 and there are two children. The full list (population) for the program holds 144 items, in the format mentioned above. – vferraz Nov 17 '17 at 14:03

1 Answers1

1

You said "I am trying to index the items that have the same counter and delete them from the list". While that's possible, it's easier (and faster) to just build a new list that contains the chromosomes that you want to keep, unless population is huge.

We first scan the selected_chromosomes to extract their counter numbers into a set so we can look them up quickly.

population=[
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [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], [1], [3]],
]

selected_chromosomes=[
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]],
]

def population_adjustment(population, selected_chromosomes):
    # Create a set of the counter numbers to remove
    drop = {u[-1][0] for u in selected_chromosomes}

    # Copy the wanted chromosomes to a new list
    return [u for u in population if u[-1][0] not in drop]

new_pop = population_adjustment(population, selected_chromosomes)
for row in new_pop:
    print(row)

output

[[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]]
[[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [1], [3]]

If the population list is huge, or you have some other reason to keep the original list (eg, there are multiple references to it in various places), here's how to delete the unwanted lists. We have to be careful, though. Removing items from a list that you're iterating over is dangerous, since removal disturbs the indices of the remaining list items, as shown here. It's a bit like cutting a tree branch that you're sitting on. If you cut in the wrong place, Bad Things happen. ;) The simplest way is to iterate over the list in reverse.

population=[
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [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], [1], [3]],
]

selected_chromosomes=[
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]],
]

def population_adjustment(population, selected_chromosomes):
    # Create a set of the counter numbers to remove
    drop = {u[-1][0] for u in selected_chromosomes}

    # Iterate backwards over population so we can safely delete sublists
    for i in range(len(population)-1, -1, -1):
        k = population[i][-1][0]
        if k in drop:
           del population[i] 

    # Since we mutate `population` we should return `None`, as is conventional in Python.
    # This return statement isn't necessary, since `None` is the default return value,
    # but it's nice to be explicit
    return None

population_adjustment(population, selected_chromosomes)
for row in population:
    print(row)

This code produces the same output as the previous version, so I won't repeat it.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • Hey, I will try this! The thing is I have 144 chromosomes, however the number of chosen and deleted will always be 2, and it should be able to perform this during a number of iterations – vferraz Nov 17 '17 at 14:09
  • @vferraz 144 is pretty small, but it'd be noticeably slow if there were many thousands of chromosomes. But I just added a new version that uses deletion instead of rebuilding the list. – PM 2Ring Nov 17 '17 at 14:15
  • I have just tried both of them, and both seem to be fine! I guess its not a problem to delete items since I am running it for "n" iterations and I am only interested in populations P(0) and P(N), being the initial value already recorded, every time I start a new iteration I add new fitnesses and counters to the current individuals and the populations in between the process aren't useful. Thank you very much!! I am not really a programmer and Id never thought on something like this! – vferraz Nov 17 '17 at 14:22