修正:『マッチ箱の脳』人工知能ジェネテックアルゴリズムをPythonでやってみた - 牌語備忘録 - pygoの最後に乗せてた失敗版のコードをエントリーばらした。
『Rubyで書いてみた〜人工知能ジェネテックアルゴリズム - 牌語備忘録 - pygo』をやるときにPythonのコードを読み返したら、いろいろ修正したくなったのでやってみた
- クラスでやってみた
- 無駄にながいとこ若干短く
- 変数名とか解りやすく?
- 汎用性?
- 処理終了時の表示を若干変更
#!/usr/bin/env python # *-# -*- coding: utf-8 -*- # Genetic Algorithm # ga2.py import random class GeneticAlgorithm: def matchbox(self, num = 10, to_kind = 3): return [random.randint(1, to_kind) for n in range(num)] def amount_of_box(self, amount = 10): return [self.matchbox() for count in range(amount)] def del_repetition_new_add(self, amount_of_box_seq): amount = len(amount_of_box_seq) set_tuple = set(map(tuple,amount_of_box_seq)) tuple_to_lst = map(list, set_tuple) lst_len = len(tuple_to_lst) if lst_len < 10: return tuple_to_lst + self.amount_of_box(amount - lst_len) return amount_of_box_seq def rating(self, ans, amount_of_box_seq, point = 10): score_lst = [] for box in amount_of_box_seq: score = 0 for a, b in zip(ans, box): if a == b: score += point score_lst.append([score, box]) return sorted(score_lst, reverse = True) def parent(self, rate_seq): return [rate_seq[0][1], rate_seq[1][1]] def mutation(self, kids_seq): p = random.randint(0, len(kids_seq)) if p < 10: change = lambda x:x + 1 if x < 3 else x - 2 kids_seq[p] = change(kids_seq[p]) return kids_seq def recombination(self, parent_seq): amount_of_stick = len(parent_seq[0]) crossing = random.randint(0, amount_of_stick) kid_a = parent_seq[1][:crossing] + parent_seq[0][crossing:] kid_b = parent_seq[0][:crossing] + parent_seq[1][crossing:] return [self.mutation(kid_a), self.mutation(kid_b)] def answer_display(self, ans, limit_count = 200): log = [] all_box = self.amount_of_box() for count in range(1, limit_count + 1): non_repetition_seq = self.del_repetition_new_add(all_box) rate_seq = self.rating(ans, non_repetition_seq)[:] log.append("Generation: %d" % (count)) log.append("\n".join(["%d %s" % (score, lst) for score, lst in rate_seq])) all_box = [lst for scor, lst in rate_seq] parent_seq = self.parent(rate_seq) top = all_box[:2] tail = all_box[2:-2] all_box = self.recombination(parent_seq) + tail + top if rate_seq[0][0] == 100: log.append('\nAI: "The answer is %s !" (%d generations)' % (rate_seq[0][1], count)) break else: log.append("\nbreak: exceeded %d generations of the upper limit." % count) return "\n".join(log) if __name__ == "__main__": answer = [3, 1, 2, 2, 2, 3, 1, 3, 2, 1] ga = GeneticAlgorithm() #test #print ga.matchbox() #print ga.amount_of_box() #print ga.del_repetition_new_add(ga.amount_of_box()) #print ga.rating(answer, ga.amount_of_box()) #print ga.parent(ga.rating(answer, ga.amount_of_box())) #print ga.mutation([3, 1, 2, 2, 2, 3, 1, 3, 2, 1]) #print ga.recombination(ga.parent(rate_lst)) print ga.answer_display(answer)