Для данного положительного целого числа n
рассмотрим все двоичные строки длины 2n-1
. Для данной строки S
, не говоря L
быть массивом длиной , n
который содержит счетчик числа 1
х в каждой подстроке длиной n
из S
. Например, если n=3
и S = 01010
тогда L=[1,2,1]
. Мы называем L
счетный массив S
.
Мы говорим , что две строки S1
и S2
той же длины матча , если их соответствующие счетные массивы L1
и L2
обладают свойством , что L1[i] <= 2*L2[i]
и L2[i] <= 2*L1[i]
для всех i
.
задача
Для увеличения, n
начиная с n=1
, задача состоит в том, чтобы найти размер наибольшего набора строк, каждая из которых имеет длину, 2n-1
чтобы ни одна строка не совпадала.
Ваш код должен выводить одно число на значение n
.
Гол
Ваша оценка является самой высокой, n
за которую никто другой не опубликовал более правильный ответ ни для одного из ваших ответов. Очевидно, что если у вас есть все оптимальные ответы, вы получите балл за самый высокий n
пост. Тем не менее, даже если ваш ответ не является оптимальным, вы все равно можете получить счет, если никто другой не сможет его побить.
Пример ответов
Ибо n=1,2,3,4
я получаю 2,4,10,16
.
Языки и библиотеки
Вы можете использовать любой доступный язык и библиотеки, которые вам нравятся. Там, где это возможно, было бы хорошо иметь возможность запускать ваш код, поэтому, пожалуйста, включите полное объяснение того, как запускать / компилировать ваш код в Linux, если это вообще возможно.
Ведущие записи
- 5 от Мартина Бюттнера в Mathematica
- 6 Рето Коради в C ++ . Ценности есть
2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
. Первые 5, как известно, являются оптимальными. - 7 Питером Тейлором на Яве . Ценности есть
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
. - 9 от joriki на Яве . Ценности есть
2, 4, 10, 16, 31, 47, 76, 112, 168
.
L1[i]/2 <= L2[i] <= 2*L1[i]
.match(A, B)
иmatch(B, C)
не подразумеваетmatch(A, C)
(то же самое для обратного). Пример: [1] и [2] совпадают, [2] и [3] совпадают, но [1] и [3] нет. Аналогично, [1,3] и [3,1] не совпадают, [3, 1] и [2, 3] не совпадают, но [1, 3] и [2, 3] совпадают.Ответы:
2, 4, 10, 16, 31, 47, 76, 112, 168
Для каждого n этот код Java определяет возможные массивы подсчета и затем находит несоответствующие наборы увеличивающегося размера, для каждого размера, начиная со случайного набора и улучшая его путем рандомизированного наискорейшего спуска. На каждом этапе один из элементов набора случайно выбирается равномерно и заменяется другим счетным массивом, случайно выбранным среди тех, которые не используются. Шаг считается принятым, если он не увеличивает количество совпадений. Этот последний рецепт, кажется, имеет решающее значение; принимать шаги, только если они уменьшают количество совпадений, не так эффективно. Шаги, оставляющие количество совпадений неизменным, позволяют исследовать пространство поиска, и в конечном итоге может открыться некоторое пространство, чтобы избежать одного из совпадений. После 2 ^ 24 шагов без улучшения, предыдущий размер выводится для текущего значения n, и n увеличивается.
Результаты до n = 9
2, 4, 10, 16, 31, 47, 76, 112, 168
улучшаются по сравнению с предыдущими результатами для n = 8 на один и для n = 9 на два. Для более высоких значений n может быть увеличено ограничение в 2 ^ 24 шага.Я также пробовал моделируемый отжиг (с количеством спичек в качестве энергии), но без улучшения по сравнению с самым крутым спуском.
Код
сохранить как
Question54354.java
скомпилировать с
javac Question54354.java
запустить с
java Question54354
источник
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
Примечания
Если мы рассмотрим граф
G
с вершинами0
доn
и ребер , соединяющих две цифры , которые совпадают, то тензор мощностьG^n
имеет вершины ,(x_0, ..., x_{n-1})
образующие декартова степени{0, ..., n}^n
и ребро между согласующими кортежами. Представляющий интерес граф является подграфом,G^n
индуцированным теми вершинами, которые соответствуют возможным «счетным массивам».Итак, первая подзадача состоит в том, чтобы создать эти вершины. Наивный подход перечисляет над
2^{2n-1}
строками или порядка4^n
. Но если мы вместо этого посмотрим на массив первых разностей счетных массивов, мы обнаружим, что есть только3^n
возможности, и из первых различий мы можем вывести диапазон возможных начальных значений, требуя, чтобы ни один элемент в нулевых разностях не был меньше0
или больше чемn
.Затем мы хотим найти максимальный независимый набор. Я использую одну теорему и две эвристики:
(n, n, ..., n)
будет в максимально независимом наборе. Есть довольно большая клика вершин,{m, m+1, ..., n}^n
гдеm
наименьшее целое число, которое соответствуетn
;(n, n, ..., n)
гарантированно не будет совпадений за пределами этой клики.На моем компьютере это происходит
111
заn=8
16 секунд,166
заn=9
8 минут и235
заn=10
2 часа.Код
Сохранить как
PPCG54354.java
, скомпилировать какjavac PPCG54354.java
и запустить какjava PPCG54354
.источник
Mathematica
n = 5
,, 31 строкаЯ только что написал решение для грубой силы, используя встроенные модули Mathematica, чтобы проверить примеры ответов Лембика, но оно также может справиться
n = 5
:В качестве бонуса этот код создает визуализацию проблемы в виде графика, где каждое ребро указывает две совпадающие строки.
Вот график для
n = 3
:источник
C ++ (эвристический): 2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
Это немного отстает от результата Питера Тейлора, будучи на 1–3 меньше
n=7
,9
и10
. Преимущество в том, что это намного быстрее, поэтому я могу запустить его для более высоких значенийn
. И это можно понять без всякой причудливой математики. ;)Текущий код рассчитан на запуск
n=15
. Время выполнения увеличивается примерно в 4 раза для каждого увеличенияn
. Например, это было 0,008 секундыn=7
, 0,07 секундыn=9
, 1,34 секундыn=11
, 27 секундn=13
и 9 минутn=15
.Я использовал два ключевых наблюдения:
c
исключением диапазонаc / 2
для2 * c
других значений. Для меньших значенийc
этот диапазон меньше, что означает, что меньшее количество значений исключается при его использовании.Генерация уникальных массивов подсчета
Я использовал грубую силу, перебирая все значения, генерируя массив count для каждого из них и выводя результирующий список. Конечно, это можно сделать более эффективно, но этого достаточно для тех значений, с которыми мы работаем.
Это очень быстро для небольших значений. Для больших значений накладные расходы становятся существенными. Например, для
n=15
него используется около 75% всего времени выполнения. Это определенно будет область, на которую стоит обратить внимание при попытке подняться намного вышеn=15
. Даже просто использование памяти для построения списка подсчитывающих массивов для всех значений станет проблематичным.Количество уникальных счетных массивов составляет около 6% от количества значений для
n=15
. Этот относительный счет становится меньше, когдаn
становится больше.Жадный выбор подсчета значений массива
Основная часть алгоритма выбирает подсчет значений массива из сгенерированного списка, используя простой жадный подход.
Исходя из теории, что использование счетных массивов с небольшими счетами выгодно, счетные массивы сортируются по сумме их подсчетов.
Затем они проверяются по порядку, и выбирается значение, если оно совместимо со всеми ранее использованными значениями. Таким образом, это включает в себя один линейный проход через уникальные счетные массивы, где каждый кандидат сравнивается с ранее выбранными значениями.
У меня есть некоторые идеи о том, как можно улучшить эвристику. Но это казалось разумной отправной точкой, и результаты выглядели довольно хорошо.
Код
Это не очень оптимизировано. В какой-то момент у меня была более сложная структура данных, но для ее обобщения потребовалось бы больше работы
n=8
, и разница в производительности не казалась существенной.источник
n=4
уже. Это могло бы закончитьсяn=5
с некоторым терпением. Вы, должно быть, использовали лучшую стратегию возврата, чтобы даже сделать этоn=7
. Была ли ваша эвристика, или она исследовала все пространство решений? Я обдумываю некоторые идеи о том, как сделать это лучше, либо путем точной настройки порядка сортировки, либо, возможно, не будучи чисто жадным.3^n
и две эвристики, которые он описывает.n=7
быстро находит 76 . Но, пытаясь это сделатьn=9
, он все еще застрял на 164, когда я остановил его через 20 минут. Таким образом, расширение этого с помощью ограниченной формы простого возврата не выглядит в целом многообещающим.