赞
踩
在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。正确的解有很多个,遗传算法并不直接计算一共有多少个解,而是寻找满足条件的解,从一种状态进化到一种满足8皇后不能互相攻击的状态.
Q . . . . . . .
. . . . Q . . .
. . . . . . Q .
. Q . . . . . .
. . . Q . . . .
. . . . . . . Q
. . . . . . . .
. . Q . . . . .
用matplotlib简单可视化棋盘
import random
import numpy as np
import matplotlib.pyplot as plt
def display_chessboard(coordinates):
plt.figure(figsize=(7, 7))
for i in range(9):
plt.axhline(y=i,c='black')
for i in range(9):
plt.axvline(x=i,c='black')
for x,y in coordinates:
plt.text(x+0.35,y+0.35,'Q',size=20,color='blue')
plt.xlim(0,8)
plt.ylim(0,8)
# 这是一个正确的摆法
coordinates = [(2, 0),(4, 1),(7, 2),(3, 3),(0, 4),(6, 5),(1, 6),(5, 7)]
display_chessboard(coordinates)
# 随机生成初始状态
def generate_initinal_state(length,constraint=False):
geneSet = list(range(length))
# 不同行不同列约束
if constraint:
coordinate_xs = random.sample(geneSet,length)
coordinate_ys = random.sample(geneSet,length)
coordinates = [(x,y) for x,y in zip(coordinate_xs, coordinate_ys)]
else:
coordinate_xs = [random.sample(geneSet,1)[0] for i in range(length)]
coordinate_ys = [random.sample(geneSet,1)[0] for i in range(length)]
coordinates = [(x,y) for x,y in zip(coordinate_xs, coordinate_ys)]
return coordinates
coordinates_1 = generate_initinal_state(8)
coordinates_2 = generate_initinal_state(8, True)
##### 随机初始,只有一个queen满足条件
display_chessboard(coordinates_1)
这个是没有约束的随机初始化
##### 增加行列约束后,有两个queen满足条件
display_chessboard(coordinates_2)
增加了行列约束的
需要一个合适的适应度函数来量化当前棋盘的状态,便于跟其他状态进行比较.
方案1:比较简单,就是遍历Queens,检测前后左右,对角线有无其他Queen,详细说下方案2:
发现没有,如果Queen在同一对角线的话,坐标和是相等的,如果8个Queen的坐标和是不同的8个数字,那就满足了条件的25%了
def get_fitness(coordinates):
x_s = [coordinate[0] for coordinate in coordinates]
y_s = [coordinate[1] for coordinate in coordinates]
x_set = set(x_s)
y_set = set(y_s)
# 左对角线
a_set = set([sum(coordinate) for coordinate in coordinates])
# 右对角线(反转x轴)
b_set = set([8 - coordinate[0]+coordinate[1] for coordinate in coordinates])
fitness = 32 -len(x_set)-len(y_set)-len(a_set)-len(b_set)
return fitness
random_state = generate_initinal_state(length=8)
display_chessboard(random_state)
print('random_state fitness : ',get_fitness(random_state))
random_state fitness : 10
def mutate(coordinates, coordinateSet):
index = np.random.randint(8)
new_coordinates = coordinates.copy()
picked_gene = coordinates[index]
new_gene, alternative = random.sample(coordinateSet, 2)
if picked_gene == new_gene:
new_coordinates[index] = alternative
else:
new_coordinates[index] = new_gene
return new_coordinates
init_state = generate_initinal_state(length=8,constraint=True)
display_chessboard(init_state)
初始状态是加入了约束的,开局的状态比较理想.
print('init state fitness : ',get_fitness(init_state))
init state fitness : 4
coordinateSet = [(x,y) for x in range(8) for y in range(8)]
state_logs = []
fines_logs = []
bestState = init_state
bestFitness = get_fitness(init_state)
state_logs.append(bestState)
fines_logs.append(bestFitness)
while True:
childState = mutate(bestState,coordinateSet)
childFitness = get_fitness(childState)
state_logs.append(childState)
fines_logs.append(childFitness)
if childFitness > bestFitness:
continue
print('childState Fitness :',childFitness)
if childFitness == 0:
display_chessboard(childState)
break
bestState = childState
bestFitness = childFitness
childState Fitness : 4
childState Fitness : 4
childState Fitness : 4
childState Fitness : 4
childState Fitness : 4
childState Fitness : 3
childState Fitness : 3
childState Fitness : 3
childState Fitness : 3
childState Fitness : 3
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 2
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 1
childState Fitness : 0
进化的过程我做成了短视频,会放到公众号: 唐牛才是食神
常驻作者: 今晚打老虎, 懂王就是懂, 唐牛才是食神
安利一下公众号:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。