我是该平台的新手,我正在尝试实现一个功能,该功能创建解决方案的总体,然后对选定的父项进行交叉和变异以创建新的子代,即遗传算法。我已经使用随机方法进行选择。尝试调用此函数时,我遇到此错误
crossOver = self.pmxCrossover([popul[0], popul[1]])
TypeError: 'method' object is not subscriptable'
TSP.py
from Individual import *
import random
from operator import attrgetter
import sys
class BasicTSP:
def __init__(self, _fName, _popSize, _mutationRate, _maxIterations):
"""
Parameters and general variables
"""
self.population = []
self.matingPool = []
self.best = None
self.popSize = 100
self.genSize = None
self.mutationRate = 0.1
self.maxIterations = 500
self.iteration = 0
self.fName = _fName
self.data = {}
self.matingPool = []
self.readInstance()
self.initPopulation()
def readInstance(self):
"""
Reading an instance from fName
"""
file = open(self.fName, 'r')
self.genSize = int(file.readline())
self.data = {}
for line in file:
(id, x, y) = line.split()
self.data[int(id)] = (int(x), int(y))
file.close()
def initPopulation(self):
"""
Creating random individuals in the population
"""
for i in range(0, self.popSize):
individual = Individual(self.genSize, self.data)
individual.computeFitness()
self.population.append(individual)
self.best = self.population[0].copy()
for ind_i in self.population:
if self.best.getFitness() > ind_i.getFitness():
self.best = ind_i.copy()
print("Best initial sol: ", self.best.getFitness())
def updateBest(self, candidate):
if self.best == None or candidate.getFitness() < self.best.getFitness():
self.best = candidate.copy()
print("iteration: ", self.iteration, "best: ", self.best.getFitness())
"""
def randomSelection(self):
Random (uniform) selection of two individuals
"""
indA = self.matingPool[random.randint(0, self.popSize - 1)]
indB = self.matingPool[random.randint(0, self.popSize - 1)]
return [indA, indB]
def stochasticUniversalSampling(self):
wheel = []
fitness = Individual.computeFitness()
total = sum(self.fitness(p) for p in self.population)
top = 0
for p in self.population:
f = self.fitness(p) / total
wheel.append((top, top + f, p))
top += f
mid = len(wheel) // 2
low, high, answer = wheel[mid]
if low <= num <= high:
return answer
elif low > num:
return wheel[mid + 1:], num
else:
return wheel[:mid], num
stepSize = 1.0 / N
answer = []
r = random.random()
answer.append(wheel.binSearch(wheel, r))
while len(answer) < N:
r += stepSize
if r > 1:
r %= 1
answer.append(self.binSearch(wheel, r))
return answer
def uniformCrossover(self, indA, indB):
"""
Your Uniform Crossover Implementation
"""
size = min(len(indA), len(indB))
for i in range(size):
if random.random() < self.mutationRate:
indA[i], indB[i] = indB[i], indA[i]
return indA, indB
def pmxCrossover(self, indA, indB):
"""
Your PMX Crossover Implementation
"""
size = min(len(indA), len(indB))
c1, c2 = [0] * size, [0] * size
# Initialize the position of each indices in the individuals
for i in range(size):
c1[indA[i]] = i
c2[indB[i]] = i
# Choose crossover points
crosspoint1 = random.randint(0, size)
crosspoint2 = random.randint(0, size - 1)
if crosspoint2 >= crosspoint1:
crosspoint2 += 1
else: # Swap the two cx points
crosspoint1, crosspointt2 = crosspoint2, crosspoint1
# Apply crossover between cx points
for i in range(crosspoint1, crosspoint2):
# Keep track of the selected values
temp1 = indA[i]
temp2 = indB[i]
# Swap the matched value
indA[i], indA[c1[temp2]] = temp2, temp1
indB[i], indB[c2[temp1]] = temp1, temp2
# Position bookkeeping
c1[temp1], c1[temp2] = c1[temp2], c1[temp1]
c2[temp1], c2[temp2] = c2[temp2], c2[temp1]
return indA, indB
def reciprocalExchangeMutation(self, ind):
"""
Your Reciprocal Exchange Mutation implementation
"""
if random.random() > self.mutationRate:
indexA = random.randint(0, self.genSize - 1)
indexB = random.randint(0, self.genSize - 1)
tmp = ind.genes[indexA]
ind.genes[indexA] = ind.genes[indexB]
ind.genes[indexB] = tmp
ind.computeFitness()
self.updateBest(ind)
return ind
def inversionMutation(self, ind):
"""
Your Inversion Mutation implementation
"""
pass
def updateMatingPool(self):
"""
Updating the mating pool before creating a new generation
"""
self.matingPool = []
for ind_i in self.population:
self.matingPool.append(ind_i.copy())
def newGeneration(self):
"""
Creating a new generation
1. Selection
2. Crossover
3. Mutation
"""
for gene_i in range(0, int(len(self.population) / 2)):
popul = []
popul = self.stochasticUniversalSampling()
crossOver = self.pmxCrossover(popul[0], popul[1])
mutate = self.reciprocalExchangeMutation(crossOver)
mutate.computeFitness()
self.population[gene_i] = mutate
self.updateBest(mutate)
"""
Depending of your experiment you need to use the most suitable algorithms for:
1. Select two candidates
2. Apply Crossover
3. Apply Mutation
"""
def GAStep(self):
"""
One step in the GA main algorithm
1. Updating mating pool with current population
2. Creating a new Generation
"""
self.updateMatingPool()
self.newGeneration()
def search(self):
"""
General search template.
Iterates for a given number of steps
"""
self.iteration = 0
while self.iteration < self.maxIterations:
self.GAStep()
self.iteration += 1
print("Total iterations: ", self.iteration)
print("Best Solution: ", self.best.getFitness())
# if len(sys.argv) < 2:
# print("Error - Incorrect input")
# print("Expecting python BasicTSP.py [instance] ")
# sys.exit(0)
# problem_file = sys.argv[1]
ga = BasicTSP('city.txt', 300, 0.1, 500)
ga.search()
Individual.py
"""
Basic TSP Example
file: Individual.py
"""
import random
import math
class Individual:
def __init__(self, _size, _data):
"""
Parameters and general variables
"""
self.fitness = 0
self.genes = []
self.genSize = _size
self.data = _data
self.genes = list(self.data.keys())
for i in range(0, self.genSize):
n1 = random.randint(0, self.genSize - 1)
n2 = random.randint(0, self.genSize - 1)
tmp = self.genes[n2]
self.genes[n2] = self.genes[n1]
self.genes[n1] = tmp
def setGene(self, genes):
"""
Updating current choromosome
"""
self.genes = []
for gene_i in genes:
self.genes.append(gene_i)
def copy(self):
"""
Creating a new individual
"""
ind = Individual(self.genSize, self.data)
for i in range(0, self.genSize):
ind.genes[i] = self.genes[i]
ind.fitness = self.getFitness()
return ind
def euclideanDistance(self, c1, c2):
"""
Distance between two cities
"""
d1 = self.data[c1]
d2 = self.data[c2]
return math.sqrt((d1[0] - d2[0]) ** 2 + (d1[1] - d2[1]) ** 2)
def getFitness(self):
return self.fitness
def computeFitness(self):
"""
Computing the cost or fitness of the individual
"""
self.fitness = self.euclideanDistance(self.genes[0], self.genes[len(self.genes) - 1])
for i in range(0, self.genSize - 1):
self.fitness += self.euclideanDistance(self.genes[i], self.genes[i + 1])
city.txt
20
1 404852 473167
2 1013583 517089
3 1046205 487054
4 744806 188315
5 958973 386684
6 639036 154790
7 387527 434868
8 602485 116037
9 741638 472818
10 732428 146593
11 516677 662087
12 657752 157071
13 196581 507980
14 663473 231937
15 590079 666222
16 382093 401433
17 966725 424017
18 285762 418017
19 394378 404659
20 563588 673501
请不要回答这个问题;这是一个课程作业。