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

歡迎訪問 生活随笔!

生活随笔

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

python

八皇后问题python_python求解八皇后问题

發(fā)布時(shí)間:2024/9/18 python 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 八皇后问题python_python求解八皇后问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天突然有個(gè)行外的朋友扔了一張圖給我,希望我能幫他用python做一下這個(gè)作業(yè)——八皇后問題。

八皇后問題是一種經(jīng)典的數(shù)學(xué)求解問題,規(guī)則是在8×8的國際象棋棋盤上,要求在每一行(或者每一列)放置一個(gè)皇后,且能做到在水平方向、豎直方向和斜方向都沒有沖突。

關(guān)于這個(gè)問題的編程實(shí)現(xiàn),首先我們將棋盤等價(jià)于一個(gè)8×8的矩陣(二維數(shù)組),矩陣中的點(diǎn)(x,y)指代棋盤第x行y列的位置。而沖突的自然語言定義是同行、同列或同對(duì)角線,那么這個(gè)邏輯換算到程序中,我們可以認(rèn)為兩點(diǎn)(x1,y1)和(x2,y2)至少滿足以下四個(gè)條件之一:

同行:x1 = x2

同列:y1 = y2

斜線正方向:x1 + y1 = x2 + y2

斜線反方向:x1 - y1 = x2 - y2

一開始看到這個(gè)問題的規(guī)則,我有些小瞧了它的難度,以為通過逐行排除過濾就可以推出可行解,因此稍微整理一下思路就草草開干了,最后毫無疑問地踩了不少坑。在這個(gè)問題上,逐行定點(diǎn)的方式是可行的,關(guān)鍵在于八皇后問題在這種求解方式下存在死解,即可能在中途某行進(jìn)行取點(diǎn)時(shí),發(fā)現(xiàn)該行上沒有一個(gè)點(diǎn)符合要求。因此,八皇后問題的程序求解歸根到底其實(shí)是一個(gè)回溯遍歷的問題。通過回溯,我重新調(diào)整了思路:

1、從第一行開始,按照沖突規(guī)則過濾出每行目前可選的位置點(diǎn)集合,取一點(diǎn);

2、如果遇到死解,即當(dāng)前行沒有符合要求的可選點(diǎn),則回退到上一行,重新取點(diǎn);

3、直到第八行取到了符合要求的安全位置,求解成功。

捋清了這個(gè)編程思路,利用python實(shí)現(xiàn)也就不難了。

import random

import math

# 棋盤初始化

# params

# -d: 矩陣的大小

def initial_chessboard(d):

chessboard = [[(x+1, y+1) for y in range(d)] for x in range(d)]

return chessboard

# 指定行過濾出可選位置并隨機(jī)選取一個(gè),作為本行queen的填入位置

# params

# -chessboard:棋盤矩陣

# -rowIndex: 指定矩陣的某一行的序號(hào)

# -placePicked:已被選的位置

# -exclusions: 回溯時(shí)的排除項(xiàng)列表

def filter_and_pick_place(chessboard, rowIndex, placePicked, exclusions):

# 取到該行

row = chessboard[rowIndex]

# 在后續(xù)過程中保存本行過濾完的可選位置

alternative = []

if len(placePicked) != 0:

# 遍歷本行的每一項(xiàng)

for column in row:

# 這個(gè)變量標(biāo)志了該位置是否可用,初始化的時(shí)候是False,可用

available = True

# 遍歷已被選的位置

for item in placePicked:

# 只要有一個(gè)出現(xiàn)同列或同對(duì)角線,或位于排除項(xiàng)列表中時(shí),將available標(biāo)記為不可用

if column[1] == item[1] or column[0]+column[1] == item[0]+item[1] or \

column[0]-column[1] == item[0]-item[1] or column in exclusions:

available = False

# 該位置可用,添加進(jìn)可用項(xiàng)數(shù)組里

if available:

alternative.append(column)

else:

alternative = row

if len(alternative) == 0:

# 死解,返回0,指示不成功

return 0

else:

# 活解,隨機(jī)挑選位置點(diǎn),返回1,指示成功

randomIndex = math.floor(len(alternative) * random.random())

pick = alternative[randomIndex]

placePicked.append(pick)

return 1

# 根據(jù)最終結(jié)果用圖表展示出來

# params

# -positions: 最終挑選的位置列表

def generate_figure(positions):

figureSring = ''

for row in range(8):

for col in range(8):

if (row+1, col+1) in positions:

figureSring += 'x '

else:

figureSring += '- '

figureSring += '\n'

return figureSring

if __name__ == '__main__':

chessboard = initial_chessboard(8)

placePicked = []

exclusions = [[] for i in range(8)]

row = 0

while row < 8:

success = filter_and_pick_place(chessboard, row, placePicked, exclusions[row])

if success == 1:

# 沒有遇到死解,繼續(xù)往下

row += 1

else:

# 遇到了死解,回退到上一行并且將死解的點(diǎn)存入排除項(xiàng)中,重新選點(diǎn)

row -= 1

exclusions[row].append(placePicked.pop())

# 由于是自上而下選點(diǎn)的方式,當(dāng)上一行的點(diǎn)重新選取時(shí),后一行的排除項(xiàng)已經(jīng)沒有意義了,清空

if row < 7:

exclusions[row+1] = []

# 打印出棋盤

print(generate_figure(placePicked))

最終結(jié)果如下:

$ python eight_queens.py

- - - x - - - -

- - - - - - - x

- - - - x - - -

- - x - - - - -

x - - - - - - -

- - - - - - x -

- x - - - - - -

- - - - - x - -

總結(jié)

以上是生活随笔為你收集整理的八皇后问题python_python求解八皇后问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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