One of the samples for the Google or-tools is a solver for the n-queens problem. Внизу говорится, что реализация может быть улучшена путем добавления ограничений на ограничение симметрии решателю ограничений.N-Queens Symmetry Breaking Google OR Tools
Оглядываясь по интернету, I found the symmetry breaking constraints for the n-queens problem, но я не могу на всю жизнь понять, как преобразовать их в ограничения на код Python, который их реализует.
EDIT: это был плохой вопрос, давайте обновление ...
Что я пробовал?
Вот настройки с первой ссылке выше:
from ortools.constraint_solver import pywrapcp
N = 8
solver = pywrapcp.Solver("n-queens")
# Creates the variables.
# The array index is the column, and the value is the row.
queens = [solver.IntVar(0, N - 1, "x%i" % i) for i in range(N)]
# Creates the constraints.
# All rows must be different.
solver.Add(solver.AllDifferent(queens))
# All columns must be different because the indices of queens are all different.
# No two queens can be on the same diagonal.
solver.Add(solver.AllDifferent([queens[i] + i for i in range(N)]))
solver.Add(solver.AllDifferent([queens[i] - i for i in range(N)]))
# TODO: add symmetry breaking constraints
db = solver.Phase(queens, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE)
solver.NewSearch(db)
num_solutions = 0
while solver.NextSolution():
num_solutions += 1
solver.EndSearch()
print()
print("Solutions found:", num_solutions)
print("Time:", solver.WallTime(), "ms")
Я знаю, что могу реализовать простые ограничения успешно. Если бы я хотел, чтобы обеспечить решение всегда ферзя в первом столбце первой строки, я мог бы осуществить это так:
solver.Add(queens[0] == 0)
Переменная queens[0]
представляет расположение ферзей в первом столбце и это ограничение только если первый столбец имеет королеву в первой строке. Конечно, это не то, что я хочу сделать, потому что возможно, что решение не содержит никаких угловых ячеек.
Ограничения на нарушение симметрии для проблемы n-queens приведены ниже. Они вытягиваются непосредственно из ссылки во втором абзаце.
Я понимаю, как работают эти ограничения. Идея состоит в том, что вы можете применить эту функцию к каждой ячейке на плате n-queens, чтобы преобразовать состояние в эквивалентное состояние. Одним из этих состояний будет каноническое представление этого состояния. Это используется как метод сокращения будущей обработки путем устранения дублирующих оценок.
Если бы я только реализовал это в факторе, я бы сделал именно то, что я описал выше, преобразую состояние с помощью каждой возможной функции нарушения симметрии, вычислив какой-то хэш состояния (например, строку выбранной строки в каждом столбце) и выберите тот, который является самым низким для каждого предлагаемого решения. Пропустите будущую обработку на тех, которые мы видели ранее.
Моя проблема заключается в том, что я не знаю, как преобразовать эти преобразования в ограничения для решения для программирования ограничений для инструментов google или-tools.
Давайте рассмотрим простейший, d1(r[i] = j) => r[j] = i
, отражение о главной диагонали. Я знаю, что преобразование необходимо применять ко всем ячейкам, а затем сравнивать с текущим состоянием, чтобы предотвратить его расширение. Я недостаточно понимаю о python, чтобы понять, какое выражение работает здесь для преобразования, и я просто не могу понять, как создать ограничение, которое сравнивает преобразование с текущим состоянием для данного решателя.
state = [queens[i].Value() for i in range(N)]
symX = [state[N - (i + 1)] for i in range(N)]
symY = [N - (state[i] + 1) for i in range(N)]
symD1 = [state.index(i) for i in range(N)]
symD2 = [N - (state.index(N-(i+1)) + 1) for i in range(N)]
symR90 = [N - (state.index(i) + 1) for i in range(N)]
symR180 = [N - (state[N-(i+1)] + 1) for i in range(N)]
symR270 = [state.index(N-(i+1)) for i in range(N)]
Я собирался представить ответ здесь, но обратите внимание, что вы также конкурируют в Programming Contest текущего Аль Циммермана «многоугольные области». Без сомнения, у вас будет хороший ответ через 3 месяца после окончания конкурса, и люди смогут обсуждать свои решения и алгоритмы. – gb96
@ gb96 действительно я, но я не прошу, что делать, только как делать то, что я решил, я хочу попробовать, поэтому мне все хорошо. Удачи в конкурсе! –