Skip to content

Commit

Permalink
Changes to be committed:
Browse files Browse the repository at this point in the history
	new file:   TSP/GA.py
	new file:   TSP/Life.py
	new file:   TSP/tsp_ga.py
	new file:   os_test.py
	modified:   plt/plt_basic.py
	deleted:    py_plt.py
	new file:   pylintrc
  • Loading branch information
transcendentsky committed Jul 6, 2018
1 parent 1403cdb commit 7061f25
Show file tree
Hide file tree
Showing 7 changed files with 682 additions and 77 deletions.
100 changes: 100 additions & 0 deletions TSP/GA.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# -*- coding: utf-8 -*-

"""GA.py
遗传算法类
"""

import random
from Life import Life


class GA(object):

def __init__(self, x_rate=0.7, mutation_rate=0.005, life_count=50, gene_length=100, judge=lambda lf, av: 1,
save=lambda: 1, mk_life=lambda: None, x_func=None, m_func=None):
self.x_rate = x_rate
self.mutation_rate = mutation_rate
self.mutation_count = 0
self.generation = 0
self.lives = []
self.bounds = 0.0 # 得分总数
self.best = None
self.life_count = life_count
self.gene_length = gene_length
self.__judge = judge
self.save = save
self.mk_life = mk_life # 默认的产生生命的函数
self.x_func = (x_func, self.__x_func)[x_func == None] # 自定义交叉函数
self.m_func = (m_func, self.__m_func)[m_func == None] # 自定义变异函数

for i in range(life_count):
self.lives.append(Life(self, self.mk_life()))

def __x_func(self, p1, p2):
# 默认交叉函数
r = random.randint(0, self.gene_length)
gene = p1.gene[0:r] + p2.gene[r:]
return gene

def __m_func(self, gene):
# 默认突变函数
r = random.randint(0, self.gene_length - 1)
gene = gene[:r] + ("0", "1")[gene[r:r] == "1"] + gene[r + 1:]
return gene

def __bear(self, p1, p2):
# 根据父母 p1, p2 生成一个后代
r = random.random()
if r < self.x_rate:
# 交叉
gene = self.x_func(p1, p2)
else:
gene = p1.gene

r = random.random()
if r < self.mutation_rate:
# 突变
gene = self.m_func(gene)
self.mutation_count += 1

return Life(self, gene)

def __get_one(self):
# 根据得分情况,随机取得一个个体,机率正比于个体的score属性
r = random.uniform(0, self.bounds)
for lf in self.lives:
r -= lf.score;
if r <= 0:
return lf

def __new_child(self):
# 产生新的后代
return self.__bear(self.__get_one(), self.__get_one())

def judge(self, f=lambda lf, av: 1):
# 根据传入的方法 f ,计算每个个体的得分
last_avg = self.bounds / float(self.life_count)
self.bounds = 0.0
self.best = Life(self)
self.best.set_score(-1.0)
for lf in self.lives:
lf.score = f(lf, last_avg)
if lf.score > self.best.score:
self.best = lf
self.bounds += lf.score

def next(self, n=1):
# 演化至下n代
while n > 0:
# self.__getBounds()
self.judge(self.__judge)
new_lives = [Life(self, self.best.gene)]
# self.bestHistory.append(self.best)
while len(new_lives) < self.life_count:
new_lives.append(self.__new_child())
self.lives = new_lives
self.generation += 1
# print("gen: %d, mutation: %d, best: %f" % (self.generation, self.mutationCount, self.best.score))
self.save(self.best, self.generation)

n -= 1
34 changes: 34 additions & 0 deletions TSP/Life.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-

"""Life.py
生命类
"""

import random


class Life(object):

def __init__(self, env, gene=None):
self.env = env
self.score = 0

if gene is None:
self.__rnd_gene()
elif isinstance(gene, list):
self.gene = []
for k in gene:
self.gene.append(k)
else:
self.gene = gene

def __rnd_gene(self):
self.gene = ""
for i in range(self.env.gene_length):
self.gene += str(random.randint(0, 1))

def set_score(self, v):
self.score = v

def add_score(self, v):
self.score += v
189 changes: 189 additions & 0 deletions TSP/tsp_ga.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-

"""TSP.py
TSP问题
"""

