DEAP / deap

Distributed Evolutionary Algorithms in Python
http://deap.readthedocs.org/
GNU Lesser General Public License v3.0
5.87k stars 1.13k forks source link

AttributeError: 'list' object has no attribute 'fitness' #728

Closed Mehdiasr closed 1 year ago

Mehdiasr commented 1 year ago

Hello, the individual format I'm working with is ['TGCCG', 'ATGTT']. I successfully created this format using toolbox.register("attr_int", init_individual, seq_length=5) and toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_int, n=2). However, the issue arises when handling the offspring. The current format of the offspring is [['TGCCG', 'ATGTT'], ['CCTCC', 'GCATG'], ['CATAA', 'TCGGT'], ['CATAA', 'TCGGT'], ['CACGA', 'CGTGT']]. The problem occurs with the line offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb), resulting in the error AttributeError: 'list' object has no attribute 'fitness'. I have cross-checked my code with the Deap framework guidelines, and everything seems to be properly aligned. However, I am unable to discern why this error is occurring. Thanks for your help.

fmder commented 1 year ago

Verify that your crossover and mutation return Individuals? Often a small mistake will make them return lists.

Le mar. 17 oct. 2023, 11 h 30, Darkestofdayss @.***> a écrit :

Hello, the individual format I'm working with is ['TGCCG', 'ATGTT']. I successfully created this format using toolbox.register("attr_int", init_individual, seq_length=5) and toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_int, n=2). However, the issue arises when handling the offspring. The current format of the offspring is [['TGCCG', 'ATGTT'], ['CCTCC', 'GCATG'], ['CATAA', 'TCGGT'], ['CATAA', 'TCGGT'], ['CACGA', 'CGTGT']]. The problem occurs with the line offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb), resulting in the error AttributeError: 'list' object has no attribute 'fitness'. I have cross-checked my code with the Deap framework guidelines, and everything seems to be properly aligned. However, I am unable to discern why this error is occurring. Thanks for your help.

— Reply to this email directly, view it on GitHub https://github.com/DEAP/deap/issues/728, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHKXQSNRAHR62BSI3643JTX72QDFAVCNFSM6AAAAAA6EBUTF2VHI2DSMVQWIX3LMV43ASLTON2WKOZRHE2DONZQG4ZDMMY . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Mehdiasr commented 1 year ago

Here are my mutation and crossover function that returns individuals Also in this format ['TGCCG', 'ATGTT']:

def custom_mutate_individual(individual, indpb):
    """
    Mutate sequences within an individual with a probability of indpb.
    """
    mutated_individual = []
    for sequence in individual:
        mutated_sequence = ""
        for nucleotide in sequence:
            if random.random() < indpb:
                # Perform a mutation
                possible_mutations = ['A', 'T', 'G', 'C']
                possible_mutations.remove(nucleotide)  # Exclude the current nucleotide
                mutated_nucleotide = random.choice(possible_mutations)
                mutated_sequence += mutated_nucleotide
            else:
                # No mutation
                mutated_sequence += nucleotide
        mutated_individual.append(mutated_sequence)
    return mutated_individual
def one_point_crossover(individual1, individual2):
    """
    Perform one-point crossover on two individuals.
    """
    # Choose a random crossover point within the range of the shortest sequence
    min_length = min(len(individual1), len(individual2))
    crossover_point = random.randint(1, min_length - 1)

    # Perform the crossover
    new_individual1 = individual1[:crossover_point] + individual2[crossover_point:]
    new_individual2 = individual2[:crossover_point] + individual1[crossover_point:]

    return new_individual1, new_individual2
fmder commented 1 year ago

Your mutation returns a list. Try to print its type just before returning.

Le mar. 17 oct. 2023, 13 h 00, Darkestofdayss @.***> a écrit :

Here are my mutation and crossover function that returns individuals Also in this format ['TGCCG', 'ATGTT']: def custom_mutate_individual(individual, indpb): """ Mutate sequences within an individual with a probability of indpb. """ mutated_individual = [] for sequence in individual: mutated_sequence = "" for nucleotide in sequence: if random.random() < indpb:

Perform a mutation

