質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

446閲覧

比較対象のデータ型が異なるという理由でリストのソードができない。

AI_engineer

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/05/25 04:53

編集2022/11/14 19:30

質問

オライリージャパン『集合知プログラミング』11章のサンプルコードがうまく実行できません。
遺伝的プログラミングを使って得られたランダムな座標から関数を同定するプログラムを組んでいます。
関数を500個作成後、それぞれの関数のスコアを算出し要素数500のリストを作ったのですが、そのスコアのリストをソートすることができずに困っています。
どなたかご教授お願いいたします。

再質問

エラーを取り除くことができましたが、原因を知りたいのでご教授下さい。
scoresがタプルのリストになっていたのでrankfunction関数(176行目)の
scores.sort(key = lambda x: x[0])
とするとエラーを解消することができましたが、これはタプル型のどの要素でソートするかを明示していなかったためエラーが出ていたという解釈でよろしいでしょうか。

実現したいこと

スコアのリストをソートする際のエラーを解消したい。

発生している問題・エラーメッセージ

Traceback (most recent call last): File "g:\M1\code\gp\sample_gp.py", line 198, in <module> print(evolve(2, 500, rf, mutationrate=0.2, breedingrate=0.1, pexp=0.7, pnew=0.1)) File "g:\M1\code\gp\sample_gp.py", line 152, in evolve scores = rankfunction(population) File "g:\M1\code\gp\sample_gp.py", line 175, in rankfunction scores.sort() TypeError: '<' not supported between instances of 'node' and 'constnode'

該当のソースコード

python

