mersinvald
@mersinvald
Студент, тунеядец, мечтатель

Генерация всех позможных вариантов заполнения квадратной матрицы N-м числом графов. Алгоритм..?

Здравствуйте.
Возникла необходимость сгенерировать полную выборку возможных вариантов "закраски" матрицы графами.
А точнее их связывания в различных последовательностях. Графы представляют собой ориентированные цепочки.

То есть нужно найти все возможные варианты цепочек элементов, при условии что графов:
а) может быть произвольное количество.
б) "длина" цепочки элементов может варьироваться.
в) матрица произвольного размера, но всегда квадратная.
г) связывать можно только стоящие "рядом элементы" по x или y, никаких диагоналей.

Прошу помощи в поиске оптимального алгоритма, или хотя бы рабочего, для которого можно доказать что полученная выборка будет полной.

UPD: немного переформулирую: нужно найти все варианты связывания элементов в цепочки. (минимум по 2 элемента, дабы сократить количество вариантов)

Для 2х2
2bb79a781a9f4f218975ab3e1c60bec8.jpg

Соответственно для 3х3 и более разница будет в том, что цепочки могут быть сложных форм и разных длинн. И разного количества, в каждом варианте.
  • Вопрос задан
  • 1082 просмотра
Пригласить эксперта
Ответы на вопрос 1
Mrrl
@Mrrl
Заводчик кардиганов
Если мы возьмём любую цепочку, проходящую через все точки (например, змейку или спираль), и разрежем её на куски всеми возможными способами, а потом часть кусков ещё и развернём, у нас уже получится примерно 2^(N^2)/3 вариантов. Уже при N=7 перечислить их нереально (при N=6 их всего 10 миллиардов - это не так много). Но поскольку исходных цепочек (проходящих через все точки) много, а кроме того, не все конфигурации можно получить разрезанием одной цепочки, вариантов будет ещё больше.
Алгоритмы - как рекурсия, так и перебор состояний клеток - не очень сложные. В обоих случаях нужно искать разбиение на неориентированные цепочки, а потом всеми способами задавать их направление.
В случае перебора состояний (он проще) делаем так. Замечаем, что у каждой клетки есть 10 возможных состояний - 4 для конца цепочки (направления, куда из этой клетки цепочка идёт), 4 для клетки, где цепочка поворачивает, и 2 для клетки, через которую она проходит прямо. Кроме того, есть ограничения: цепочка не может упираться в стенку, и общее ребро двух соседних клеток либо пересекается цепочкой с каждой стороны, либо нет. Ну, и не должно быть циклов.
Алгоритм получается таким. Перебираете клетки матрицы по строкам. Для каждой очередной клетки смотрите состояние её соседей, и получаете список возможных состояний самой клетки - их не более трёх. В случае, если есть состояние, которое соединяет две соседние цепочки, надо пройтись по ним - проверить, не являются ли они концами одной цепочки (если да - получится цикл, а он запрещён). Теперь подставляем в клетку по очереди все допустимые состояния, и рекурсивно вызываем функцию перебора для следующей клетки. Когда дойдём до конца - фиксируем найденное разбиение.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы