Расстояние Хэмминга между двумя строками одинаковой длины - это количество позиций, в которых соответствующие символы различны.
Позвольте P
быть двоичной строкой длины n
и T
быть двоичной строкой длины 2n-1
. Мы можем вычислить n
расстояния Хэмминга между подстрокой P
каждой n
длины T
в порядке слева направо и поместить их в массив (или список).
Пример последовательности расстояний Хэмминга
Пусть P = 101
и T = 01100
. Последовательность расстояний Хэмминга, которую вы получаете от этой пары, такова 2,2,1
.
Определение близости
Теперь давайте рассмотрим две такие последовательности расстояний Хэмминга. Скажи x = (0, 2, 2, 3, 0)
и y = (2, 1, 4, 4, 2)
как примеры. Мы говорим , что x
и y
в close
случае y <= x <= 2*y
или если x <= y <= 2*x
. Здесь скалярное умножение и неравенство взяты поэлементно. То есть, для двух последовательностей A
и B
, A <= B iff A[i] <= B[i]
по всем показателям i
.
Обратите внимание, что последовательности расстояний Хэмминга образуют частичный порядок при таком способе их сравнения. Другими словами, многие пары последовательностей не являются ни большими, ни равными, ни меньшими или равными друг другу. Например (1,2)
и (2,1)
.
Таким образом, используя пример выше, (0, 2, 2, 3, 0) <= 2*(2, 1, 4, 4, 2) = (4, 2, 8, 8, 4)
но (0, 2, 2, 3, 0)
не больше, чем (2, 1, 4, 4, 2)
. Также (2, 1, 4, 4, 2)
не меньше или равно 2*(0, 2, 2, 3, 0) = (0, 4, 4, 6, 0)
. В результате x
и y
не близко друг к другу.
задача
Для увеличения, n
начиная с n=1
, рассмотрим все возможные пары двоичных строк P
длины n
и T
длины 2n-1
. Есть 2^(n+2n-1)
такие пары и, следовательно, много последовательностей расстояний Хэмминга. Однако многие из этих последовательностей будут идентичны. Задача состоит в том, чтобы найти размер наибольшего набора последовательностей расстояний Хэмминга, чтобы никакие две последовательности не были близки друг к другу.
Ваш код должен выводить одно число на значение n
.
Гол
В общем, ваш счет - самый высокий показатель, который n
ваш код достигает на моей машине за 5 минут (но читайте дальше). Время для общего времени работы, а не время только для этого n
.
Чтобы получить оценки за неоптимальные ответы, потому что найти оптимальные ответы, скорее всего, будет сложно, нам понадобится немного тонкая система подсчета очков. Ваша оценка - это наибольшее значение, n
для которого никто другой не опубликовал более правильный ответ для любого размера, который меньше этого. Например, если вы выводите данные, 2, 4, 21
а кто-то другой выводит данные, 2, 5, 15
вы получите оценку только 1
за то, что у кого-то есть лучший ответ n = 2
. Если вы выводите данные, 2, 5, 21
вы получаете оценку 3
независимо от того, что выводит кто-то еще, поскольку все эти ответы являются оптимальными. Очевидно, что если у вас есть все оптимальные ответы, вы получите балл за самый высокий n
пост. Тем не менее, даже если ваш ответ не является оптимальным, вы все равно можете получить счет, если никто другой не сможет его побить.
Пример ответов и проработанный пример
(Эти ответы еще не проверены. Независимая проверка будет принята с благодарностью.)
Благодаря ETHproductions:
- n = 1 дает 2.
- n = 2 дает 5.
- n = 3 дает 21.
Давайте посмотрим на n = 2
более подробно. В этом случае полный список последовательностей расстояний Хэмминга (представленных здесь кортежами):
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
Мы видим, что (0,0)
это не близко к любому другому кортежу. В самом деле , если мы возьмем (0, 0)
, (0, 1)
, (1, 0)
, (2, 1)
, (1,2)
то ни один из этих кортежей не близки к какой - либо из других. Это дает оценку 5
для n = 2
.
Для n = 3
полного списка различных последовательностей расстояний Хэмминга:
[(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 2), (0, 2, 3), (0, 3, 0), (0, 3, 1), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 3, 0), (1, 3, 1), (1, 3, 2), (2, 0, 1), (2, 0, 2), (2, 0, 3), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 0), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 3, 1), (2, 3, 2), (2, 3, 3), (3, 0, 2), (3, 0, 3), (3, 1, 0), (3, 1, 1), (3, 1, 2), (3, 2, 0), (3, 2, 1), (3, 2, 2), (3, 3, 2), (3, 3, 3)]
Из этих 48
последовательностей мы можем выбрать набор размеров, 21
чтобы ни одна пара в этом наборе не была близка друг к другу.
Языки и библиотеки
Вы можете использовать любой доступный язык и библиотеки, которые вам нравятся. Там, где это возможно, было бы хорошо иметь возможность запускать ваш код, поэтому, пожалуйста, включите полное объяснение того, как запускать / компилировать ваш код в Linux, если это вообще возможно.
Моя машина Время будет работать на моей 64-битной машине. Это стандартная установка Ubuntu с 8 ГБ ОЗУ, восьмиъядерным процессором AMD FX-8350 и Radeon HD 4250. Это также означает, что мне нужно иметь возможность запускать ваш код.
Ведущий ответ
- Счет 4 за 2, 5, 21, 83, 361 Кристиана Сиверса. C ++
- Оценка 5 за 2, 5, 21, 83, 372 по fəˈnɛtɪk. Javascript
Ответы:
C ++ с использованием библиотеки igraph
Спасибо за прекрасную возможность выучить новую библиотеку!
Эта программа теперь вычисляется
2, 5, 21, 83, 361
быстро. Вы можете контролировать печать узлов сPRINTNODES
константой.Используемый граф имеет дополнительные ребра между узлами, соответствующими векторам расстояния, где один из них близок (но не равен) другому, а другой перевернут. Это ускоряет вычисления, и любой найденный независимый набор, конечно, также является одним из исходных графов. Кроме того, даже если он не полностью реализован, вычисленный независимый набор закрывается при обращении. Я считаю, что всегда существует максимальный независимый набор с этим свойством. По крайней мере, есть один для
n<=4
. (Я уверен, что могу показать 83 оптимально.)Чтобы скомпилировать на Debian, установите
libigraph0-dev
и сделайтеg++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o ig ig.cpp -ligraph
.Старое описание:
Библиотека igraph имеет функцию для вычисления максимального размера независимого набора вершин графа. Он может решить эту проблему
n=3
менее чем за секунду и не заканчивается в течение нескольких днейn=4
.Поэтому я делаю граф на связанные компоненты и позволяю библиотеке обрабатывать небольшие (меньше, чем
MAXDIRECT
узлы) компоненты. Для других компонентов я выбираю вершину и удаляю ее. В лучшем случае это разбивает график на несколько компонентов, но обычно это не так. В любом случае, компоненты (возможно, только один) меньше, и мы можем использовать рекурсию.Очевидно, что выбор вершины важен. Я просто беру один из максимальной степени. Я обнаружил, что получаю лучший результат (но только для
n=4
), когда использую перевернутый список узлов. Это объясняет волшебную частьconstruct
функции.Возможно, стоит улучшить выбор. Но кажется более важным пересмотреть удаленные узлы. Прямо сейчас я никогда не смотрю на них снова. Некоторые из них могут быть не связаны ни с одним из выбранных узлов. Проблема в том, что я не знаю, какие узлы образуют независимое множество. Например, удаление узлов перенумеровывает остальные узлы. Это можно сделать, прикрепив к ним атрибуты. Но что еще хуже, вычисление числа независимости просто дает это число. Лучшая альтернатива, предлагаемая библиотекой, состоит в том, чтобы вычислять все самые большие независимые наборы, что медленнее (насколько кажется, зависит от размера графика). Тем не менее, это, кажется, прямой путь. Гораздо более расплывчато, я также думаю, что было бы полезно рассмотреть, можем ли мы использовать особый способ определения графа.
Случай
n=6
может стать достижимым (вообще, не обязательно через 5 минут), если я заменю рекурсию циклом, используя очередь для остальных компонентов.Мне было интересно взглянуть на компоненты графиков. Ведь
n=4
их размеры есть168, 2*29, 2*28, 3, 4*2, 4*1
. Только самый большой не может быть обработан напрямую.Для
n=5
, этих размеров1376, 2*128, 2*120, 119, several <=6
.Я ожидаю, что эти двойные размеры будут соответствовать изоморфным графам, но использование этого, похоже, не стоит, потому что всегда есть один доминирующий самый большой компонент:
Поскольку
n=6
самый большой компонент содержит11941
узлы (из общего числа15425
), следующие два самых больших компонента имеют размер596
.Ибо
n=7
эти цифры есть107593 (125232), 2647
.источник
g++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o sievers sievers.cpp -ligraph
. Это важно где-ligraph
есть.set
я использую, чтобы избежать дубликатов, но я даже не думал об их порядке, когда писал этот код. Внутренний цикл, начинающийся с «i+1
просто», избегает смотреть на пару, а также на ее замененную версию, которая не нужна и является самым простым способом избежать петель (ребер(a,a)
). Это не зависит от порядка, в котором приходят узлы, мне все равно, получу я(a,b)
или(b,a)
.Javascript, Seq: 2,5,21,
8183,37267,349Удалось увеличить значение на 4 с помощью случайного удаления элементов в начале моего поиска. Как ни странно, удаление 20 элементов с более чем 6 соединениями было быстрее, чем удаление 5 элементов с более чем 8 соединениями ...
Эта последовательность, вероятно, не оптимальна для 5 и не может быть оптимальной для 4. Хотя ни один из узлов не является близким к другому в наборе.
Код:
Попробуйте онлайн!
Фрагмент, который можно добавить в конец программы, чтобы показать, какие последовательности расстояний Хэмминга каждой выбранной последовательности расстояний Хемминга
Объяснение:
Во-первых, код генерирует все уникальные расстояния Хемминга от подстрок.
Далее код преобразует этот список в неориентированный граф
Наконец, код циклически перебирает этот граф, удаляя вершину с наибольшим количеством соединений каждый цикл, прежде чем восстанавливать любые узлы, которые теперь будут иметь меньше соединений, чем текущий максимум. По окончании этого цикла выводится количество оставшихся узлов.
Наборы:
1:
2:
3:
4:
5:
источник