Нахождение набора перестановок с ограничением

У меня есть набор из N ^ 2 чисел и N ячеек. Каждый бин должен иметь N номеров из назначенного ему набора. Проблема, с которой я столкнулся, заключается в поиске набора распределений, которые отображают числа в ячейки, удовлетворяющие ограничению, согласно которому каждая пара чисел может использовать одну и ту же корзину только один раз.

Распределение может быть хорошо представлено матрицей NxN, в которой каждая строка представляет собой ячейку. Тогда задача состоит в том, чтобы найти набор перестановок элементов матрицы, в котором каждая пара чисел находится в одной и той же строке только один раз. Неважно, какая это строка, только то, что два числа были назначены одному и тому же.

Пример набора из 3 перестановок, удовлетворяющих ограничению для N=8:

 0  1  2  3  4  5  6  7
 8  9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
 0  8 16 24 32 40 48 56
 1  9 17 25 33 41 49 57
 2 10 18 26 34 42 50 58
 3 11 19 27 35 43 51 59
 4 12 20 28 36 44 52 60
 5 13 21 29 37 45 53 61
 6 14 22 30 38 46 54 62
 7 15 23 31 39 47 55 63
 0  9 18 27 36 45 54 63
 1 10 19 28 37 46 55 56
 2 11 20 29 38 47 48 57
 3 12 21 30 39 40 49 58
 4 13 22 31 32 41 50 59
 5 14 23 24 33 42 51 60
 6 15 16 25 34 43 52 61
 7  8 17 26 35 44 53 62

Перестановка, не принадлежащая указанному выше набору:

 0 10 20 30 32 42 52 62
 1 11 21 31 33 43 53 63
 2 12 22 24 34 44 54 56
 3 13 23 25 35 45 55 57
 4 14 16 26 36 46 48 58
 5 15 17 27 37 47 49 59
 6  8 18 28 38 40 50 60
 7  9 19 29 39 41 51 61

Из-за множественных столкновений со второй перестановкой, так как, например, они оба соединяют числа 0 и 32 в одной строке.


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

Однако я не могу найти способ создать набор, состоящий из большего количества. Кажется, что это либо очень сложная проблема, либо простая проблема с неочевидным решением. В любом случае я был бы признателен, если бы у кого-нибудь были какие-либо идеи, как решить это в разумные сроки для случая N = 8, или если бы он указал правильное академическое название проблемы, чтобы я мог найти ее в Google.

Если вам интересно, для чего это полезно, я ищу алгоритм планирования для кроссбарного коммутатора с 8 буферами, который обслуживает трафик до 64 пунктов назначения. Эта часть алгоритма планирования не зависит от входного трафика и циклически переключается между несколькими аппаратными отображениями буфера назначения. Цель состоит в том, чтобы каждая пара адресов назначения конкурировала за один и тот же буфер только один раз за циклический период и максимизировала продолжительность этого периода. Другими словами, чтобы каждая пара адресов как можно реже конкурировала за один и тот же буфер.


РЕДАКТИРОВАТЬ:

Вот какой код у меня есть. КОД

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

Альтернатива потребовала бы, чтобы выбор перестановки I включал поиск перестановок (I+1..N), чтобы проверить, является ли перестановка I частью решения, состоящего из максимального числа перестановок. Это потребовало бы перечисления всех перестановок для проверки на каждом шаге, что непомерно дорого.


person Community    schedule 21.08.2009    source источник
comment
Весь вопрос немногословен. Непонятно, что вы имеете в виду под парой. Что вы подразумеваете под «ограничением, согласно которому каждая пара чисел может использовать одну и ту же ячейку только один раз»?   -  person Alex    schedule 22.08.2009
comment
У меня возникли проблемы с пониманием вашего ограничения: каждая пара чисел может использовать одну и ту же ячейку только один раз. Разве это не тривиально верно для любого расположения N ^ 2 уникальных чисел? Можете ли вы показать расположение, которое не соответствует этому ограничению?   -  person Jim Lewis    schedule 22.08.2009
comment
Ограничение должно выполняться для всего набора перестановок. Таким образом, если одна перестановка помещает числа 1 и 2 в одну и ту же строку, никакая другая перестановка в наборе больше не может помещать 1 и 2 в ту же строку.   -  person    schedule 22.08.2009
comment
Формально пусть P(a,b,i) — это предикат a и b, находящиеся в одной строке в перестановке i, и предположим, что имеется n перестановок. Тогда ограничение состоит в том, что не существует таких a, b ‹= N^2 и i, j ‹= n, что P(a,b,i) && P(a,b,j).   -  person Steve Jessop    schedule 22.08.2009
comment
P(a,b,i) само может быть выражено как R(a,i) == R(b,i), где R — функция, отображающая пару (a,i) в номер строки, в которой находится элемент a появляется в перестановке i.   -  person Steve Jessop    schedule 22.08.2009
comment
Если вам все еще нравится ваш код утром :-), опубликуйте его как ответ, чтобы мы могли проголосовать за вас еще раз! Это была очень интересная задача!   -  person Jim Lewis    schedule 22.08.2009


Ответы (4)


