[PYTHON] Solving the N Queen problem with combinatorial optimization

what is this

Tips for solving combinatorial optimization based on the N Queen problem.

Original article: Solving N Queen problem with combinatorial optimization

Conclusion

Changing the order of the constraints may change the calculation time. Let's verify with 4 patterns.

Solve the N Queen problem

First, check that you can actually solve it with 8x8.

from ortoolpy import pd, addbinvars, model_min, lpSum, addvals
n = 8
df = pd.DataFrame([(i, j) for i in range(n) for j in range(n)],
                  columns=['X', 'Y'])
addbinvars(df);
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%time m.solve()
addvals(df)
cc = df.Val.astype(int).map('.O'.__getitem__).values.reshape(n, n)
print('\n'.join(''.join(c) for c in cc))

output

Wall time: 27 ms
..O.....
O.......
......O.
....O...
.......O
.O......
...O....
.....O..

Next, check the execution time with four formulas with a size of 100 x 100.

Pattern 1 (4.0 seconds)

m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()

3.97 s ± 702 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

Pattern 2 (4.7 seconds)

m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()

4.7 s ± 423 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

Pattern 3 (2.2 seconds)

m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
for i in range(n):
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()

2.24 s ± 36.5 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

Pattern 4 (6.4 seconds)

m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
for i in range(n):
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()

6.44 s ± 129 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

What should i do

The four patterns have the same formulation, only the order of the constraints is different. However, the calculation time has changed nearly three times. Moreover, the tendency is different depending on n.

In such a case, it may be better to prepare multiple patterns and execute them at the same time like this time, and stop all if even one answer is found.

Supplement

The calculation was done on a ThinkPad X280. The library installation is pip install or toolpy.

The 100 x 100 N Queens problem has 10,000 0-1 variables. The combination is $ 10 ^ {3010} $. It's a tremendous number of combinations, but it's amazing that you can solve it in just over 2 seconds with free software (PuLP).

Recommended Posts

Solving the N Queen problem with combinatorial optimization
Solving the N Queens problem with combinatorial optimization
Solving 4-color problems with combinatorial optimization
Pave the road with combinatorial optimization
Solving game theory with combinatorial optimization
Solving nurse scheduling problems with combinatorial optimization
Solving the nurse scheduling problem (shift optimization) with a genetic algorithm
Solving Knapsack Problems with Google's OR-Tools-Practicing the Basics of Combinatorial Optimization Problems
Solving the Python knapsack problem with the greedy algorithm
Solving the iris problem with scikit-learn ver1.0 (logistic regression)
Grouping games with combinatorial optimization
Combinatorial optimization with quantum annealing
Maximize restaurant sales with combinatorial optimization
Go see whales with combinatorial optimization
The power of combinatorial optimization solvers
Try to solve the N Queens problem with SA of PyQUBO
Combinatorial optimization-Typical problem-Transportation route (delivery optimization) problem
Let's solve the portfolio with continuous optimization
Let's stack books flat with combinatorial optimization
We will implement the optimization algorithm (Problem)
Solve the traveling salesman problem with OR-Tools
Solving the traveling salesman problem with the genetic algorithm (GA) and its library (vcopt)
Try to solve the fizzbuzz problem with Keras
Combinatorial optimization to find the hand of "Millijan"
Let's decide the date course by combinatorial optimization
Minimize the number of polishings by combinatorial optimization
Judging the finish of mahjong by combinatorial optimization
Solving the Lorenz 96 model with Julia and Python
I tried to solve the virtual machine placement optimization problem (simple version) with blueqat
Use combinatorial optimization
Combinatorial optimization-Typical problem-Facility placement problem with no capacity constraints
Solving the shortest path problem (VRP) Mixed integer programming
Try to solve the internship assignment problem with Python
The first algorithm to learn with Python: FizzBuzz problem
○○ Solving problems in the Department of Mathematics by optimization
python chrome driver ver. Solving the problem of difference
The 14th offline real-time writing reference problem with Python
I tried to solve the problem with Python Vol.1