人工智慧 爬山法解決八皇后問題 python原始碼

2021-10-06 16:28:12 字數 3533 閱讀 7372

八皇后問題,乙個古老而著名的問題,是回溯演算法的典型案例。該問題由國際西洋棋棋手馬克斯·貝瑟爾於 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,則可以確定皇后位置...