Вам нужен комбинаторный блочный дизайн. Используя номенклатуру на связанной странице, вам нужны дизайны размера (n ^ 2, n, 1) для максимального k. Это даст вам n(n+1) перестановок, используя вашу номенклатуру. Это максимум, теоретически возможный при счетном аргументе (см. объяснение в статье о выводе b из v, k и лямбда). Такие планы существуют для n = p ^ k для некоторого простого p и целого числа k с использованием аффинной плоскости. Предполагается, что единственные существующие аффинные плоскости имеют такой размер. Поэтому, если вы можете выбрать n, возможно, этого ответа будет достаточно.

Однако, если вместо максимально теоретически возможного количества перестановок вы просто хотите найти большое число (наибольшее, что вы можете для данного n^2), я не уверен, как называется изучение этих объектов.

person Martin Hock    schedule 22.08.2009
comment
Большое большое спасибо! На странице википедии для блочных конструкций я нашел ссылку на базу данных, содержащую интересующее меня решение (64, 8, 1). - person ; 24.08.2009

Создайте массив 64 x 64 x 8: bool disabled[i][j][k], который указывает, появилась ли пара (i,j) в строке k. Каждый раз, когда вы используете пару (i, j) в строке k, вы устанавливаете соответствующее значение в этом массиве равным единице. Обратите внимание, что вы будете использовать только половину этого массива, для которой i ‹ j.

Чтобы создать новую перестановку, начните с попытки члена 0 и убедитесь, что по крайней мере семь из запрещённых [0] [j] [0] не установлены. Если не осталось семи, увеличьте и повторите попытку. Повторите, чтобы заполнить остальную часть строки. Повторите весь этот процесс, чтобы заполнить всю перестановку NxN.

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

person Brian    schedule 21.08.2009
comment
+1, но я думаю, что ограничение сильнее: как только пара появилась в одной строке, они не могут появиться вместе в любой строке в другой перестановке. Так может быть, запрещенный массив должен быть 64x64 без конечного размера? - person Jim Lewis; 22.08.2009
comment
Жадный подход, подобный этому, дает лишь небольшое количество перестановок перед завершением. Это было первое, что я попробовал. - person ; 22.08.2009

Возможно, вы могли бы переформулировать свою проблему в теории графов. Например, вы начинаете с полного графа с N×N вершин. На каждом шаге вы разбиваете граф на N N-клик, а затем удаляете все используемые ребра.

Для этого случая N = 8, K64 имеет 64 × 63/2 = 2016 ребер, а шестьдесят четыре партии K8 имеют 1792 ребра, поэтому ваша проблема может не быть невозможной :-)

person John Fouhy    schedule 22.08.2009
comment
Это звучит правильно! И познавательно — потому что известно, что задача поиска клики в общем случае является NP-полной. Я подозреваю, что первые несколько итераций (пока граф NxN все еще относительно плотный), вероятно, легко найти методом грубой силы, но по мере удаления ребер поиск клик занимает все больше и больше времени. - person Jim Lewis; 22.08.2009
comment
Что ж, поиск максимальных клик NP-полный. Я не уверен в этой проблеме. Я думаю, что клики было бы легко найти, если бы они существовали, поскольку каждая вершина должна быть членом одной, а вас интересует только размер N. Проблема в том, что жадный алгоритм, вероятно, выберет неправильные клики и не сможет найти все N, предполагая, что N существует (ну, во всяком случае, это мое внутреннее чувство). - person John Fouhy; 22.08.2009
comment
Да, по сути, я реализовал поиск всех 8 кликов. Это быстро сделать, имея 2 начальные перестановки (найдено 40320 8-клик), и выполнимо, имея 1 начальную перестановку (найдено 16 миллионов 8-клик). Проблема, однако: 1. Перечисление всех допустимых перестановок, то есть наборов из 8 8-клик, представляет собой 40320^8 или (16 миллионов)^8 дело. 2. Количество 8-клик и возможных перестановок на следующем шаге зависит от выбора перестановки на этом шаге, жадность действительно не работает. Полный поиск должен был бы при поиске перестановки I оценить все последующие перестановки (I+1..N):/ - person ; 22.08.2009

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

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

На самом деле, если вы воспользуетесь таблицей запрещенных пар, которую я предложил ранее, вы обнаружите, что максимальное количество возможных перестановок составляет всего N+1 = 9, прежде чем вы закончите. Таблица имеет N^2 x (N^2-1)/2 = 2016 неизбыточных ограничений, и каждая новая перестановка создаст N x (N выбирает 2) = 28 новых пар. Таким образом, все пары будут израсходованы после 2016/28 = 9 перестановок. Похоже, осознание того, что перестановок так мало, является ключом к решению проблемы.

Вы можете создать список из N перестановок, пронумерованных n = 0 ... N-1, как

A_ij = (i * N + j + j * n * N) mod N^2

который генерирует новую перестановку, сдвигая столбцы в каждой перестановке. Верхний ряд n-й перестановки — это диагонали n-1-й перестановки. РЕДАКТИРОВАТЬ: Упс... это работает только тогда, когда N простое число.

Это пропускает одну последнюю перестановку, которую вы можете получить, транспонируя матрицу:

A_ij = j * N + i
person Brian    schedule 22.08.2009
comment
Вы также получаете верхний предел N+1, изучая N-1 соседей данного значения, например. 1. Каждое из оставшихся N ^ 2-1 чисел может появляться только один раз в строке с 1, что означает, что существует не более (N ^ 2-1)/(N-1) = N + 1 уникальных строк, следовательно, матрицы, содержащий 1. - person outis; 23.08.2009