日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

爬山法实现 八皇后问题 (Python 实现)

發(fā)布時(shí)間:2025/3/11 python 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 爬山法实现 八皇后问题 (Python 实现) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文主要簡(jiǎn)單闡述爬山法的基本算法思想,并給出用此算法實(shí)現(xiàn)八皇后問題詳細(xì)過程

最基本的爬上搜索算法表示:(節(jié)選自《人工智能》第二版):

function?HILL-CLIMBING(problem)?return?a state thate is a locak maximum
????inputs:?problem
????local variables:?current, a node?
?????????????????????????neighbor,a node
????current?= MakeNode(INITAL-STATE(problem));
????loop do
????????neighbor?= a highest-valued successor of?current?;
????????if?VALUE[neighbor] <= VALUE[current]?then return?STATE[current];
????????current?=?neighbor?;

算法特點(diǎn):

??????? 爬山法是一個(gè)向值增加的方向持續(xù)移動(dòng)的簡(jiǎn)單循環(huán)過程--類似于登高,它將會(huì)在到達(dá)一個(gè)“峰頂”時(shí)終止,此時(shí)相鄰狀態(tài)中沒有比它更高的值。這個(gè)算法不會(huì)維護(hù)搜索樹,因此當(dāng)前節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)只需要記錄當(dāng)前狀態(tài)和它的目標(biāo)函數(shù)值,它不會(huì)前瞻與當(dāng)前狀態(tài)不直接相鄰的那些狀態(tài)的值。這里更高的值是根據(jù)具體的應(yīng)用場(chǎng)景來定的,準(zhǔn)確的說是更接近目標(biāo)狀態(tài)的值,由我們?cè)O(shè)置的啟發(fā)式函數(shù)來決定哪個(gè)值更好,比如我們求解八皇后問題更高的值就是當(dāng)前格局中皇后沖突對(duì)數(shù)最少的情況


算法局限性:

????? 爬山法屬于一種局部的貪婪搜索方法,當(dāng)它在搜索過程中遇到了局部最大值就很難繼續(xù)向下搜索了,局部極大值是一個(gè)比它的每個(gè)鄰居狀態(tài)都高得到峰頂,但是比全局最大值(我們要到達(dá)的最終狀態(tài))要低,爬山法算法到達(dá)局部極大值附近就會(huì)被拉向峰頂,然后卡在局部極大值處無處可走。因此產(chǎn)生了爬山法的變種如隨機(jī)爬山法及其變種如隨機(jī)爬山法,隨機(jī)重新開始的爬山法,模擬退火搜索能夠非常有效的解決N皇后問題。

