2017-04-18 16 views
4

私はpythonで遺伝的アルゴリズムの問​​題を解決しています。私は完全なコードをまだ完成させていません。私はコードを完成するたびにテストします。TypeError: '<'はインスタンス間でサポートされていませんPython

TypeError: '<' not supported between instances of 'part' and 'part'

興味深いのは、このエラーが常に表示されません。

は、現時点では私はというエラーで立ち往生しています。コードがスムーズに実行され、目的の出力が表示されることがありますが、時にはこのエラーが表示されることがあります。

この理由は何ですか?私を助けてください。私はコードとエラーメッセージを添付しています。私は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) 

エラーメッセージ:(毎回ランダム化されている)が出力される enter image description here

:比較するたび enter image description here

+0

私は(https://conemu.github.io/)[コピーすることができますコマンドプロンプト]あなたがダウンロードして使用することをお勧めすることはできますので、あなたの質問に不要なスクリーンショットを追加する必要はありません。 –

答えて

6

pre_sorted項目[fitness, part]とリストのリストがあることを考えると、これはcroaks 2つのサブリストは同じfitnessです。

Pythonは辞書的に並べ替えを並べ替え、不一致要素が見つかるまで要素の左から右に比較されます。あなたの場合、2番目の要素(part)は、2つの部分の適合度が同じ場合にのみアクセスされます。

  • [0, part0] < [1, part1] =>フィットネスはすでに異なるためpart0part1を比較しません。
  • [0, part0] < [0, part1] =>part0part1は、適応度が同じであるためです。のリストをソートする

    @total_ordering 
    class part(): 
        [...] 
    
        def __lt__(self, other): 
         return self.number < other.number. 
    

    そして、ええ、:sorted(pre_sorted, key=operator.itemgetter(0))

    提言2:functools.total_orderingは全順序をpart与えるためのドキュメントを読む

提案1:ソートのみ適応することにより

リストが間違っているようです。内側の要素はタプルの方が良いかもしれないので、内容を誤って変更することはできません。

+0

ありがとうございました!できます! しかし、operator.itemgetter(0)を使用して最初の要素fitnessのみを比較すると、同じフィットネスがある場合、どのようなpythonが行いますか?選択する要素は? – Zaidur

+0

@Zaidur 'sort()'は安定しています。つまり、2つの要素を比較すると元の順序が保持されます。ただし、直前にランダムサンプリングを使用して母集団を作成したことに注意してください。 – dhke

2

したがってpre_sortedは、要素が[int, part]のリストです。このリストをソートし、同じ整数値を持つ2つの要素を持つ場合は、partの値を比較して、どちらが最初になるかを判断します。しかし、一部の部品が部品よりも小さいかどうかを判断する機能を持たないユーザーもいれば、そのエラーがスローされます。

部品を注文するには__le__(self, other)ファンクションを追加してください。

More on operators here

関連する問題