这个想法是尝试通过在棋盘的每一行中完全随机地放置女王来尝试解决“女王问题”,并看看解决它需要多少次重复。国际象棋棋盘可以是任何尺寸。
我的想法是创建s列表,每个列表包含s“空”字符(下划线)。然后为每一行随机选择一个位置插入皇后(“I”值)然后标记下面的所有位置和对角线向下(我要逐行,所以我不必打扰上面的行)如果在任何迭代中,女王的随机选择位置与该行中任何X的位置匹配,我从头开始新的棋盘。
我有类似的东西,但似乎卡在第19行(标有注释),但它没有给我任何错误。有什么不对?另外,我的解决方案(除了那条线)是否正确?
from random import *
#Success flag
success = 0
#Trials counter
trials = 0
s = input ("enter board size\n")
s = int(s)
block = 1 #blockade
queen = 2 #queen
board = [[0 for x in range(s)] for y in range(s)]
while success == 0:
for y in range (0, s-1):
pos = randint(0,s-1) #line 19
if board[y][pos] != block:
board[y][pos] = queen
a = 1
for z in range (y, s-2):
board[z + 1][pos] = block
if pos - a >= 0:
board[z + 1][pos - a] = block
if pos + a <= s-1:
board[z + 1][pos + a] = block
a = a + 1
success = 1
else:
success = 0
#Printing board
for y in range (0, s-1):
print (board[y])
print ("Number of trials:\n")
print (trials)
答案 0 :(得分:2)
一些问题:
range
函数的第二个参数代表不访问的第一个数字,所以大多数时候你只有一个简短。查看更正的代码,并在我做出更改的评论中
import random
s = input ("enter board size\n")
s = int(s)
trials = 0
block = 1
queen = 2
# add some maximum to the number of attempts
max_trials = 100000
success = 0
# add safety measure to avoid infinite looping
while success == 0 and trials <= max_trials:
# initialise board before every trial
board = [[0 for x in range(s)] for y in range(s)]
# assume success until failure
success = 1
# count trials
trials += 1
for y in range (0, s): # use correct range
# get the fields that are still available in this row
available = [x for x, i in enumerate(board[y]) if i == 0]
if len(available) == 0:
success = 0
# exit for loop, you want to start a next trial
break
# choose a random position among available spots only
pos = available[random.randint(0, len(available)-1)]
board[y][pos] = queen
a = 1
for z in range (y+1, s): # use correct range
board[z][pos] = block
if pos - a >= 0:
board[z][pos - a] = block
if pos + a < s:
board[z][pos + a] = block
a = a + 1
for y in range (0, s): # use correct range
print (board[y])
print ("Number of trials:", trials)
上查看它
答案 1 :(得分:2)
这是一个简短的解决方案,基于对放置的皇后坐标进行算术运算:
import random, itertools
def clashes(p,q):
a,b = p
c,d = q
return a == c or b == d or abs(a-c) == abs(b-d)
def solution(queens):
#assumes len(queens) == 8
return not any(clashes(p,q) for p,q in itertools.combinations(queens,2))
def randSolve():
counter = 0
while True:
counter += 1
queens = [(i,random.randint(1,8)) for i in range(1,9)]
if solution(queens): return counter, queens
print(randSolve())
上次我跑了,我得到了:
(263528, [(1, 4), (2, 7), (3, 3), (4, 8), (5, 2), (6, 5), (7, 1), (8, 6)])
意味着在263527次失败后遇到第一个解决方案。平均而言,在获得成功之前,您可能会遇到182360次失败。
答案 2 :(得分:0)
尝试不同的行并且这次失败后,你必须创建一个新的空板,如果成功为0,你应该打破for循环。
while success == 0:
board = [[0 for x in range(s)] for y in range(s)]
for y in range (0, s):
pos = randint(0,s-1) #line 19
if board[y][pos] != block:
board[y][pos] = queen
for i in range(y+1, s):
board[i][pos] = block
success = 1
else:
success = 0
break
trials += 1
您可以遵循相同的逻辑来实现对角线情况。