import sys
import random
import math
import time
import Tkinter
import threading

from GA import GA


class MyTSP(object):
"""TSP"""

def __init__(self, root, width=800, height=600, n=32):
self.root = root
self.width = width
self.height = height
self.n = n
self.canvas = Tkinter.Canvas(
root,
width=self.width,
height=self.height,
bg="#ffffff",
xscrollincrement=1,
yscrollincrement=1
)
self.canvas.pack(expand=Tkinter.YES, fill=Tkinter.BOTH)
self.title("TSP")
self.__r = 5
self.__t = None
self.__lock = threading.RLock()
self.__running = False
self.nodes = []
self.nodes2 = []
self.ga = None
self.order = []

self.__bind_events()
self.new()

def __bind_events(self):
self.root.bind("q", self.quite)
self.root.bind("n", self.new)
self.root.bind("e", self.evolve)
self.root.bind("s", self.stop)

def title(self, s):
self.root.title(s)

def new(self, evt=None):
self.__lock.acquire()
self.__running = False
self.__lock.release()

self.clear()
self.nodes = [] # 节点坐标
self.nodes2 = [] # 节点图片对象
for i in range(self.n):
x = random.random() * (self.width - 60) + 30
y = random.random() * (self.height - 60) + 30
self.nodes.append((x, y))
node = self.canvas.create_oval(
x - self.__r,
y - self.__r, x + self.__r, y + self.__r,
fill="#ff0000",
outline="#000000",
tags="node",
)
self.nodes2.append(node)

self.ga = GA(
life_count=50,
mutation_rate=0.05,
judge=self.judge(),
mk_life=self.mk_life(),
x_func=self.x_func(),
m_func=self.m_func(),
save=self.save()
)
self.order = range(self.n)
self.line(self.order)

def distance(self, order):
"""得到当前顺序下连线总长度"""
distance = 0
for i in range(-1, self.n - 1):
i1, i2 = order[i], order[i + 1]
p1, p2 = self.nodes[i1], self.nodes[i2]
distance += math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)

return distance

def mk_life(self):
def f():
lst = range(self.n)
random.shuffle(lst)
return lst

return f

def judge(self):
"""评估函数"""
return lambda lf, av=100: 1.0 / self.distance(lf.gene)

def x_func(self):
"""交叉函数"""

def f(lf1, lf2):
p1 = random.randint(0, self.n - 1)
p2 = random.randint(self.n - 1, self.n)
g1 = lf2.gene[p1:p2] + lf1.gene
# g2 = lf1.gene[p1:p2] + lf2.gene
g11 = []
for i in g1:
if i not in g11:
g11.append(i)
return g11

return f

def m_func(self):
"""变异函数"""

def f(gene):
p1 = random.randint(0, self.n - 2)
p2 = random.randint(self.n - 2, self.n - 1)
gene[p1], gene[p2] = gene[p2], gene[p1]
return gene

return f

def save(self):
def f(lf, gen):
pass

return f

def evolve(self, evt=None):
self.__lock.acquire()
self.__running = True
self.__lock.release()

while self.__running:
self.ga.next()
self.line(self.ga.best.gene)
self.title("TSP - gen: %d" % self.ga.generation)
self.canvas.update()

self.__t = None

def line(self, order):
"""将节点按 order 顺序连线"""
self.canvas.delete("line")

def line2(i1, i2):
p1, p2 = self.nodes[i1], self.nodes[i2]
self.canvas.create_line(p1, p2, fill="#000000", tags="line")
return i2

reduce(line2, order, order[-1])

def clear(self):
for item in self.canvas.find_all():
self.canvas.delete(item)

def quite(self, evt):
self.__lock.acquire()
self.__running = False
self.__lock.release()
sys.exit()

def stop(self, evt):
self.__lock.acquire()
self.__running = False
self.__lock.release()

def mainloop(self):
self.root.mainloop()


if __name__ == "__main__":
MyTSP(Tkinter.Tk()).mainloop()
4 changes: 4 additions & 0 deletions os_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import os

os.mkdir('dsds/dsds') # Failed , could only make one dir
os.makedirs('sdsd/ldsd/ds') # Success, can make multi dirs
Loading

0 comments on commit 7061f25

Please sign in to comment.