possible_mutations = ['A', 'T', 'G', 'C'] possible_mutations.remove(nucleotide) # Exclude the current nucleotide mutated_nucleotide = random.choice(possible_mutations) mutated_sequence += mutated_nucleotide else:

No mutation

mutated_sequence += nucleotide mutated_individual.append(mutated_sequence) return mutated_individual

def one_point_crossover(individual1, individual2): """ Perform one-point crossover on two individuals. """

Choose a random crossover point within the range of the shortest sequence

min_length = min(len(individual1), len(individual2)) crossover_point = random.randint(1, min_length - 1)

Perform the crossover

new_individual1 = individual1[:crossover_point] + individual2[crossover_point:] new_individual2 = individual2[:crossover_point] + individual1[crossover_point:]

return new_individual1, new_individual2

— Reply to this email directly, view it on GitHub https://github.com/DEAP/deap/issues/728#issuecomment-1766819299, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHKXQRWGMNGSFQSA6N2BF3X722SDAVCNFSM6AAAAAA6EBUTF2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWHAYTSMRZHE . You are receiving this because you commented.Message ID: @.***>

fmder commented 1 year ago

Plus it does not return a tuple of one individual.

Le mar. 17 oct. 2023, 13 h 02, François-Michel De Rainville < @.***> a écrit :

Your mutation returns a list. Try to print its type just before returning.

Le mar. 17 oct. 2023, 13 h 00, Darkestofdayss @.***> a écrit :

Here are my mutation and crossover function that returns individuals Also in this format ['TGCCG', 'ATGTT']: def custom_mutate_individual(individual, indpb): """ Mutate sequences within an individual with a probability of indpb. """ mutated_individual = [] for sequence in individual: mutated_sequence = "" for nucleotide in sequence: if random.random() < indpb:

Perform a mutation

possible_mutations = ['A', 'T', 'G', 'C'] possible_mutations.remove(nucleotide) # Exclude the current nucleotide mutated_nucleotide = random.choice(possible_mutations) mutated_sequence += mutated_nucleotide else:

No mutation

mutated_sequence += nucleotide mutated_individual.append(mutated_sequence) return mutated_individual

def one_point_crossover(individual1, individual2): """ Perform one-point crossover on two individuals. """

Choose a random crossover point within the range of the shortest

sequence min_length = min(len(individual1), len(individual2)) crossover_point = random.randint(1, min_length - 1)

Perform the crossover

new_individual1 = individual1[:crossover_point] + individual2[crossover_point:] new_individual2 = individual2[:crossover_point] + individual1[crossover_point:]

return new_individual1, new_individual2

— Reply to this email directly, view it on GitHub https://github.com/DEAP/deap/issues/728#issuecomment-1766819299, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHKXQRWGMNGSFQSA6N2BF3X722SDAVCNFSM6AAAAAA6EBUTF2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWHAYTSMRZHE . You are receiving this because you commented.Message ID: @.***>

Mehdiasr commented 1 year ago

it is because my individual itself is a list so mutate of it is going to be a list as well.

fmder commented 1 year ago

Your individual should be something inheriting from a list containing a fitness attribute. See how the individual class is created using the creator.

Le mar. 17 oct. 2023, 13 h 04, Darkestofdayss @.***> a écrit :

it is because my individual itself is a list.

— Reply to this email directly, view it on GitHub https://github.com/DEAP/deap/issues/728#issuecomment-1766826065, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHKXQSC6ZQAIC5MUFMJIYDX723CJAVCNFSM6AAAAAA6EBUTF2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWHAZDMMBWGU . You are receiving this because you commented.Message ID: @.***>

fengyangsun commented 1 year ago

Try to revise the last 1 lines of mutation to: individual[:] = mutated_individual[:] del individual.fitness.values return individual

or simply something like: mutated_individual = creator.Individual(mutated_individual) I prefer the first one and it should work.

Same thing for crossover: new_individual1 = deepcopy(individual1) new_individual2=deepcopy(individual2) : . new_individual1[:] = individual1[:crossover_point] + individual2[crossover_point:] new_individual2[:] = individual2[:crossover_point] + individual1[crossover_point:]

Hopefully it should work. If not, you may try to something like new_individual1 = creator.Individual(new_individual1)

Mehdiasr commented 1 year ago

Great! it works. Thanks a lot.