Эта задача частично является задачей алгоритмов, частично задачей оптимизации, а частично просто самой быстрой задачей кода.
Циклическая матрица полностью определяется ее первой строкой r
. Оставшиеся строки представляют собой циклические перестановки строк r
со смещением, равным индексу строки. Мы допустим циклические матрицы, которые не являются квадратными, так что они просто пропускают некоторые из своих последних строк. Однако мы всегда предполагаем, что количество строк не больше, чем количество столбцов. Например, рассмотрим следующую циклическую матрицу 3 на 5.
10111
11011
11101
Мы говорим, что матрица обладает свойством X, если она содержит два непустых набора столбцов с неидентичными индексами, которые имеют одинаковую (векторную) сумму. Векторная сумма двух столбцов - это просто поэлементное суммирование двух столбцов. То есть сумма двух столбцов, содержащих x
элементы, каждый является другим столбцом, содержащим x
элементы.
Приведенная выше матрица тривиально обладает свойством X, поскольку первый и последний столбцы совпадают. Тождественная матрица никогда не обладает свойством X.
Если мы просто удалим последний столбец матрицы выше, то получим пример, который не имеет свойства X и даст оценку 4/3.
1011
1101
1110
Задание
Задача состоит в том, чтобы написать код, чтобы найти циклическую матрицу с наивысшей оценкой, все записи которой равны 0 или 1 и которая не имеет свойства X.
Гол
Ваша оценка будет равна количеству столбцов, разделенному на количество строк в вашей наилучшей оценочной матрице.
Tie Breaker
Если два ответа имеют одинаковую оценку, победит тот, который отправил первый.
В (очень) маловероятном случае, когда кто-то найдет способ получить неограниченное количество баллов, будет принято первое действительное доказательство такого решения. В еще более маловероятном случае, когда вы сможете найти доказательство оптимальности конечной матрицы, я, конечно, также призову победу.
намек
Получить счет 12/8 не так уж сложно.
Языки и библиотеки
Вы можете использовать любой язык со свободно доступным компилятором / интерпретатором и т. Д. для Linux и любых библиотек, которые также свободно доступны для Linux.
Ведущие записи
- 36/19 Питер Тейлор (Ява)
- 32/17 от Suboptimus Prime (C #)
- 21/12 от justhalf (Python 2)
источник
01
обладает свойством X, поскольку набор первого столбца имеет ту же векторную сумму, что и пустой набор. Возможно, вы имели в виду непустые наборы столбцов? Я думаю, что чище не менять его, хотя.01
имеет свойство X:(1) = (0) + (1)
. Если вы хотите исключить это, вы должны сказать, что два набора столбцов должны быть непересекающимися.2^m
комбинаций столбцов для проверки свойства X. Если бы мы могли как-то разработать схему «встретиться посередине» (см. Проблему «сумма подмножеств»), это могло бы уменьшить это доm * 2^(m/2)
...Ответы:
16/9 20/11 22/12 28/15 30/16 32/1734/18 36/19 (Ява)Это использует ряд идей, чтобы уменьшить пространство поиска и стоимость. Посмотрите историю изменений для более подробной информации о более ранних версиях кода.
0
и1
) и заканчивая; Я использую алгоритм, описанный в коде Грея, для ожерелий с фиксированной плотностью и слов Линдона в постоянном амортизированном времени , Савада и Уильямс, Теоретическая информатика 502 (2013): 46-54.BigInteger
чтобы дать точный тест. Я получаю значительное улучшение скорости, рискуя получить ложные негативы, работая по модулю большого простого числа и сохраняя все в примитивах. Простое число, которое я выбрал, является самым большим, меньше чем 2 57 , поскольку это позволяет умножать на основание моего условного векторного представления без переполнения.{-1,0,1}^m
имеет свое отрицание, также{-1,0,1}^m
необходимо хранить только один из двух.2n/(n+1)
, я ускоряю процесс, просто проверяя это.Первый найденный
и это единственный удар за 15 часов.
Меньшие победители:
источник
n
а неrows
, хотя это отказоустойчиво в том смысле, что он будет отбрасывать действительные решения, а не принимать недействительные. Это также не влияет на результаты.Python 2 - 21/12
В процессе доказательства того, что
2-(3/n)
всегда существует для любогоn
Вдохновленный этим вопросом , я использовал последовательность де Брюйна для грубой силы возможных матриц. И после брутфорса
n=6,7,8,9,10
я обнаружил шаблон, который всегда имеет форму самого высокого решения(n, 2n-3)
.Поэтому я создал еще один метод, чтобы использовать только эту форму матрицы и использовать многопроцессорную обработку, чтобы ускорить процесс, поскольку эта задача легко распространяется. В 16-ядерном Ubuntu решение может быть найдено
n=12
примерно за 4 минуты:Большая часть вычислений идет на проверку свойства X, которое требует проверки всех подмножеств (есть
2^(2n-3)
подмножества)Обратите внимание, что я поворачиваю первый ряд влево, а не вправо, как в вопросе. Но это эквивалентно, поскольку вы можете просто перевернуть всю матрицу. знак равно
Код:
Старый ответ, для справки
Оптимальное решение пока (
n=10
):Для
n=7
:Решение с формой, как описано OP (
n=8
):Но лучше (
n=8
):Также найдено другое оптимальное решение по адресу
n=9
:Код выглядит следующим образом. Это просто грубая сила, но, по крайней мере, она может найти что-то лучше, чем претензия ОП =)
источник
n >= 31
, что подразумевает необходимость проверки2^(2n-3) = 2^59
комбинаций 31-мерного вектора. Не закончим в нашей жизни = Dn*(2n-3)
24/13 26/14 28/15 30/1632/17 (C #)Изменить: Удалил устаревшую информацию из моего ответа. Я использую в основном тот же алгоритм, что и Питер Тейлор ( Edit: похоже, он сейчас использует лучший алгоритм), хотя я добавил некоторые из моих собственных оптимизаций:
HasPropertyXFast
функцию, которая быстро проверяет наличие небольших наборов с равными суммами, прежде чем использовать подход «посередине».HasPropertyXFast
функции, я начинаю с проверки наборов столбцов с 1 столбцом, затем с 2, 3 и так далее. Функция возвращается, как только найдено первое столкновение сумм столбцов. На практике это означает, что мне обычно приходится проверять несколько сотен или тысяч наборов столбцов, а не миллионы.long
переменные для хранения и сравнения целых столбцов и их векторных сумм. Этот подход по крайней мере на порядок быстрее, чем сравнение столбцов как массивов.long
типов данных и шаблонов использования.Выход программы:
Код:
Файл конфигурации:
источник
ulong
и позволить переносу смены вместо использованияBigInteger
.GetSumOfColumns
добавляет дополнительный цикл, который, как я ожидаю, будет стоить больше, чем фактор 2. Сортировка маски звучит интересно: возможно, вы могли бы изменить ответ, чтобы немного поговорить об этом? (И в какой-то момент я буду экспериментировать с альтернативным способом раннего прерывания: причина, по которой я не могу этого сделать, заключается в том, что HashSet не поддерживает одновременную итерацию и модификацию, но у меня есть идеи, чтобы избежать необходимости в итераторе) ,