Reputation: 227
I have tried solving this problem with backtracking and it prints all possible solutions.
Two questions came up:
1.Can i implement n queen using other techniques?
2.Is it possible to make the code below print only the first solution and then terminate?
My current code uses backtracking:
n = 8
x = [-1 for x in range(n)]
def safe(k,i):
for j in xrange(k):
if x[j] == i or abs(x[j] - i) == abs(k - j) :
return False
return True
def nqueen(k):
for i in xrange(n):
if safe(k,i):
x[k] = i
if k == n-1:
print "SOLUTION", x
else:
nqueen(k+1)
nqueen(0)
Note: I am interested in techniques that do not depend on a particular programming language.
Upvotes: 2
Views: 4945
Reputation: 9107
According to Wikipedia, you can do using heuristics:
This heuristic solves N queens for any N ≥ 4. It forms the list of numbers for vertical positions (rows) of queens with horizontal position (column) simply increasing. N is 8 for eight queens puzzle.
This heuristics is O(n)
since it's just printing the result after some if
statements.
Regarding your second question: "Is it possible to make code below to print only first solution and then terminate?"
You can just call sys.exit(0)
after you print:
import sys
n = 8
x = [-1 for x in range(n)]
def safe(k,i):
for j in xrange(k):
if x[j] == i or abs(x[j] - i) == abs(k - j) :
return False
return True
def nqueen(k):
for i in xrange(n):
if safe(k,i):
x[k] = i
if k == n-1:
print "SOLUTION", x
sys.exit(0)
else:
nqueen(k+1)
nqueen(0)
or, alternatively you can return a value and then propagate the value if it indicates termination:
n = 8
x = [-1 for x in range(n)]
def safe(k,i):
for j in xrange(k):
if x[j] == i or abs(x[j] - i) == abs(k - j) :
return False
return True
def nqueen(k):
for i in xrange(n):
if safe(k,i):
x[k] = i
if k == n-1:
print "SOLUTION", x
return True # Found a solution, send this good news!
else:
if nqueen(k+1): # Good news!
return True # Share the good news to parent!
return False # We have searched every possible combinations, and I regret to tell you that I could not find any solution.
nqueen(0)
As for the time complexity, since it's a complete search, it's n^n
. Although due to the pruning (using safe(k,i)
), in practice it's a lot faster.
Upvotes: 4
Reputation: 347
The question of solving N-queens without backtracking has another interesting question attached to it. Are there almost perfect queen placing heuristics such that, in a backtracking framework, you nearly always find a valid configuration? This is equivalent to saying that the heuristic almost always tells you the correct square to place the next queen on the board. This heuristic is much more interesting than the known closed form solution that gives a valid configuration for all values of N (except N=2 and 3, obviously).
The analysis of almost perfect minimum backtracking heuristics is an issue which has been studied in literature. The most important references are [Kalé 90] and [San Segundo 2011]. The best heuristic to place the next queen in the backtracking framework seems to be the following:
Here to close a diagonal refers to cancel all its available squares.
Upvotes: 2