求解八皇后問題:

  • #-*- coding: utf-8 -*-
  • import random
  • #函數(shù)一:參數(shù)為當(dāng)前棋盤布局狀態(tài),根據(jù)布局判斷當(dāng)前八皇后布局存在沖突的皇后對(duì)數(shù)
  • def get_numof_conflict(status):
  • num = 0
  • for i in range(len(status)):
  • for j in range(i + 1,len(status)):
  • if status[i] == status[j]:
  • num += 1
  • offset = j - i
  • if abs(status[i]-status[j]) == offset:
  • num += 1
  • return num
  • #函數(shù)二:參數(shù)為當(dāng)前棋盤布局狀態(tài),利用爬山法思想選擇鄰居狀態(tài)最好的布局并返回
  • def hill_climbing(status):
  • convert = {}
  • length = len(status)
  • for col in range(length):
  • best_move = status[col]
  • for row in range(length):
  • if status[col] == row:
  • continue
  • status_copy = list(status)
  • status_copy[col] = row
  • convert[(col,row)] = get_numof_conflict(status_copy)
  • answers = [] #最佳后繼集合
  • conflict_now = get_numof_conflict(status) #當(dāng)前皇后沖突對(duì)數(shù)
  • #遍歷存儲(chǔ)所有可能后繼的字典,找出最佳后繼
  • for key,value in convert.iteritems():
  • if value < conflict_now:
  • conflict_now = value
  • for key,value in convert.iteritems():
  • if value == conflict_now:
  • answers.append(key)
  • #如果最佳后繼集合元素大于一個(gè) 隨機(jī)選擇一個(gè)
  • if len(answers) > 0:
  • x = random.randint(0,len(answers)-1)
  • col = answers[x][0]
  • row = answers[x][1]
  • status[col] = row
  • return status
  • #函數(shù)三:求得八皇后滿足沖突數(shù)為0的一個(gè)解,循環(huán)輸出每一步的后繼集合 直到不存在沖>突為止
  • def Queens():
  • status = [0,1,2,3,4,5,6,7] #初始狀態(tài)所有皇后都在對(duì)角線
  • #當(dāng)存在沖突的個(gè)數(shù)大于0時(shí) 循環(huán)求解最佳后繼 直到找到八皇后解
  • while get_numof_conflict(status) > 0:
  • status = hill_climbing(status)
  • print status
  • print get_numof_conflict(status)
  • print "the answer is"
  • print
  • print status
  • if __name__ == '__main__':
  • Queens()
  • 代碼說明 :

    (1)啟發(fā)式耗散函數(shù)?get_numof_conflict求出可以彼此攻擊2的皇后對(duì)的數(shù) ?hill_climbing是算法中爬山過程的實(shí)現(xiàn),convert字典中存儲(chǔ)的鍵是所有可能后繼狀態(tài),值是此狀態(tài)對(duì)應(yīng)的皇后沖突對(duì)數(shù),后面通過遍歷來找到最佳后繼。爬山法算法通常在最佳后繼集合中隨機(jī)選擇一個(gè)進(jìn)行擴(kuò)展,如果這樣的后繼多于一個(gè)的話

    (2)? 棋盤的排列用列表 status 表示, 依次表示第一列第二列到第n列的擺放位置。 如列表[0,2,1] 表示3*3矩陣第一列皇后放在最下面一格,第二列放在最上面一格,第三列放在中間一格

    (3) 運(yùn)行結(jié)果說明:初始狀態(tài)每個(gè)皇后都在次對(duì)角線上 每次運(yùn)行程序?qū)⑤敵銮蠼庖粋€(gè)八皇后正確解的爬山法實(shí)現(xiàn)過程 ,依次輸出求解過程每一個(gè)最佳選擇的鄰居狀態(tài)和其存在的皇后沖突對(duì)數(shù),可以看出在求解過程中 不斷爬山的過程--每進(jìn)行一步都達(dá)到一個(gè)更好的格局,沖突次數(shù)更少,最后一行顯示的是八皇后的一個(gè)正確解 沖突數(shù)為 0

    運(yùn)行截圖



    本文主要簡(jiǎn)單闡述爬山法的基本算法思想,并給出用此算法實(shí)現(xiàn)八皇后問題詳細(xì)過程

    最基本的爬上搜索算法表示:(節(jié)選自《人工智能》第二版):

    function?HILL-CLIMBING(problem)?return?a state thate is a locak maximum
    ????inputs:?problem
    ????local variables:?current, a node?
    ?????????????????????????neighbor,a node
    ????current?= MakeNode(INITAL-STATE(problem));
    ????loop do
    ????????neighbor?= a highest-valued successor of?current?;
    ????????if?VALUE[neighbor] <= VALUE[current]?then return?STATE[current];
    ????????current?=?neighbor?;

    算法特點(diǎn):

    ??????? 爬山法是一個(gè)向值增加的方向持續(xù)移動(dòng)的簡(jiǎn)單循環(huán)過程--類似于登高,它將會(huì)在到達(dá)一個(gè)“峰頂”時(shí)終止,此時(shí)相鄰狀態(tài)中沒有比它更高的值。這個(gè)算法不會(huì)維護(hù)搜索樹,因此當(dāng)前節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)只需要記錄當(dāng)前狀態(tài)和它的目標(biāo)函數(shù)值,它不會(huì)前瞻與當(dāng)前狀態(tài)不直接相鄰的那些狀態(tài)的值。這里更高的值是根據(jù)具體的應(yīng)用場(chǎng)景來定的,準(zhǔn)確的說是更接近目標(biāo)狀態(tài)的值,由我們?cè)O(shè)置的啟發(fā)式函數(shù)來決定哪個(gè)值更好,比如我們求解八皇后問題更高的值就是當(dāng)前格局中皇后沖突對(duì)數(shù)最少的情況


    算法局限性:

    ????? 爬山法屬于一種局部的貪婪搜索方法,當(dāng)它在搜索過程中遇到了局部最大值就很難繼續(xù)向下搜索了,局部極大值是一個(gè)比它的每個(gè)鄰居狀態(tài)都高得到峰頂,但是比全局最大值(我們要到達(dá)的最終狀態(tài))要低,爬山法算法到達(dá)局部極大值附近就會(huì)被拉向峰頂,然后卡在局部極大值處無處可走。因此產(chǎn)生了爬山法的變種如隨機(jī)爬山法及其變種如隨機(jī)爬山法,隨機(jī)重新開始的爬山法,模擬退火搜索能夠非常有效的解決N皇后問題。

    求解八皇后問題:

  • #-*- coding: utf-8 -*-
  • import random
  • #函數(shù)一:參數(shù)為當(dāng)前棋盤布局狀態(tài),根據(jù)布局判斷當(dāng)前八皇后布局存在沖突的皇后對(duì)數(shù)
  • def get_numof_conflict(status):
  • num = 0
  • for i in range(len(status)):
  • for j in range(i + 1,len(status)):
  • if status[i] == status[j]:
  • num += 1
  • offset = j - i
  • if abs(status[i]-status[j]) == offset:
  • num += 1
  • return num
  • #函數(shù)二:參數(shù)為當(dāng)前棋盤布局狀態(tài),利用爬山法思想選擇鄰居狀態(tài)最好的布局并返回
  • def hill_climbing(status):
  • convert = {}
  • length = len(status)
  • for col in range(length):
  • best_move = status[col]
  • for row in range(length):
  • if status[col] == row:
  • continue
  • status_copy = list(status)
  • status_copy[col] = row
  • convert[(col,row)] = get_numof_conflict(status_copy)
  • answers = [] #最佳后繼集合
  • conflict_now = get_numof_conflict(status) #當(dāng)前皇后沖突對(duì)數(shù)
  • #遍歷存儲(chǔ)所有可能后繼的字典,找出最佳后繼
  • for key,value in convert.iteritems():
  • if value < conflict_now:
  • conflict_now = value
  • for key,value in convert.iteritems():
  • if value == conflict_now:
  • answers.append(key)
  • #如果最佳后繼集合元素大于一個(gè) 隨機(jī)選擇一個(gè)
  • if len(answers) > 0:
  • x = random.randint(0,len(answers)-1)
  • col = answers[x][0]
  • row = answers[x][1]
  • status[col] = row
  • return status
  • #函數(shù)三:求得八皇后滿足沖突數(shù)為0的一個(gè)解,循環(huán)輸出每一步的后繼集合 直到不存在沖>突為止
  • def Queens():
  • status = [0,1,2,3,4,5,6,7] #初始狀態(tài)所有皇后都在對(duì)角線
  • #當(dāng)存在沖突的個(gè)數(shù)大于0時(shí) 循環(huán)求解最佳后繼 直到找到八皇后解
  • while get_numof_conflict(status) > 0:
  • status = hill_climbing(status)
  • print status
  • print get_numof_conflict(status)
  • print "the answer is"
  • print
  • print status
  • if __name__ == '__main__':
  • Queens()
  • 代碼說明 :

    (1)啟發(fā)式耗散函數(shù)?get_numof_conflict求出可以彼此攻擊2的皇后對(duì)的數(shù) ?hill_climbing是算法中爬山過程的實(shí)現(xiàn),convert字典中存儲(chǔ)的鍵是所有可能后繼狀態(tài),值是此狀態(tài)對(duì)應(yīng)的皇后沖突對(duì)數(shù),后面通過遍歷來找到最佳后繼。爬山法算法通常在最佳后繼集合中隨機(jī)選擇一個(gè)進(jìn)行擴(kuò)展,如果這樣的后繼多于一個(gè)的話

    (2)? 棋盤的排列用列表 status 表示, 依次表示第一列第二列到第n列的擺放位置。 如列表[0,2,1] 表示3*3矩陣第一列皇后放在最下面一格,第二列放在最上面一格,第三列放在中間一格

    (3) 運(yùn)行結(jié)果說明:初始狀態(tài)每個(gè)皇后都在次對(duì)角線上 每次運(yùn)行程序?qū)⑤敵銮蠼庖粋€(gè)八皇后正確解的爬山法實(shí)現(xiàn)過程 ,依次輸出求解過程每一個(gè)最佳選擇的鄰居狀態(tài)和其存在的皇后沖突對(duì)數(shù),可以看出在求解過程中 不斷爬山的過程--每進(jìn)行一步都達(dá)到一個(gè)更好的格局,沖突次數(shù)更少,最后一行顯示的是八皇后的一個(gè)正確解 沖突數(shù)為 0

    運(yùn)行截圖



    總結(jié)

    以上是生活随笔為你收集整理的爬山法实现 八皇后问题 (Python 实现)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。