八皇后问题-用Python实现

  • 回溯算法
  • 代码实现(我的- -)
  • 特定条件的八皇后问题
  • 代码实现(百科上的)
  • 收获


回溯算法

简述一下基本实现方法:
1.从第一行开始,放置第一个皇后
2.下一行,从第一列开始,依次判断这个位置和已有的皇后位置是否冲突,如果不冲突,放下。
3.如果到这一行的最后一列依然冲突,则返回上一行,并从上一行的位置开始,探索剩余列的可能性。
4.如果到最后一行,解出一个解,记录下以后,返回上一行,继续探索新的解
具体图解可以参考八皇后问题回溯法和迭代法

代码实现(我的- -)

#判断在该位置是否成立
def isright(row,col,k):
    if(row in k):
        return False
    if(col in k.values()):
        return False
    for i in k:
        if(row!=i):
            if(abs((col-a[i])/(row-i))==1):
                return False               
    return True

#求出所有92种情况
import copy
a={}
i=0
j=0
c=0
ans=[]
count=0
while(i<8):
    while(j<8):
        if(isright(i,j,a)):
            a[i]=j
            if(i==7):
                answ=[]
                answ.append(a)
                ans.append(copy.deepcopy(answ))#注意list.append在while中的使用
                c+=1
                #print(a)
                del a[i]
                i=i-1
                
                j=a[i]+1
                del a[i]
            else:
                i=i+1
                j=0
            break
            
        j+=1
    if(j==8):
        if(i==0):
            break
        elif(i==1):
            i=i-1
            j=a[i]+1
            del a[i]
        else:
            i=i-1
            j=a[i]+1
            del a[i]
#结果在ans中

特定条件的八皇后问题

在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 1848 年提出著名的八皇后问题:即在 8 × 8 的棋盘上摆放八个皇后,使其不能互相攻击 —— 即任意两个皇后都不能处于同一行、同一列或同一条斜线上。 要求第一行的皇后放在指定列,问有多少种摆法?

row=0
column=int(input())-1
for i in range(0,len(ans)):
    for j in (ans[i]):
        for k in j:
            if (column==j[k] and row==k):
                count+=1
         
print(count)

代码实现(百科上的)

def queen(A, cur=0):
    if cur == len(A):
        print(A)
        return 0
    for col in range(len(A)):  # 遍历当前行的所有位置
        A[cur] = col
        for row in range(cur):  # 检查当前位置是否相克
            if A[row] == col or abs(col - A[row]) == cur - row:
                break
        else:  # 如果完成了整个遍历,则说明位置没有相克
            queen(A, cur+1)  # 计算下一行的位置
queen([None]*8)

以上,刚开始很难懂,不知道他是怎么实现回溯的。

老师给我推荐了一个网站:python可视化!! 太牛了!!

python八皇后穷举法 八皇后问题python解决_八皇后问题


当走不通的时候,递归的函数返回0,于是上一行就按照原来的节奏继续往下。

包括最后cur==len(A) return 0也是一样的

收获

  • 在for循环中,不能随意改变循环变量的值,改用while
  • 在while循环中,List.append(a)由于是引用a的地址,所以会导致覆盖。要利用copy~
  • 哇哦~for还能和else搭配:
当for循环完整执行后,执行else后的语句。
如果for循环中遇到break,则不执行else后的语句。
  • 我的思维就像刚学c一样,弱爆了
  • 我对回溯递归有了更深的理解,下次就这么干,不用while了( • ̀ω•́ )✧