八皇后問題,乙個古老而著名的問題,是回溯演算法的典型案例。該問題由國際西洋棋棋手馬克斯·貝瑟爾於 1848 年提出:在 8×8 格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。測試結果:演算法的邏輯流程圖如下所示:
源**為:
import copy
import numpy as np
import random
import time
# 爬山法解決八皇后問題
# 八皇后初始化函式
def init():
cache = {}
m = np.zeros((8, 8), dtype=int)
for i in range(0, 8):
temp = random.randrange(0, 8)
m[temp, i] = 1
cache["queen" + str(i)] = [temp, i]
return m, cache
# 計算當前狀態碰撞數量
def compute_weight_single(coord_cache):
weight = 0
for i in range(0, 8):
x, y = coord_cache["queen" + str(i)]
for j in range(i + 1, 8):
_x, _y = coord_cache["queen" + str(j)]
if _x - x == j - i or _x - x == i - j:
weight += 1
if _x == x:
weight += 1
return weight
# 計算8x8的碰撞矩陣
def compute_weight_matrix(coord_cache):
weight_matrix = np.zeros((8, 8))
for i in range(0, 8):
for j in range(0, 8):
# fix bug
# 此處需用dict.copy函式,直接寫賦值會導致僅僅建立了乙個引用,改變引用也會改變原來的值
temp_coord_cache = coord_cache.copy()
temp_coord_cache["queen" + str(i)] = [j, i]
weight = compute_weight_single(temp_coord_cache)
weight_matrix[j, i] = weight
return weight_matrix
# 根據碰撞矩陣調整皇后的位置
def next_move(cache, weight_matrix):
coord_cache = cache
min = np.min(weight_matrix)
for i in range(0, 8):
for j in range(0, 8):
if weight_matrix[j, i] == min:
# 調整皇后的位置
coord_cache["queen" + str(i)] = [j, i]
return coord_cache
# 把當前的皇后狀態畫出來
def draw(coord_cache):
m = np.zeros((8, 8), dtype=int)
for i in range(8):
row, column = coord_cache["queen" + str(i)]
row, column = int(row), int(column)
m[row][column] = 1
return m
# 爬山演算法
def climbing_algorithm():
m, coord_cache = init()
while true:
weight = compute_weight_single(coord_cache) # 計算當前狀態的碰撞值
# print("當前的八皇后狀態為:\n", draw(coord_cache))
# print("當前的八皇后狀態的碰撞度為\n", weight)
if weight == 0: # 碰撞值為零,為目標狀態,演算法結束
return true
weight_matrix = compute_weight_matrix(coord_cache) # 計算8*8的碰撞矩陣
# print("當前的碰撞矩陣為:\n", weight_matrix)
# 如果碰撞矩陣的最小值都大於等於當前狀態的碰撞值,則不能找到乙個更好的解
if weight_matrix.min() >= weight:
return false
else:
coord_cache = next_move(coord_cache, weight_matrix) # 移動皇后
def climbing_algorithm_test(num):
tic = time.time()
success_case = 0
fail_case = 0
for i in range(num):
if climbing_algorithm():
print("第個例子成功找到最優解".format(i))
success_case += 1
else:
print("第個例子失敗".format(i))
fail_case += 1
toc = time.time()
print("個例子中成功解決的例子為:".format(num, success_case))
print("個例子成功解決的百分比為:".format(num, success_case / num))
print("個例子中失敗的例子為:".format(num, fail_case))
print("個例子失敗的百分比為:".format(num, fail_case / num))
print("個例子執行演算法所需的時間為:秒".format(num, toc - tic))
climbing_algorithm_test(10000)
各演算法解決八皇后八數碼成功率:
爬山法實現 八皇后問題 (Python 實現)
本文主要簡單闡述爬山法的基本演算法思想,並給出用此演算法實現八皇后問題詳細過程 最基本的爬上搜尋演算法表示 節選自 人工智慧 第二版 function hill climbing problem return a state thate is a locak maximum inputs probl...
人工智慧導論 上機 A 解決八數碼問題
a 演算法的精髓 f n g n h n f n g n h n f n g n h n h n h n h n 是當前狀態n nn到目標狀態的曼哈頓距離和。利用堆優化bfs bfsbf s即可。還可以在bfs bfsbf s時記錄前驅,然後倒著找到路線方案。author codancer crea...
回溯法解決八皇后問題
在西洋棋棋盤上 8 8 放置八個皇后,使得任意兩個皇后之間不能在同一行,同一列,也不能位於同於對角線上。問共有多少種不同的方法,並且指出各種不同的放法。使用回溯法依次假設皇后的位置,當第乙個皇后確定後,尋找下一行的皇后位置,當滿足左上 右上和正上方向無皇后,即矩陣中對應位置都為0,則可以確定皇后位置...