因此,我正在尝试使用遗传算法创建路径查找器。因此,在我的代码中,我创建了尺寸为10x10的正方形,我希望它向右移动,同时避开目标也是10x10的障碍。但是,无论何时我运行代码,生成的适应度都不会增加,因此我的遗传算法不会收敛。我该怎么做才能优化我的代码并使算法收敛?我正在使用pygame绘制路径板。在基因组阵列达到600个大小之后,我也停止生成基因组。
这是我的代码 '''python
import random
import sys
class Genome:
def __init__(self):
self.genome_array = []
self.fitness = 0
self.x_position = 50
self.y_position = 250
self.genome_size = 50
self.total_size = 0
self.goal_x = 500
self.goal_y = 250
self.vel = 10
def generateGenome(self):
i = 0
while i < self.genome_size:
print("GenerateGenome")
position = self.generatePosition(self.x_position, self.y_position)
self.genome_array.append(position)
self.x_position += position[0]
self.y_position += position[1]
(self.fitness, endGame) = self.calcfitness(
[self.x_position, self.y_position])
if endGame:
return (endGame, self.fitness)
i += 1
self.total_size += self.genome_size
return (endGame, self.fitness)
def calcfitness(self, player_position):
# x position
if player_position[0] > self.goal_x:
pos_x = player_position[0] - self.goal_x
fitnessX = pos_x / self.goal_x
fitnessX = 1 - fitnessX
else:
fitnessX = player_position[0] / self.goal_x
# y position
if player_position[1] > self.goal_y:
pos_y = player_position[1] - self.goal_y
fitnessY = pos_y / self.goal_y
fitnessY = 1 - fitnessY
else:
fitnessY = player_position[0] / self.goal_y
result = (abs(fitnessX * fitnessY) + .02)
print("FITNESS == {}".format(result))
if result == 1.02:
return (result, True)
else:
return (result, False)
def generatePosition(self, pos_x, pos_y):
if pos_x < 10 or pos_y < 10:
sys.exit("NEGATIVE NUMBER ERROR in GENERATE POSITION")
print(pos_x)
print(pos_y)
tempx = pos_x
tempy = pos_y
x_vel = 0
y_vel = 0
goodNum = False
while not goodNum:
randNum = random.randint(1, 8)
print("random number = {}".format(randNum))
print("GeneratePosition")
if randNum == 1: # right
pos_x += self.vel
x_vel += self.vel
elif randNum == 2: # diagonal up right
pos_x += self.vel
pos_y -= self.vel
x_vel += self.vel
y_vel -= self.vel
elif randNum == 3: # up
pos_y -= self.vel
y_vel -= self.vel
elif randNum == 4: # diagonal up left
pos_x -= self.vel
pos_y -= self.vel
x_vel -= self.vel
y_vel -= self.vel
elif randNum == 5: # left
pos_x -= self.vel
x_vel -= self.vel
elif randNum == 6: # diagonal down left
pos_x -= self.vel
pos_y += self.vel
x_vel -= self.vel
y_vel += self.vel
elif randNum == 7: # down
pos_y += self.vel
y_vel += self.vel
else: # diagonal down right
pos_x += self.vel
pos_y += self.vel
x_vel += self.vel
y_vel += self.vel
if (pos_x >= 290 and pos_x <= 320) and (pos_y >= 70 and pos_y <= 480):
pos_x = tempx
pos_y = tempy
x_vel = 0
y_vel = 0
print("x = {} y = {}".format(pos_x,pos_y))
continue
elif (pos_x < 10 or pos_x >= 590) or (pos_y < 10 or pos_y >= 590):
pos_x = tempx
pos_y = tempy
x_vel = 0
y_vel = 0
print("x = {} y = {}".format(pos_x,pos_y))
continue
else:
goodNum = True
return [x_vel, y_vel]
class Population:
population_array = []
population_size = 100
mutationRate = .7
maxPopulationFitness = -1000
maxFitness = -1000
def __init__(self):
i = 0
while i < self.population_size:
genome = Genome()
self.population_array.append(genome)
i += 1
def generatePopulation(self):
i = 0
self.maxPopulationFitness = -1000
while i < self.population_size:
(endgame, maxFit) = self.population_array[i].generateGenome()
if maxFit > self.maxFitness:
self.maxFitness = maxFit
if maxFit > self.maxPopulationFitness:
self.maxPopulationFitness = maxFit
if endgame:
return (True, i)
i += 1
return (False, None)
def calcFitness(self):
i = 0
self.maxPopulationFitness = -1000
while i < self.population_size:
pos_x = self.population_array[i].x_position
pos_y = self.population_array[i].y_position
(result, endGame) = self.population_array[i].calcfitness([pos_x,pos_y])
print("*****Fitness = {}******".format(result))
self.population_array[i].fitness = result
if result > self.maxFitness:
self.maxFitness = result
if result > self.maxPopulationFitness:
self.maxPopulationFitness = result
if endGame:
return (endGame, i)
i += 1
return (False, None)
def selection(self):
while True:
index = random.randint(0,self.population_size - 1)
bestFitness = random.uniform(0,self.maxPopulationFitness)
print("bestFitness = {}".format(bestFitness))
parent = self.population_array[index]
print("parentFitness = {}".format(parent.fitness))
if (bestFitness < parent.fitness):
return parent
def randomSelection(self):
print("RandomSelection")
i = 0
new_population = []
while i < self.population_size:
parent_one = self.selection()
parent_two = self.selection()
print("Step {}".format(i))
child_one = self.crossover(parent_one,parent_two)
(valid,xpos,ypos) = self.checkPath(child_one.genome_array)
if not valid:
continue
new_population.append(child_one)
child_one.x_position = xpos
child_one.y_position = ypos
i += 1
self.population_array = new_population
def crossover(self,parent_one, parent_two):
randPosition = random.randint(0,parent_one.total_size - 1)
i = 0
child_one = Genome()
child_one.total_size = parent_one.total_size
while i < parent_one.total_size:
if i > randPosition:
child_one.genome_array.append(parent_one.genome_array[i])
position = parent_one.genome_array[i]
else:
child_one.genome_array.append(parent_two.genome_array[i])
position = parent_two.genome_array[i]
i += 1
i = 0
while i < parent_one.total_size:
randMutate = random.random()
if randMutate < self.mutationRate:
position = child_one.genome_array[i]
position[0] = self.mutateChild(position[0])
position[1] = self.mutateChild(position[1])
i += 1
return child_one
def mutateChild(self,pos):
if pos == 0:
randNum = random.randint(0,1)
if not randNum:
return -10
else:
return 10
else:
return pos * -1
def checkPath(self,genomeArray):
xpos = 50
ypos = 250
for path in genomeArray:
xpos += path[0]
ypos += path[1]
if (xpos >= 290 and xpos <= 320) and (ypos >= 70 and ypos <= 480):
return (False, None, None)
elif (xpos < 10 or xpos >= 590) or (ypos < 10 or ypos >= 590):
return (False, None, None)
return (True, xpos, ypos)
def checkValidPosition(self,pos_x,pos_y):
if (pos_x >= 290 and pos_x <= 320) and (pos_y >= 70 and pos_y <= 480):
return False
elif (pos_x < 10 or pos_x >= 590) or (pos_y < 10 or pos_y >= 590):
return False
else:
return True
'''