Простенькая задача

From
Alexey Kruglov (2:5015/70.5)
To
Andrew Plyako
Date
2002-05-09T20:32:08Z
Area
RU.ALGORITHMS
nPuBeT, Andrew!

Вторник 07 Мая 2002 22:44, Andrew Plyako wrote to All:

 AP> Есть матрица (двумерный массив) n на n. Надо в цикле перебрать все
 AP> варианты расстановки 0 и 1 в этой матрице; все варианты __с точностью
 AP> до отражений/поворотов__.

 AP> Какой алгоритм можно предложить? Просто промоделировать все 2^{n^2}
 AP> вариантов расстановки 0 и 1 несложно. Но как при этом "пропустить" уже
 AP> полученные (с точностью до поворота) варианты?
Это, кстати, сократит количество вариантов менее, чем в 8 раз, т.е. их будет
больше 2^{n^2-3}.

Теперь решение.

Обозначим поворот (например, прочив часовой стрелки) на 90 градусов S,
отражение (например, относительно вертикальной прямой) R. <a,b> -- группа,
сожержащая все произведения, составленные a и b в любом порядке (и только их). 
Можно разбить матрицу на восьмерки и четверки (и при нечетном n будет еще
центральный элемент), которые преобразуются при поворотах и отражениях
независимо. Центральный элемент можно перебирать отдельно, например, самым
внутренним циклом, т.к. его S и R не меняют. Матрицу будем представлять в виде
вектора из всех ее восьмерок и четверок: M=(x_1,...,x_m).

Будем перебирать матрицы M, для которых m<=fM для всех f\in <S,R>. Порядок на M
лексикографический, порядок на 8-ках и 4-ках любой (линейный :). Перебирать
тоже будем в этом же порядке.

Пусть начало M_{k-1}=(x_1,...,x_{k-1}) такое, что M_{k-1}<=fM_{k-1} для f\in
<S,R>, уже подобрано. Надо перебрать все начала длины k с тем же свойством,
начинающиеся с M_{k-1}. Пусть G(x) -- подгруппа <S,R>, эл-ты которой переводят
x в себя, G_{k-1}=G(M_{k-1}).

M_k<=fM_k <=> (M_{k-1}=fM_{k-1} и x_k<=f x_k) или M_{k-1}<fM_{k-1} <=>
(f\in G_{k-1} и x_k<=f x_k) или f\not\in G_{k-1}.   =>

(\forall f: f\in <S,R> => M_k<=fM_k) <=> \forall f\in G_{k-1}: x_k<=f x_k.

Т.е. в качестве x_k надо брать все, удовлетворяющие последнему св-ву. Поскольку
G_{k-1} может принимать только 10 значений (могу ошибаться):
<S,R>, <S^2,R>, <R>,
<S>,   <S^2>,   <>=<e>,
<RS>, <RS^2>, <RS^3>, <RS,S^2>,
все варианты для x_k можно загнать в таблицу, т.е. для 4-ок и для 8-ок будет
таблица please_give_me_the_i_th_possible_value_of_x_k[G_{k-1},i].

Легко проверить, что G_k=G_{k-1} \cap G(x_k) -- пригодится для перебора
x_{k+1}. G_k можно положить в ту же таблицу рядом с x_k.

Получается рекурсивный перебор, следующему шагу передается M_k и G_k.
M_0=(), G_0=<S,R>. В случае нечетного n последний шаг рекурсии должен еще
M_0=(), G_0=<S,R>перебрать 2 значения центрального элемента.

Чтобы быстрее работало, при G_{k-1}=<> для восьмерок можно перебирать x_k без
таблицы, прямо циклом, G_k=G_{k-1} \cap G(x_k)=<>.

 AP> Оговорюсь, что
 AP> 1) не важен порядок в каком будут получатся эти варианты расстановки
 AP> 2) важно получать только правильные варианты; моделирование всех
 AP> вариантов с последующей проверкой/отбраковкой -- не устраивает.
Лишних не перебирается, т.к. все циклы идут по непустым множествам.

nOkA. Alexey.

--- GoldED+/386 1.1.4.7
 * Origin:  6DFA 1186 7576 DE60 6CCB  EB39 AD81 1733 EEBB 970A  (2:5015/70.5)