Coverage for moptipy / examples / bitstrings / nqueens.py: 22%
91 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""
2The N-Queens problem.
4The N-Queens problem is defined for bit strings of length n = N ** 2.
5A bit string `x` is mapped to a chess board and a queen is placed for any bit
6of value 1. The goal is to place N queens such that they cannot attack each
7other. The total number of queens on the board be Q(x) is the number of `True`
8bits, which might be more or less than N.
9We also count the number ez(x) of queens in every single row, column, and
10diagonal z of the chess board. The minimization version of the N-Queens
11problem is then `N - Q(x) + N sum_(all z) max(0, ez(x) - 1)`.
12The N-Queens problems are attested moderate difficulty in [1].
14Here, `N` is stored in the `k`-value of the benchmark function instances.
16The best possible objective value of this function is achieved if exactly
17`k=N` queens are positioned such that none can beat any other queen. The
18objective function then returns 0.
20The worst case is if a queen is placed on every single field, i.e., if we have
21`n = k*k` queens on the field. Then, the objective value will be
22`(((((k - 2) * 4) + 1) * k) + 3) * k`.
241. Carola Doerr, Furong Ye, Naama Horesh, Hao Wang, Ofer M. Shir, and Thomas
25 Bäck. Benchmarking Discrete Optimization Heuristics with IOHprofiler.
26 Applied Soft Computing Journal. 88:106027. 2020.
27 doi: https://doi.org/10.1016/j.asoc.2019.106027
282. Thomas Weise, Zhize Wu, Xinlu Li, Yan Chen, and Jörg Lässig. Frequency
29 Fitness Assignment: Optimization without Bias for Good Solutions can be
30 Efficient. *IEEE Transactions on Evolutionary Computation (TEVC)*.
31 27(4):980-992. August 2023.
32 doi: https://doi.org/10.1109/TEVC.2022.3191698
34This is code is part of the research work of Mr. Jiazheng ZENG (曾嘉政),
35a Master's student at the Institute of Applied Optimization
36(应用优化研究所) of the School of Artificial
37Intelligence and Big Data (人工智能与大数据学院) at
38Hefei University (合肥大学) in
39Hefei, Anhui, China (中国安徽省合肥市) under the supervision of
40Prof. Dr. Thomas Weise (汤卫思教授).
41"""
42from typing import Callable, Final, Iterator, cast
44import numba # type: ignore
45import numpy as np
46from pycommons.types import check_int_range
48from moptipy.examples.bitstrings.bitstring_problem import (
49 SquareBitStringProblem,
50)
53@numba.njit(nogil=True, cache=True)
54def nqueens(x: np.ndarray, k: int) -> int:
55 """
56 Evaluate the N-Queens objective function.
58 :param x: the np array representing the board (bit string)
59 :param k: the total number of queens (dimension of the problem)
60 :return: the penalty score
62 >>> nqueens(np.array([False, True, False, False,
63 ... False, False, False, True,
64 ... True, False, False, False,
65 ... False, False, True, False]), 4)
66 0
68 >>> nqueens(np.array([False, False, True, False,
69 ... True, False, False, False,
70 ... False, False, False, True,
71 ... False, True, False, False]), 4)
72 0
74 >>> nqueens(np.array([False, False, False, False,
75 ... False, False, False, False,
76 ... False, False, False, False,
77 ... False, False, False, False]), 4)
78 4
80 >>> nqueens(np.array([ True, False, False, False,
81 ... False, False, False, False,
82 ... False, False, False, False,
83 ... False, False, False, False]), 4)
84 3
86 # two queens, but in the same row, which gives 2 + 4
87 >>> nqueens(np.array([ True, True, False, False,
88 ... False, False, False, False,
89 ... False, False, False, False,
90 ... False, False, False, False]), 4)
91 6
93 # three queens, but 2 in the same row, 2 in the same column, and 2 in one
94 # diagonal, which gives 1 + 4 + 4 + 4
95 >>> nqueens(np.array([ True, True, False, False,
96 ... True, False, False, False,
97 ... False, False, False, False,
98 ... False, False, False, False]), 4)
99 13
101 # four queens, but 3 in the same row, 2 in the same column, and 2 in one
102 # diagonal, which gives 0 + 8 + 4 + 4
103 >>> nqueens(np.array([ True, True, True, False,
104 ... True, False, False, False,
105 ... False, False, False, False,
106 ... False, False, False, False]), 4)
107 16
109 # five queens, but 4 in the same row, 2 in the same column, and 2 in one
110 # diagonal, which gives -1 + 12 + 4 + 4
111 >>> nqueens(np.array([ True, True, True, True,
112 ... True, False, False, False,
113 ... False, False, False, False,
114 ... False, False, False, False]), 4)
115 19
117 >>> nqueens(np.array([
118 ... False, False, False, True, False, False, False, False,
119 ... False, False, False, False, False, True, False, False,
120 ... False, False, False, False, False, False, False, True,
121 ... False, True, False, False, False, False, False, False,
122 ... False, False, False, False, False, False, True, False,
123 ... True, False, False, False, False, False, False, False,
124 ... False, False, True, False, False, False, False, False,
125 ... False, False, False, False, True, False, False, False,]), 8)
126 0
128 # five queens, but 4 in the same row, 2 in the same column, and 2 in one
129 # diagonal, which gives -1 + 12 + 4 + 4
130 >>> nqueens(np.array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 4)
131 19
133 # 16 bits, board width = 4, and 2 queens
134 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 4)
135 6
137 # 16 bits, board width = 4, and 2 queens
138 >>> nqueens(np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 4)
139 2
141 # 16 bits, board width = 4, and 2 queens
142 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0]), 4)
143 2
145 # 16 bits, board width = 4, and 3 queens
146 >>> nqueens(np.array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 4)
147 5
149 # 16 bits, board width = 4, and 4 queens
150 >>> nqueens(np.array([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 4)
151 12
153 # 16 bits, board width = 4, and 4 queens
154 >>> nqueens(np.array([0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 4)
155 12
157 # 16 bits, board width = 4, and 4 queens
158 >>> nqueens(np.array([0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0]), 4)
159 12
161 # 16 bits, board width = 4, and 4 queens
162 >>> nqueens(np.array([0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0]), 4)
163 20
165 # 16 bits, board width = 4, and 11 queens
166 >>> nqueens(np.array([1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1]), 4)
167 85
169 # 16 bits, board width = 4, and 8 queens
170 >>> nqueens(np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0]), 4)
171 52
173 # 16 bits, board width = 4, and 9 queens
174 >>> nqueens(np.array([1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0]), 4)
175 67
177 # 16 bits, board width = 4, and 10 queens
178 >>> nqueens(np.array([0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1]), 4)
179 78
181 # 16 bits, board width = 4, and 0 queens
182 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 4)
183 4
185 # 16 bits, board width = 4, and 16 queens
186 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 4)
187 156
189 # 25 bits, board width = 5, and 3 queens
190 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
191 ... 0, 0, 1, 0, 0, 0, 0, 0]), 5)
192 17
194 # 25 bits, board width = 5, and 1 queen
195 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
196 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
197 4
199 # 25 bits, board width = 5, and 4 queens
200 >>> nqueens(np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
201 ... 0, 0, 0, 0, 1, 1, 0, 0]), 5)
202 16
204 # 25 bits, board width = 5, and 1 queen
205 >>> nqueens(np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
206 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
207 4
209 # 25 bits, board width = 5, and 5 queens
210 >>> nqueens(np.array([1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
211 ... 0, 0, 0, 1, 0, 0, 1, 0]), 5)
212 25
214 # 25 bits, board width = 5, and 5 queens
215 >>> nqueens(np.array([0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0,
216 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
217 30
219 # 25 bits, board width = 5, and 5 queens
220 >>> nqueens(np.array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
221 ... 0, 0, 0, 0, 0, 0, 0, 1]), 5)
222 15
224 # 25 bits, board width = 5, and 5 queens
225 >>> nqueens(np.array([0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
226 ... 0, 1, 0, 0, 0, 0, 0, 0]), 5)
227 20
229 # 25 bits, board width = 5, and 15 queens
230 >>> nqueens(np.array([1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1,
231 ... 1, 1, 0, 1, 1, 0, 1, 1]), 5)
232 160
234 # 25 bits, board width = 5, and 22 queens
235 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,
236 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
237 283
239 # 25 bits, board width = 5, and 18 queens
240 >>> nqueens(np.array([1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1,
241 ... 1, 1, 1, 1, 1, 1, 0, 1]), 5)
242 217
244 # 25 bits, board width = 5, and 21 queens
245 >>> nqueens(np.array([0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
246 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
247 274
249 # 25 bits, board width = 5, and 0 queens
250 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
252 5
254 # 25 bits, board width = 5, and 25 queens
255 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
256 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
257 340
259 # 36 bits, board width = 6, and 2 queens
260 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 6)
262 4
264 # 36 bits, board width = 6, and 2 queens
265 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
267 4
269 # 36 bits, board width = 6, and 4 queens
270 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
271 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
272 14
274 # 36 bits, board width = 6, and 3 queens
275 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 ... 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
277 3
279 # 36 bits, board width = 6, and 6 queens
280 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
281 ... 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 6)
282 42
284 # 36 bits, board width = 6, and 6 queens
285 >>> nqueens(np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
286 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]), 6)
287 42
289 # 36 bits, board width = 6, and 6 queens
290 >>> nqueens(np.array([1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]), 6)
292 36
294 # 36 bits, board width = 6, and 6 queens
295 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
296 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1]), 6)
297 42
299 # 36 bits, board width = 6, and 17 queens
300 >>> nqueens(np.array([0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0,
301 ... 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1]), 6)
302 223
304 # 36 bits, board width = 6, and 13 queens
305 >>> nqueens(np.array([1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
306 ... 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0]), 6)
307 137
309 # 36 bits, board width = 6, and 20 queens
310 >>> nqueens(np.array([0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1,
311 ... 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1]), 6)
312 274
314 # 36 bits, board width = 6, and 11 queens
315 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1,
316 ... 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0]), 6)
317 103
319 # 36 bits, board width = 6, and 0 queens
320 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
322 6
324 # 36 bits, board width = 6, and 36 queens
325 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 6)
327 630
329 # 49 bits, board width = 7, and 1 queen
330 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
333 6
335 # 49 bits, board width = 7, and 2 queens
336 >>> nqueens(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
338 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
339 5
341 # 49 bits, board width = 7, and 3 queens
342 >>> nqueens(np.array([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
345 4
347 # 49 bits, board width = 7, and 4 queens
348 >>> nqueens(np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
349 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
350 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
351 17
353 # 49 bits, board width = 7, and 7 queens
354 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
355 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
356 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
357 70
359 # 49 bits, board width = 7, and 7 queens
360 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
361 ... 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
362 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 7)
363 35
365 # 49 bits, board width = 7, and 7 queens
366 >>> nqueens(np.array([0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
367 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
368 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 7)
369 42
371 # 49 bits, board width = 7, and 7 queens
372 >>> nqueens(np.array([0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0,
373 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
374 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
375 63
377 # 49 bits, board width = 7, and 25 queens
378 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0,
379 ... 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0,
380 ... 1, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 7)
381 437
383 # 49 bits, board width = 7, and 33 queens
384 >>> nqueens(np.array([1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0,
385 ... 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
386 ... 1, 1, 1, 1, 0, 1, 0, 1, 1, 0]), 7)
387 625
389 # 49 bits, board width = 7, and 24 queens
390 >>> nqueens(np.array([1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1,
391 ... 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0,
392 ... 0, 0, 1, 0, 0, 1, 1, 0, 0, 0]), 7)
393 403
395 # 49 bits, board width = 7, and 15 queens
396 >>> nqueens(np.array([0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1,
397 ... 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), 7)
399 209
401 # 49 bits, board width = 7, and 0 queens
402 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
403 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
404 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
405 7
407 # 49 bits, board width = 7, and 49 queens
408 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
409 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
410 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 7)
411 1050
413 # 64 bits, board width = 8, and 1 queen
414 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
415 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
416 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
417 ... 0, 0, 0]), 8)
418 7
420 # 64 bits, board width = 8, and 1 queen
421 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
422 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
423 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
424 ... 0, 0, 0]), 8)
425 7
427 # 64 bits, board width = 8, and 3 queens
428 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
429 ... 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
430 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
431 ... 0, 0, 0]), 8)
432 21
434 # 64 bits, board width = 8, and 6 queens
435 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
436 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
437 ... 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
438 ... 0, 0, 0]), 8)
439 42
441 # 64 bits, board width = 8, and 8 queens
442 >>> nqueens(np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
443 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
444 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
445 ... 0, 1, 0]), 8)
446 64
448 # 64 bits, board width = 8, and 8 queens
449 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
450 ... 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
451 ... 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
452 ... 0, 0, 0]), 8)
453 72
455 # 64 bits, board width = 8, and 8 queens
456 >>> nqueens(np.array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
457 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
458 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
459 ... 0, 1, 0]), 8)
460 56
462 # 64 bits, board width = 8, and 8 queens
463 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
464 ... 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
465 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
466 ... 0, 0, 0]), 8)
467 64
469 # 64 bits, board width = 8, and 20 queens
470 >>> nqueens(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
471 ... 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0,
472 ... 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1,
473 ... 0, 0, 0]), 8)
474 348
476 # 64 bits, board width = 8, and 46 queens
477 >>> nqueens(np.array([0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,
478 ... 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1,
479 ... 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
480 ... 1, 0, 1]), 8)
481 1074
483 # 64 bits, board width = 8, and 29 queens
484 >>> nqueens(np.array([1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
485 ... 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0,
486 ... 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0,
487 ... 0, 0, 1]), 8)
488 579
490 # 64 bits, board width = 8, and 20 queens
491 >>> nqueens(np.array([1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
492 ... 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
493 ... 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
494 ... 0, 0, 0]), 8)
495 300
497 # 64 bits, board width = 8, and 0 queens
498 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
499 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
500 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
501 ... 0, 0, 0]), 8)
502 8
504 # 64 bits, board width = 8, and 64 queens
505 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
506 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
507 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
508 ... 1, 1, 1]), 8)
509 1624
511 # 81 bits, board width = 9, and 1 queen
512 >>> nqueens(np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
513 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
515 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
516 8
518 # 81 bits, board width = 9, and 7 queens
519 >>> nqueens(np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
520 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
521 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
522 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 9)
523 56
525 # 81 bits, board width = 9, and 8 queens
526 >>> nqueens(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
527 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
528 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
529 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
530 73
532 # 81 bits, board width = 9, and 3 queens
533 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
534 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
535 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
536 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]), 9)
537 15
539 # 81 bits, board width = 9, and 9 queens
540 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
541 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
542 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
543 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 9)
544 81
546 # 81 bits, board width = 9, and 9 queens
547 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
548 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
549 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550 ... 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 9)
551 63
553 # 81 bits, board width = 9, and 9 queens
554 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
555 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
556 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
557 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 9)
558 90
560 # 81 bits, board width = 9, and 9 queens
561 >>> nqueens(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
562 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
563 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
564 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
565 72
567 # 81 bits, board width = 9, and 22 queens
568 >>> nqueens(np.array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
569 ... 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1,
570 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1,
571 ... 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 9)
572 428
574 # 81 bits, board width = 9, and 43 queens
575 >>> nqueens(np.array([0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
576 ... 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
577 ... 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1,
578 ... 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0]), 9)
579 1091
581 # 81 bits, board width = 9, and 18 queens
582 >>> nqueens(np.array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
583 ... 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0,
584 ... 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
585 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]), 9)
586 288
588 # 81 bits, board width = 9, and 24 queens
589 >>> nqueens(np.array([0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0,
590 ... 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
591 ... 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0,
592 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1]), 9)
593 444
595 # 81 bits, board width = 9, and 0 queens
596 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
597 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
598 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
599 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
600 9
602 # 81 bits, board width = 9, and 81 queens
603 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 9)
607 2376
609 # 100 bits, board width = 10, and 6 queens
610 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
613 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
614 ... 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
615 34
617 # 100 bits, board width = 10, and 7 queens
618 >>> nqueens(np.array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
620 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
621 ... 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
622 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]), 10)
623 43
625 # 100 bits, board width = 10, and 8 queens
626 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
627 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
628 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
629 ... 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
630 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
631 72
633 # 100 bits, board width = 10, and 6 queens
634 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
635 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
636 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
637 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
638 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 10)
639 34
641 # 100 bits, board width = 10, and 10 queens
642 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
643 ... 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
645 ... 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
646 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
647 140
649 # 100 bits, board width = 10, and 10 queens
650 >>> nqueens(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
651 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
652 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
653 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
654 ... 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
655 80
657 # 100 bits, board width = 10, and 10 queens
658 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0,
659 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
660 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
661 ... 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
662 ... 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0]), 10)
663 130
665 # 100 bits, board width = 10, and 10 queens
666 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0,
667 ... 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
668 ... 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
669 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
670 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
671 100
673 # 100 bits, board width = 10, and 50 queens
674 >>> nqueens(np.array([0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0,
675 ... 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0,
676 ... 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1,
677 ... 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
678 ... 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0]), 10)
679 1430
681 # 100 bits, board width = 10, and 42 queens
682 >>> nqueens(np.array([0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
683 ... 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
684 ... 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,
685 ... 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0,
686 ... 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0]), 10)
687 1138
689 # 100 bits, board width = 10, and 93 queens
690 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
691 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
692 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,
693 ... 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
694 ... 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 10)
695 3067
697 # 100 bits, board width = 10, and 92 queens
698 >>> nqueens(np.array([1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
699 ... 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
700 ... 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
701 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
702 ... 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1]), 10)
703 3018
705 # 100 bits, board width = 10, and 0 queens
706 >>> nqueens(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
707 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
708 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
709 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
710 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
711 10
713 # 100 bits, board width = 10, and 100 queens
714 >>> nqueens(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
715 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
716 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
717 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
718 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 10)
719 3330
721 >>> nqueens(np.array([True] * 16), 4)
722 156
723 """
724 n: Final[int] = len(x)
726 # The chess board is stored row-by-row.
727 # Count the total number of queens on the chess board. It should be k.
728 queens_total: int = 0
730 # Since we need to go through the board row by row anyway, we
731 # can also check how many queens are in each row while we are at
732 # it.
733 must_be_one_1: int = 0 # queens per row
734 penalty: int = 0
736 # The last row goes from index n-1 to index n-k, the row before
737 # from n-k-1 to n-2k, ..., the first row goes from k-1 to 0.
738 next_row_reset = k - 1
739 for i in range(n):
740 if x[i]:
741 queens_total += 1
742 must_be_one_1 += 1
744 if i >= next_row_reset: # We reached the end of a row.
745 next_row_reset += k
747 # If there is at most one queen in the row, the penalty is zero.
748 # Otherwise, the penalty for the row is number of queens in it
749 # minus 1.
750 if must_be_one_1 > 1:
751 penalty += must_be_one_1 - 1
752 must_be_one_1 = 0
754 # Count the number of queens in the columns and check if there
755 # is more than one queen in a column.
756 # col be the column index, it goes from 1 to k.
757 for col in range(k):
758 must_be_one_1 = 0
759 # The cells in column j have indices k-j, 2k-j, 3k-j, ...,
760 # k*k-j=n-j in x and we iterate them from the back.
761 for i in range(col, n, k):
762 if x[i]:
763 must_be_one_1 += 1
764 # If there is at most one queen in the column, the penalty is zero.
765 # Otherwise, the penalty for the column is number of queens in
766 # it minus 1.
767 if must_be_one_1 > 1:
768 penalty += must_be_one_1 - 1
770 # There are 1 + 2*(k-2) = 2*k-3 diagonals of any kind.
771 # The diagonal in the "middle" is unique, the others can be
772 # mirrored.
774 # We have two types of diagonals.
775 # One goes from top-left to bottom-right, for which we use index
776 # i1 and count collisions in must_be_one_1 and must_be_one_2 and whose
777 # indices step in k-1 increments.
778 # The other one goes from bottom-left to top-right, for which we
779 # use index i2 and count collisions in must_be_one_3 and must_be_one_4
780 # and whose indices step in k+1 increments.
781 # Both have the central, non-mirrored version and the others
782 # which are mirrored around the central diagonal.
783 diagonal_step_1: Final[int] = k - 1
784 diagonal_step_2: Final[int] = k + 1
785 other_diagonal_start: Final[int] = n - 1
787 # First process unique center diagonal.
788 must_be_one_1 = 0
789 must_be_one_3: int = 0
790 d: int = k - 1
791 i1: int = k * d
792 i2: int = i1 + diagonal_step_1
793 while i1 > 0:
794 if x[i1]:
795 must_be_one_1 += 1
796 if x[i2]:
797 must_be_one_3 += 1
798 i1 -= diagonal_step_1
799 i2 -= diagonal_step_2
800 if must_be_one_1 > 1:
801 penalty += must_be_one_1 - 1
802 if must_be_one_3 > 1:
803 penalty += must_be_one_3 - 1
805 # Now process the mirrored diagonals
806 d -= 1
807 while d > 0:
808 must_be_one_1 = 0
809 must_be_one_3 = 0
810 must_be_one_2: int = 0
811 must_be_one_4: int = 0
813 i1 = k * d
814 if i1 > other_diagonal_start:
815 i1 -= diagonal_step_1 * (
816 (i1 - other_diagonal_start) // diagonal_step_1)
817 i2 = i1 + diagonal_step_1
819 while i1 > 0:
820 if x[i1]:
821 must_be_one_1 += 1
822 if x[other_diagonal_start - i1]:
823 must_be_one_2 += 1
824 if x[i2]:
825 must_be_one_3 += 1
826 if x[other_diagonal_start - i2]:
827 must_be_one_4 += 1
828 i1 -= diagonal_step_1
829 i2 -= diagonal_step_2
831 if must_be_one_1 > 1:
832 penalty += must_be_one_1 - 1
833 if must_be_one_2 > 1:
834 penalty += must_be_one_2 - 1
835 if must_be_one_3 > 1:
836 penalty += must_be_one_3 - 1
837 if must_be_one_4 > 1:
838 penalty += must_be_one_4 - 1
839 d -= 1
841 # penalty now holds the total number of collisions in the rows, columns,
842 # and all diagonals.
843 # queens_total is the number of queens.
844 # The minimization version of the IOHprofiler N queens problem is then:
845 return k - queens_total + (k * penalty)
848class NQueens(SquareBitStringProblem):
849 """The N-Queens problem."""
851 def __init__(self, n: int) -> None:
852 """
853 Initialize the n-queens problem.
855 :param n: the dimension of the problem (must be a perfect square)
856 and at least 16
857 """
858 super().__init__(check_int_range(n, "n", 16))
860 def evaluate(self, x: np.ndarray) -> int:
861 """
862 Evaluate a solution to the N-Queens problem.
864 :param x: the bit string to evaluate
865 :returns: the value of the N-Queens problem for the string
866 """
867 return nqueens(x, self.k)
869 def __str__(self) -> str:
870 """
871 Get the name of the N-Queens problem.
873 :return: `NQueens_` + dimension of the board
875 >>> NQueens(16)
876 nqueens_16
877 """
878 return f"nqueens_{self.n}"
880 def upper_bound(self) -> int:
881 """
882 Compute the upper bound of the N-Queens objective function.
884 >>> NQueens(4 * 4).upper_bound()
885 156
887 >>> NQueens(5 * 5).upper_bound()
888 340
890 >>> NQueens(6 * 6).upper_bound()
891 630
893 >>> NQueens(7 * 7).upper_bound()
894 1050
896 >>> NQueens(8 * 8).upper_bound()
897 1624
899 >>> NQueens(9 * 9).upper_bound()
900 2376
902 >>> NQueens(10 * 10).upper_bound()
903 3330
905 >>> NQueens(20 * 20).upper_bound()
906 29260
908 >>> NQueens(30 * 30).upper_bound()
909 101790
911 >>> NQueens(100 * 100).upper_bound()
912 3930300
914 >>> NQueens(6241).upper_bound()
915 1928706
917 >>> NQueens(4225).upper_bound()
918 1069120
919 """
920 k: Final[int] = self.k
921 return (((((k - 2) * 4) + 1) * k) + 3) * k
923 @classmethod
924 def default_instances(
925 cls: type, scale_min: int = 16, scale_max: int = 144) \
926 -> Iterator[Callable[[], "NQueens"]]:
927 """
928 Get the 9 default instances of the :class:`NQueens` problem.
930 :param scale_min: the minimum permitted scale, by default `16`
931 :param scale_max: the maximum permitted scale, by default `144`
932 :returns: a sequence of default :class:`NQueens` instances
934 >>> len(list(NQueens.default_instances()))
935 9
937 >>> [x() for x in NQueens.default_instances()]
938 [nqueens_16, nqueens_25, nqueens_36, nqueens_49, nqueens_64, \
939nqueens_81, nqueens_100, nqueens_121, nqueens_144]
940 """
941 return cast("Iterator[Callable[[], NQueens]]",
942 super().default_instances( # type: ignore
943 scale_min, scale_max))