1from random import random, randint, choice 2from copy import deepcopy 3from math import log 4 5class fwrapper: 6 def __init__(self, function, childcount, name): 7 self.function = function 8 self.childcount = childcount 9 self.name = name 10 11# ノードのクラス 12class node: 13 def __init__(self, fw, children): 14 self.function = fw.function 15 self.name = fw.name 16 self.children = children 17 18 def evaluate(self, inp): 19 results = [n.evaluate(inp) for n in self.children] 20 return self.function(results) 21 22 def display(self, indent=0): 23 print(' '*indent + self.name) 24 for c in self.children: 25 c.display(indent+1) 26 27# 変数ノードのクラス 28class paramnode: 29 def __init__(self, idx): 30 self.idx = idx 31 32 def evaluate(self, inp): 33 return inp[self.idx] 34 35 def display(self, indent=0): 36 print('{}p{}'.format(' '*indent, self.idx)) 37 38# 定数ノードのクラス 39class constnode: 40 def __init__(self, v): 41 self.v = v 42 43 def evaluate(self, inp): 44 return self.v 45 46 def display(self, indent=0): 47 print('{}{}'.format(' '*indent, self.v)) 48 49addw = fwrapper(lambda l: l[0] + l[1], 2, 'add') 50subw = fwrapper(lambda l: l[0] - l[1], 2, 'subtract') 51mulw = fwrapper(lambda l: l[0] * l[1], 2, 'multiply') 52 53def iffunc(l): 54 if l[0] > 0: 55 return l[1] 56 else: 57 return l[2] 58 59ifw = fwrapper(iffunc, 3, 'if') 60 61def isgreater(l): 62 if l[0] > l[1]: 63 return 1 64 else: 65 return 0 66 67gtw = fwrapper(isgreater, 2, 'isgreater') 68flist = [addw, mulw, ifw, gtw, subw] 69 70def exampletree(): 71 return node(ifw, [ 72 node(gtw, [paramnode(0), constnode(3)]), 73 node(addw, [paramnode(1), constnode(5)]), 74 node(subw, [paramnode(1), constnode(2)]) 75 ]) 76 77# 最初の集団をランダムに作成 78def makerandomtree(pc, maxdepth=4, fpr=0.5, ppr=0.6): # pc: 入力変数の数 79 if random() < fpr and maxdepth > 0: 80 f = choice(flist) 81 children = [makerandomtree(pc, maxdepth-1, fpr, ppr) for i in range(f.childcount)] 82 return node(f, children) 83 elif random() < ppr: 84 return paramnode(randint(0, pc-1)) 85 else: 86 return constnode(randint(0, 10)) 87 88def hiddenfunction(x, y): 89 return x**2 + 2*y + 3*x + 5 90 91def buildhiddenset(): 92 rows = [] 93 for i in range(200): 94 x = randint(0, 40) 95 y = randint(0, 40) 96 rows.append([x, y, hiddenfunction(x, y)]) 97 return rows 98 99def scorefunction(tree, s): 100 dif = 0 101 for data in s: 102 v = tree.evaluate([data[0], data[1]]) 103 dif += abs(v-data[2]) 104 return dif 105 106# 突然変異 107def mutate(t, pc, probchange=0.1): 108 # 部分木を突然変異させる 109 if random() < probchange: 110 return makerandomtree(pc) 111 # 突然変異させる部分木を決定する(木に潜っていく) 112 else: 113 result = deepcopy(t) 114 if hasattr(t, "children"): 115 result.children = [mutate(c, pc, probchange) for c in t.children] 116 return result 117 118# 交叉(t1とt2同時に潜っていく) 119def crossover(t1, t2, probswap=0.7, top=1): 120 if random() < probswap and not top: 121 return deepcopy(t2) 122 else: 123 result = deepcopy(t1) 124 if hasattr(t1, 'children') and hasattr(t2, 'children'): 125 result.children = [crossover(c, choice(t2.children), probswap, 0) for c in t1.children] 126 return result 127 128def evolve(pc, popsize, rankfunction, maxgen=500, mutationrate=0.1, breedingrate=0.4, pexp=0.7, pnew=0.05): 129 """_summary_ 130 131 Args: 132 pc (_type_): _description_ 133 popsize (_type_): 初期集団のサイズ. 134 rankfunction (_type_): プログラムのリストに対して用いられ、ベストからワーストの順にランク付けする関数 135 maxgen (int, optional): _description_. Defaults to 500. 136 mutationrate (float, optional): 突然変異を起こす確率. mutateに渡される. Defaults to 0.1. 137 breedingrate (float, optional): 交叉を行う確率. crossoverに渡される. Defaults to 0.4. 138 pexp (float, optional): ランクの低いプログラムが選ばれない確率. 値が高ければ高いほど,選択は厳格なものとなり,ランクの高いもののみが複製のために選ばれるようになる. Defaults to 0.7. 139 pnew (float, optional): 新たな集団を作るとき,完全に新しいランダムなプログラムが作られる確率. Defaults to 0.05. 140 141 Returns: 142 _type_: _description_ 143 """ 144 145 # ランダムな低い数値を返す。pexpが低ければ低いほど得られる数値は小さくなる 146 def selectindex(): 147 return int(log(random())/log(pexp)) 148 149 # 初期集団をランダムに作り上げる 150 population = [makerandomtree(pc) for i in range(popsize)] 151 for i in range(maxgen): 152 scores = rankfunction(population) 153 print(scores[0][0]) 154 if scores[0][0] == 0: break 155 156 # 上位2つは無条件に採用 157 newpop = [scores[0][1], scores[1][1]] 158 159 # 次世代を作る 160 while len(newpop) < popsize: 161 if random() > pnew: 162 newpop.append(mutate(crossover(scores[selectindex()][1], scores[selectindex()][1], probswap=breedingrate), pc, probchange=mutationrate)) 163 else: 164 # ランダムなノードを混ぜる 165 newpop.append(makerandomtree(pc)) 166 167 population=newpop 168 scores[0][1].display() 169 return scores[0][1] 170 171# データセットのランキングを行う関数を返す 172def getrankfunction(dataset): 173 def rankfunction(population): 174 scores = [(scorefunction(t, dataset), t) for t in population] 175 scores.sort() 176 return scores 177 return rankfunction 178 179rf = getrankfunction(buildhiddenset()) 180print(evolve(2, 500, rf, mutationrate=0.2, breedingrate=0.1, pexp=0.7, pnew=0.1))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AI_engineer

2022/05/25 05:08

scoresがタプルのリストになっていたので rankfunction関数(176行目)の scores.sort(key = lambda x: x[0]) とするとエラーを解消することができましたが、これはタプル型のどの要素でソートするかを明示していなかったためエラーが出ていたという解釈でよろしいでしょうか。
ozwk

2022/05/25 05:08

質問文は編集できます
guest

回答1

0

これはタプル型のどの要素でソートするかを明示していなかったためエラーが出ていたという解釈でよろしいでしょうか。

いいえ、タプルのリストであってもソートはできます。
実証コードです:

python

1ls=[(1,2),(3,4),(1,3)] 2ls.sort() 3print(ls) # [(1, 2), (1, 3), (3, 4)]

エラーの原因はメッセージ

TypeError: '<' not supported between instances of 'node' and 'constnode'

にあるように、nodeクラスとconstnodeクラスの間に<演算子が定義されていないからです。
ただし、解決策としては、「スコアでソートするように指定する」で良いと思います。

投稿2022/05/25 05:45

ozwk

総合スコア13512

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問