Processing math: 100%

Wednesday, May 6, 2020

n-queens in Fusion

In a nice post on LinkedIn by Alireza Soroudi the author presents a short GAMS integer model for the classical n-queens puzzle: place the maximal number of non-attacking queens on an n\times n chessboard.

We couldn't resist writing it up in Python Fusion as well.

from mosek.fusion import *
import numpy as np
import sys
n = int(sys.argv[1])
M = Model()
x = M.variable("x", [n,n], Domain.binary())
M.objective(ObjectiveSense.Maximize, Expr.sum(x))
M.constraint(Expr.sum(x, 0), Domain.lessThan(1))
M.constraint(Expr.sum(x, 1), Domain.lessThan(1))
for k in range(-n+1,n):
M.constraint(Expr.dot(x, np.diag([1]*(n-abs(k)), k)), Domain.lessThan(1))
M.constraint(Expr.dot(x, np.fliplr(np.diag([1]*(n-abs(k)), k))), Domain.lessThan(1))
M.solve()
print(np.array2string(np.fromiter(
map(lambda u: '\u2655' if u>0.5 else '_', x.level()), dtype='<U1').reshape((n,n)),
formatter={'str_kind': lambda u: u}))
view raw nqueens.py hosted with ❤ by GitHub
And here is the solution we get for n=8:
[[_ ♕ _ _ _ _ _ _]
 [_ _ _ _ _ ♕ _ _]
 [♕ _ _ _ _ _ _ _]
 [_ _ _ _ _ _ ♕ _]
 [_ _ _ ♕ _ _ _ _]
 [_ _ _ _ _ _ _ ♕]
 [_ _ ♕ _ _ _ _ _]
  [_ _ _ _ ♕ _ _ _]]