python实现遗传算法求解tsp旅行商问题(详细解释)_python实现遗传算法求解TSP旅行商问题(详细解释)...

这篇博客详细介绍了如何使用Python实现遗传算法来解决旅行商问题(TSP)。通过GA.py、Life.py和TSP_GA.py三个文件,实现了遗传算法类、基因序列类和旅行商算法类。代码中包含了种群初始化、适配值计算、交叉和突变操作,最终找到最短路径。博客还提供了34个城市经纬度的数据集。
摘要由CSDN通过智能技术生成

课设需要做这个题目,看了http://www.tuicool.com/articles/Fb2YjeF之后下了他在github上的代码https://github.com/zchlong/tsp,发现一些错别字这份代码里改正了。

三个文件:

1.GA.py遗传算法类

2.Life.py基因序列类

3.TSP_GA.py 旅行商算法类,届时直接运行这个代码文件即可

4.34所城市经纬度distanceMatrix.txt

格式:

城市名经度 纬度

1.GA.py遗传算法类

# -*- coding: utf-8 -*-

import random

from Life import Life

class GA(object):

"""遗传算法类"""

def __init__(self, aCrossRate, aMutationRate, aLifeCount, aGeneLength, aMatchFun = lambda life : 1):

self.crossRate = aCrossRate #交叉概率

self.mutationRate = aMutationRate #突变概率

self.lifeCount = aLifeCount #种群数量,就是每次我们在多少个城市序列里筛选,这里初始化为100

self.geneLength = aGeneLength #其实就是城市数量

self.matchFun = aMatchFun #适配函数

self.lives = [] #种群

self.best = None #保存这一代中最好的个体

self.generation = 1 #一开始的是第一代

self.crossCount = 0 #一开始还没交叉过,所以交叉次数是0

self.mutationCount = 0 #一开始还没变异过,所以变异次数是0

self.bounds = 0.0 #适配值之和,用于选择时计算概率

self.initPopulation() #初始化种群

def initPopulation(self):

"""初始化种群"""

self.lives = []

for i in range(self.lifeCount):

#gene = [0,1,…… ,self.geneLength-1]

#事实就是0到33

gene = range(self.geneLength)

#将0到33序列的所有元素随机排序得到一个新的序列

random.shuffle(gene)

#Life这个类就是一个基因序列,初始化life的时候,两个参数,一个是序列gene,一个是这个序列的初始适应度值

# 因为适应度值越大,越可能被选择,所以一开始种群里的所有基因都被初始化为-1

life = Life(gene)

#把生成的这个基因序列life填进种群集合里

self.lives.append(life)

def judge(self):

"""评估,计算每一个个体的适配值"""

# 适配值之和,用于选择时计算概率

self.bounds = 0.0

#假设种群中的第一个基因被选中

self.best = self.lives[0]

for life in self.lives:

life.score = self.matchFun(life)

self.bounds += life.score

#如果新基因的适配值大于原先的best基因,就更新best基因

if self.best.score < life.score:

self.best = life

def cross(self, parent1, parent2):

"""交叉"""

index1 = random.randint(0, self.geneLength - 1)

index2 = random.randint(index1, self.geneLength - 1)

tempGene = parent2.gene[index1:index2] #交叉的基因片段

newGene = []

p1len = 0

for g in parent1.gene:

if p1len == index1:

newGene.extend(tempGene) #插入基因片段

p1len += 1

if g not in tempGene:

newGene.append(g)

p1len += 1

self.crossCount += 1

return newGene

def mutation(self, gene):

"""突变"""

#相当于取得0到self.geneLength - 1之间的一个数,包括0和self.geneLength - 1

index1 = random.randint(0, self.geneLength - 1)

index2 = random.randint(0, self.geneLength - 1)

#把这两个位置的城市互换

gene[index1], gene[index2] = gene[index2], gene[index1]

#突变次数加1

self.mutationCount += 1

return gene

def getOne(self):

"""选择一个个体"""

#产生0到(适配值之和)之间的任何一个实数

r = random.uniform(0, self.bounds)

for life in self.lives:

r -= life.score

