第一次尝试发表文章,各位大佬多多指教!
八皇后问题
问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题。
这是第一次接触算法题,这个程序是按照自己对这个问题的处理方法,用程序来表达构建,想法比较简单也是python语言初学者,代码没有那么简便凑合看看
我的算法是:对每个皇后所占的地方进行判断,行,列,斜线进行限定如图是第一个皇后可能选择的位置,黄色方块代表其攻击范围,这样第二个皇后的位置只能选择空白方格。
由此我定义俩个二维数组(不清楚python中是否叫二维数组,使用的是numpy库创建),data和opinion,一个为全0,若皇后占据这个位置则变为1;另一个全为True,皇后所占据的位置以及她的攻击范围变为False。这样后面的皇后只能选择True的位置进行摆放,以此类推
以下是部分主要代码图,算法代码在最后
后面几个皇后以此类推即可。
import queenjudgmen
if __name__ == '__main__':
import numpy as np
#创建一个data数据存放皇后位置,一个opinion数据判断是否可摆放的位置
data = np.zeros((8,8),dtype=int)
opinion = np.ones((8,8),dtype=bool)
#设置第一个皇后
#判断opinion表中是否还存在可摆放的位置
firstlist = queenjudgmen.findlist(opinion)
#设置计算可行排列的个数的变量
num = 0
for firstindex in firstlist:
#设置行,列的值
firstone = queenjudgmen.resultset(firstindex, 0)
firsttwo = queenjudgmen.resultset(firstindex, 1)
#对原先的data数据和opinion数据复制
firstdata = data.copy()
firstopinion = opinion.copy()
#进行位置的判断,返回tuple类型的结果
firstresult = queenjudgmen.algjudegment(firstdata,firstopinion,firstone,firsttwo)
#拆分tuple类型数据
firstdata = queenjudgmen.resultset(firstresult, 0)
firstopinion = queenjudgmen.resultset(firstresult, 1)
#将已摆放的位置进行封锁,以免后续循环重复一样的结果
opinion[firstone][firsttwo] = False
#设置第二个皇后
secondlist = queenjudgmen.findlist(firstopinion)
#判断如果没有可摆放的位置时,跳过此次循环
if secondlist == 0:
continue
else:
for secondindex in secondlist:
secondone = queenjudgmen.resultset(secondindex, 0)
secondtwo = queenjudgmen.resultset(secondindex, 1)
seconddata = firstdata.copy()
secondopinion = firstopinion.copy()
secondresult = queenjudgmen.algjudegment(seconddata, secondopinion, secondone, secondtwo)
seconddata = queenjudgmen.resultset(secondresult, 0)
secondopinion = queenjudgmen.resultset(secondresult, 1)
firstopinion[secondone][secondtwo] = False
#设置第三个皇后
thirdlist = queenjudgmen.findlist(secondopinion)
if thirdlist == 0:
continue
else:
for thirdindex in thirdlist:
thirdone = queenjudgmen.resultset(thirdindex, 0)
thirdtwo = queenjudgmen.resultset(thirdindex, 1)
thirddata = seconddata.copy()
thirdopinion = secondopinion.copy()
thirdresult = queenjudgmen.algjudegment(thirddata, thirdopinion, thirdone, thirdtwo)
thirddata = queenjudgmen.resultset(thirdresult, 0)
thirdopinion = queenjudgmen.resultset(thirdresult, 1)
secondopinion[thirdone][thirdtwo] = False
#设置第四个皇后
fourlist = queenjudgmen.findlist(thirdopinion)
if fourlist == 0:
continue
else:
for fourindex in fourlist:
fourone = queenjudgmen.resultset(fourindex, 0)
fourtwo = queenjudgmen.resultset(fourindex, 1)
fourdata = thirddata.copy()
fouropinion = thirdopinion.copy()
fourresult = queenjudgmen.algjudegment(fourdata, fouropinion, fourone, fourtwo)
fourdata = queenjudgmen.resultset(fourresult, 0)
fouropinion = queenjudgmen.resultset(fourresult, 1)
thirdopinion[fourone][fourtwo] = False
#设置第五个皇后
fifthlist = queenjudgmen.findlist(fouropinion)
if fifthlist == 0 :
continue
else:
for fifthindex in fifthlist:
fifthone = queenjudgmen.resultset(fifthindex, 0)
fifthtwo = queenjudgmen.resultset(fifthindex, 1)
fifthdata = fourdata.copy()
fifthopinion = fouropinion.copy()
fifthresult = queenjudgmen.algjudegment(fifthdata, fifthopinion, fifthone, fifthtwo)
fifthdata = queenjudgmen.resultset(fifthresult, 0)
fifthopinion = queenjudgmen.resultset(fifthresult, 1)
fouropinion[fifthone][fifthtwo] = False
#设置第六个皇后
sixthlist = queenjudgmen.findlist(fifthopinion)
if sixthlist == 0:
continue
else:
for sixthindex in sixthlist:
sixthone = queenjudgmen.resultset(sixthindex, 0)
sixthtwo = queenjudgmen.resultset(sixthindex, 1)
sixthdata = fifthdata.copy()
sixthopinion = fifthopinion.copy()
sixthresult = queenjudgmen.algjudegment(sixthdata, sixthopinion, sixthone, sixthtwo)
sixthdata = queenjudgmen.resultset(sixthresult, 0)
sixthopinion = queenjudgmen.resultset(sixthresult, 1)
fifthopinion[sixthone][sixthtwo] = False
#设置第七个皇后
seventhlist = queenjudgmen.findlist(sixthopinion)
if seventhlist == 0 :
continue
else:
for seventhindex in seventhlist:
seventhone = queenjudgmen.resultset(seventhindex, 0)
seventhtwo = queenjudgmen.resultset(seventhindex, 1)
seventhdata = sixthdata.copy()
seventhopinion = sixthopinion.copy()
seventhresult = queenjudgmen.algjudegment(seventhdata, seventhopinion, seventhone, seventhtwo)
seventhdata = queenjudgmen.resultset(seventhresult, 0)
seventhopinion = queenjudgmen.resultset(seventhresult, 1)
sixthopinion[seventhone][seventhtwo] = False
#设置第八个皇后
eighthlist = queenjudgmen.findlist(seventhopinion)
if eighthlist == 0:
continue
else:
for eighthindex in eighthlist:
eighthone = queenjudgmen.resultset(eighthindex, 0)
eighthtwo = queenjudgmen.resultset(eighthindex, 1)
eighthdata = seventhdata.copy()
eighthopinion = seventhopinion.copy()
eighthresult = queenjudgmen.algjudegment(eighthdata, eighthopinion, eighthone, eighthtwo)
eighthdata = queenjudgmen.resultset(eighthresult, 0)
eighthopinion = queenjudgmen.resultset(eighthresult, 1)
seventhopinion[eighthone][eighthtwo] = False
num+=1
print(num)
上面是主要代码,算法代码设计了三个函数,一个是判断opinion中是否还存在Ture值,一个是行,列斜线条件的限定,总结一个规律:
行,列不用说了。
左斜线:\ (行或列)任意减一到0时,(行或列)任意加一为7时。
右斜线:/ 行加列减(最大为7,最小为0),行减列加(最小为0,最大为7)
第三份函数是获取的list中逐个输出
若代码存在问题多多指教
附加:
还是加多个算法函数代码
import numpy as np
def findlist(opinion):
namelist = list(zip(*np.where( opinion == True )))
return namelist
def algjudegment(data,opinion,row,train):
data[row][train] = 1
opinion[row][train] = False
#行的条件限定
newrow = row
newtrain = train
while newtrain != 0:
newtrain-=1
opinion[row][newtrain] = False
newrow = row
newtrain = train
while newtrain != 7:
newtrain+=1
opinion[row][newtrain] = False
#列的条件限定
newrow = row
newtrain = train
while newrow != 0:
newrow-=1
opinion[newrow][train] = False
newrow = row
newtrain = train
while newrow != 7:
newrow+=1
opinion[newrow][train] = False
#左斜线条件的限定 \
newrow = row
newtrain = train
while newrow != 0 and newtrain != 0:
newrow-=1
newtrain-=1
opinion[newrow][newtrain] = False
newrow = row
newtrain = train
while newrow != 7 and newtrain != 7:
newrow+=1
newtrain+=1
opinion[newrow][newtrain] = False
#右斜线的条件限定 /
newrow = row
newtrain = train
while newrow != 7 and newtrain != 0:
newrow+=1
newtrain-=1
opinion[newrow][newtrain] = False
newrow = row
newtrain = train
while newrow != 0 and newtrain != 7:
newrow-=1
newtrain+=1
opinion[newrow][newtrain] = False
return data,opinion
def resultset(resulttuple,number):
if number == 0:
return resulttuple[0]
elif number == 1:
return resulttuple[1]
else:
return "数据选择不正确"