Нахождение набора перестановок с ограничением - PullRequest
8 голосов
/ 22 августа 2009

У меня есть набор из 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.

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


EDIT:

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

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

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

Ответы [ 4 ]

4 голосов
/ 22 августа 2009

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

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

4 голосов
/ 22 августа 2009

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

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

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

1 голос
/ 22 августа 2009

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

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

0 голосов
/ 22 августа 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...