if r <= 0:

return life

raise Exception("选择错误", self.bounds)

def newChild(self):

"""产生新后的"""

parent1 = self.getOne()

rate = random.random()

#按概率交叉

if rate < self.crossRate:

#交叉

parent2 = self.getOne()

gene = self.cross(parent1, parent2)

else:

gene = parent1.gene

#按概率突变

rate = random.random()

if rate < self.mutationRate:

gene = self.mutation(gene)

return Life(gene)

def next(self):

"""产生下一代"""

self.judge()#评估,计算每一个个体的适配值

newLives = []

newLives.append(self.best)#把最好的个体加入下一代

while len(newLives) < self.lifeCount:

newLives.append(self.newChild())

self.lives = newLives

self.generation += 1

2.Life.py基因序列类

# -*- encoding: utf-8 -*-

SCORE_NONE = -1

class Life(object):

"""个体类"""

def __init__(self, aGene = None):

self.gene = aGene

self.score = SCORE_NONE

3.TSP_GA.py 旅行商算法类,届时直接运行这个代码文件即可

# -*- encoding: utf-8 -*-

import random

import math

import Tkinter

from GA import GA

class TSP(object):

def __init__(self, aLifeCount = 100,):

self.initCitys()

self.lifeCount = aLifeCount

self.ga = GA(aCrossRate = 0.7,

aMutationRate = 0.02,

aLifeCount = self.lifeCount,

aGeneLength = len(self.citys),

aMatchFun = self.matchFun())

def initCitys(self):

self.citys = []

#这个文件里是34个城市的经纬度

f=open("distanceMatrix.txt","r")

while True:

#一行一行读取

loci = str(f.readline())

if loci:

pass # do something here

else:

break

#用readline读取末尾总会有一个回车,用replace函数删除这个回车

loci = loci.replace("\n", "")

#按照tab键分割

loci=loci.split("\t")

# 中国34城市经纬度读入citys

self.citys.append((float(loci[1]),float(loci[2]),loci[0]))

#order是遍历所有城市的一组序列,如[1,2,3,7,6,5,4,8……]

#distance就是计算这样走要走多长的路

def distance(self, order):

distance = 0.0

#i从-1到32,-1是倒数第一个

for i in range(-1, len(self.citys) - 1):

index1, index2 = order[i], order[i + 1]

city1, city2 = self.citys[index1], self.citys[index2]

distance += math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2)

return distance

#适应度函数,因为我们要从种群中挑选距离最短的,作为最优解,所以(1/距离)最长的就是我们要求的

def matchFun(self):

return lambda life: 1.0 / self.distance(life.gene)

def run(self, n = 0):

while n > 0:

self.ga.next()

distance = self.distance(self.ga.best.gene)

print (("%d : %f") % (self.ga.generation, distance))

print self.ga.best.gene

n -= 1

print "经过%d次迭代,最优解距离为:%f"%(self.ga.generation, distance)

print "遍历城市顺序为:",

# print "遍历城市顺序为:", self.ga.best.gene

#打印出我们挑选出的这个序列中

for i in self.ga.best.gene:

print self.citys[i][2],

def main():

tsp = TSP()

tsp.run(100)

if __name__ == '__main__':

main()

4.34所城市经纬度distanceMatrix.txt

北京116.4639.92

天津117.239.13

上海121.4831.22

重庆106.5429.59

拉萨91.1129.97

乌鲁木齐87.6843.77

银川106.2738.47

呼和浩特111.6540.82

南宁108.3322.84

哈尔滨126.6345.75

长春125.3543.88

沈阳123.3841.8

石家庄114.4838.03

太原112.5337.87

西宁101.7436.56

济南11736.65

郑州113.634.76

南京118.7832.04

合肥117.2731.86

杭州120.1930.26

福州119.326.08

南昌115.8928.68

长沙11328.21

武汉114.3130.52

广州113.2323.16

台北121.525.05

海口110.3520.02

兰州103.7336.03

西安108.9534.27

成都104.0630.67

贵阳106.7126.57

昆明102.7325.04

香港114.122.2

澳门113.3322.13

参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值