web-dev-qa-db-fra.com

TypeError: '<' non pris en charge entre les instances Python

Je résous un problème d'algorithme génétique dans python 3. Je n'ai pas encore terminé le code complet. Je teste une partie du code chaque fois que je le termine.

À l'heure actuelle, je suis coincé dans une erreur en disant:

TypeError: '<' non pris en charge entre les instances de 'part' et 'part'

La chose intéressante que cette erreur ne montre pas toujours. Parfois, le code s'exécute correctement et affiche la sortie souhaitée, mais parfois il affiche cette erreur.

Quelle en est la raison? Aidez-moi, s'il vous plaît. J'attache le code et le message d'erreur. J'utilise PyCharm.

import random


class part():
    def __init__(self, number):
        self.number = number
        self.machine_sequence = []

    def add_volume(self, volume):
        self.volume = volume

    def add_machine(self, machine_numbers):
        self.machine_sequence.append(machine_numbers)


def create_initial_population():
    part_family = []

    for i in range(8):
        part_family.append(part(i))

    part_population = []

    for i in range(6):
        part_population.append(random.sample(part_family, len(part_family)))

    for i in part_population:
        for j in i:
            j.add_volume(random.randrange(100, 200))

    return part_population


def fitness(part_family):
    sum_of_boundary = []
    for i in range(0, 8, 2):
        sum_of_boundary.append(sum(j.volume for j in part_family[i:i + 2]))

    fitness_value = 0

    for i in range(len(sum_of_boundary) - 1):
        for j in range(i + 1, len(sum_of_boundary)):
            fitness_value = fitness_value + abs(sum_of_boundary[i] - sum_of_boundary[j])

    return fitness_value


def sort_population_by_fitness(population):
    pre_sorted = [[fitness(x),x] for x in population]
    sort = [x[1] for x in sorted(pre_sorted)]
    for i in sort:
        for j in i:
            print(j.volume, end = ' ')
        print()

    return sort


def evolve(population):
    population = sort_population_by_fitness(population)
    return population


population = create_initial_population()
population = evolve(population)

le message d'erreur: enter image description here

La sortie est (qui est randomisée à chaque fois): enter image description here

12
Zaidur

Étant donné que pre_sorted Est une liste de listes avec des éléments [fitness, part], Cela coince chaque fois que l'on compare deux sous-listes avec le même fitness.

Les listes Python sont triées lexicographiquement et sont comparées élément par élément de gauche à droite jusqu'à ce qu'un élément non concordant soit trouvé. Dans votre cas, le deuxième élément (part) n'est accessible que si l'adéquation de deux parties est la même.

  • [0, part0] < [1, part1] => Ne compare pas part0 Et part1 Car la forme physique est déjà différente.
  • [0, part0] < [0, part1] => compare part0 Et part1 Car la forme physique est la même.

Suggestion 1:

Trier uniquement par forme physique: sorted(pre_sorted, key=operator.itemgetter(0))

Suggestion 2: Lisez la documentation pour functools.total_ordering donnez à part une commande totale:

@total_ordering
class part():
    [...]

    def __lt__(self, other):
        return self.number < other.number.

Et oui, le tri des listes de listes semble faux. Les éléments internes peuvent être des tuples, vous ne pouvez donc pas modifier accidentellement le contenu.

17
dhke

Donc pre_sorted Est une liste avec des éléments de [int, part]. Lorsque vous triez cette liste et que vous avez deux éléments avec la même valeur entière, il compare ensuite les valeurs part pour essayer de déterminer lequel va en premier. Cependant, certains vous n'avez aucune fonction pour déterminer si une pièce est inférieure à une pièce, jette cette erreur.

Essayez d'ajouter une fonction __le__(self, other) pour commander des pièces.

Plus d'informations sur les opérateurs ici

2
fuzzything44