Документация Engee

N ферзей

Это руководство было изначально предоставлено Мэтью Хелмом (Matthew Helm) и Матье Танно (Mathieu Tanneau).

Задача об N ферзях заключается в расстановке N ферзей на шахматной доске размером N x N таким образом, чтобы ни один из ферзей не мог атаковать другого. В шахматах ферзь может двигаться по вертикали, горизонтали и диагонали, поэтому в любом ряду, в любом столбце и на любой диагонали может быть не более одного ферзя.

Четыре ферзя

Обратите внимание, что благодаря грамотному расположению ни один из ферзей на рисунке не может атаковать другого.

using JuMP
import HiGHS
import LinearAlgebra

N ферзей

N = 8

model = Model(HiGHS.Optimizer)
set_silent(model)

Далее давайте создадим шахматную доску размером N x N из двоичных значений. Значение 0 будет представлять пустое место на доске, а 1 — место, занятое одним из ферзей:

@variable(model, x[1:N, 1:N], Bin);

Теперь можно добавить ограничения:

В ряду или столбце должен быть ровно один ферзь:

for i in 1:N
    @constraint(model, sum(x[i, :]) == 1)
    @constraint(model, sum(x[:, i]) == 1)
end

На любой диагонали может быть только один ферзь:

for i in -(N - 1):(N-1)
    @constraint(model, sum(LinearAlgebra.diag(x, i)) <= 1)
    @constraint(model, sum(LinearAlgebra.diag(reverse(x; dims = 1), i)) <= 1)
end

Теперь можно запустить модель и посмотреть, удастся ли ей найти допустимое решение:

optimize!(model)
@assert is_solved_and_feasible(model)

Посмотрим, какое решение нашла модель:

solution = round.(Int, value.(x))
8×8 Matrix{Int64}:
 0  0  0  0  1  0  0  0
 0  0  1  0  0  0  0  0
 0  0  0  0  0  0  0  1
 0  0  0  1  0  0  0  0
 0  0  0  0  0  0  1  0
 1  0  0  0  0  0  0  0
 0  0  0  0  0  1  0  0
 0  1  0  0  0  0  0  0