问题描述
我正在使用 AI 和遗传算法开发俄罗斯方块游戏。
AI 的目标是“尝试”当前 Tetraaminos 和棋盘的每个可用动作,并选择最佳动作。为了选择最好的,我有一个适应度函数,可以返回棋盘内移动的分数。
例如,我在移动后计算棋盘内的所有孔,并将这些值与变量相乘。
def evaluate_move(self,board: Board,shape):
score = 0
board.check_rows(shape)
score += self.aggregate_height * board.aggregate_height()
score += self.bumpiness * board.bumpiness()
score += self.holes * board.holes()
score += self.columns_with_holes * board.columns_with_holes()
score += self.number_of_pits * board.number_of_pits()
score += self.cleared_rows * board.line_cleared
return score
self.aggregate_height
等每个变量都基于遗传算法。
self.aggregate_height = random.uniform(-3,0)
self.bumpiness = random.uniform(-3,0)
self.holes = random.uniform(-3,0)
self.columns_with_holes = random.uniform(-3,0)
self.number_of_pits = random.uniform(-3,0)
self.cleared_rows = random.uniform(0,3)
每个值都在 (-1,1)
范围内标准化,如下所示:
def normalize(value):
return value / 3
然后,在每一代之后,像这样应用交叉和变异:
def crossover(self,other_parent):
"""Create a crossover of the best parents."""
child = geneticAgent()
child.aggregate_height = self.aggregate_height if random.randint(0,1) == 0 else other_parent.aggregate_height
child.bumpiness = self.bumpiness if random.randint(0,1) == 0 else other_parent.bumpiness
child.holes = self.holes if random.randint(0,1) == 0 else other_parent.holes
child.columns_with_holes = self.columns_with_holes if random.randint(0,1) == 0 else other_parent.columns_with_holes
child.number_of_pits = self.number_of_pits if random.randint(0,1) == 0 else other_parent.number_of_pits
child.cleared_rows = self.cleared_rows if random.randint(0,1) == 0 else other_parent.cleared_rows
return child
def mutation(self):
"""Mutating the offsprings generated from crossover to maintain variation in the population."""
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.aggregate_height += random.uniform(-0.2,0.2)
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.bumpiness += random.uniform(-0.2,0.2)
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.holes += random.uniform(-0.2,0.2)
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.columns_with_holes += random.uniform(-0.2,0.2)
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.number_of_pits += random.uniform(-0.2,0.2)
if numpy.random.random() < configuration.MUTATION_PERCENTAGE:
self.cleared_rows += random.uniform(-0.2,0.2)
self.normalize_values()
遗传算法的参数是:
# genetic ALGORITHM
NUMBER_OF_POPULATION = 200
NUMBER_OF_GENERATION = 200
NUMBER_PARENTS_CROSSOVER = 10
MUTATION_PERCENTAGE = 0.1
NUMBER_OF_GAMES = 5
问题是我没有看到真正的改进。 7代之后,最好的得到了70000+的分数,此后其他一代的结果都是最差的。
每条染色体的分数就是AI在游戏中得到的分数/NUMBER_OF_GAMES
因此,每个 AI 从染色体中获取值,测试所有可能的移动,找到找到的最好的移动,并继续进行直到游戏结束。如果此 AI 已经玩了 NUMBER_OF_GAMES
场游戏,则返回游戏的平均分。完成所有 AI 后,应用交叉,然后变异,然后重复。
编辑:锦标赛交叉
def select_crossover_parents(population,tetris_fitness):
crossover_parents = []
for i in range(configuration.NUMBER_PARENTS_CROSSOVER):
best_index = None
indexes = random.sample(range(0,configuration.NUMBER_OF_POPULATION - 1),15)
for index in indexes:
if (best_index is None) or (tetris_fitness[index] > tetris_fitness[best_index]):
best_index = index
crossover_parents.append(population[best_index])
return crossover_parents
crossover_parents_total = algorithm_manager.select_crossover_parents(population,tetris_fitness)
while len(population) != (configuration.NUMBER_OF_POPULATION - len(parents)):
crossover_parents = random.sample(crossover_parents_total,2)
population.append(crossover_parents[0].crossover(crossover_parents[1]))
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)