Сворачивание набора строк на основе заданного расстояния Хэмминга

Учитывая набор строк (первый столбец) вместе с количеством (второй столбец), например:

aaaa 10
aaab 5
abbb 3
cbbb 2
dbbb 1
cccc 8

Существуют ли какие-либо алгоритмы или даже реализации (в идеале в виде исполнителя Unix, R или python), которые сворачивают этот набор в новый набор на основе заданного расстояния Хэмминга.

  • Сворачивание подразумевает добавление счетчика
  • Строки с меньшим числом сворачиваются в строки с большим числом.

Например, скажем, для расстояния Хэмминга 1 приведенный выше набор свернет вторую строку aaab в aaaa, поскольку они находятся на расстоянии 1 Хэмминга друг от друга, а aaaa имеет более высокий счет. Свернутая запись будет иметь общий счет, здесь aaaa 15

Таким образом, для этого набора мы получили бы следующий свернутый набор:

aaaa 15
abbb 6
cccc 8

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

Дополнительная предыстория и мотивация

Вычисление расстояния Хэмминга между двумя строками (парой) реализовано в большинстве языков программирования. Решение грубой силы будет вычислять расстояние между всеми парами. Может быть, нет никакого способа обойти это. Однако, например. Я полагаю, что эффективные решения позволили бы избежать вычисления расстояния для всех пар и т. д. Возможно, есть умные способы сохранить некоторые вычисления, основанные на метрической теории (поскольку расстояние Хэмминга является метрикой), например. если расстояние Хэмминга между x и z равно 3, а x и y равно 3, я могу не вычислять между y и z. Может быть, есть умный подход k-mer или, может быть, какое-то эффективное решение для постоянного расстояния (скажем, d=1).

Даже если бы это было только решение грубой силы, мне было бы любопытно, было ли это реализовано раньше и как его использовать (в идеале, без необходимости реализовывать его самому).


person Sebastian Müller    schedule 06.11.2019    source источник
comment
Я хорошо знаю, как вычислить a между двумя строками, но вопрос касается набора (!) Укусов, что не так тривиально (например, я бы предположил, что эффективные решения позволили бы избежать вычисления расстояния для всех пар и т. д. ). На самом деле я довольно много исследовал это и не знаю программы, которая решает поставленный пример. Не могли бы вы предоставить это на случай, если я что-то упустил?   -  person Sebastian Müller    schedule 06.11.2019
comment
Я не вижу другой альтернативы, кроме грубой силы с помощью цикла. Возможно, есть способ ускорить его с помощью разумного использования алгоритма сортировки, смешанного с вычислением Хэмминга. Я отзову свой предыдущий комментарий, так как дополнительная сложность группы строк вышла за рамки моей головы :-)   -  person Nic3500    schedule 06.11.2019
comment
Не беспокойся! Я полагаю, что есть умные способы сохранить некоторые вычисления, основанные на метрической теории и т. д. (например, если расстояние Хэмминга между x и z равно 3, а x и y равно 3, я могу избежать вычислений между y и z). Может быть, есть умный подход k-mer. Даже если бы это было решение грубой силы, мне было бы любопытно, было ли это реализовано раньше.   -  person Sebastian Müller    schedule 06.11.2019
comment
Кроме того, может ли тот, кто проголосовал за вопрос, пояснить, почему? Это так, я могу улучшить этот и / или будущие вопросы!   -  person Sebastian Müller    schedule 06.11.2019
comment
Это был я, я не мог удалить его некоторое время. Его больше нет.   -  person Nic3500    schedule 06.11.2019
comment
Может быть, у кого-то на //math.stackexchange.com появится идея для алгоритма, но перекрестная публикация не приветствуется. Если через день-два здесь не ответят, удалить здесь и сделать репост туда? Удачи.   -  person shellter    schedule 06.11.2019
comment
@SebastianMüller Дополнительная информация, которую вы написали в комментариях (то, что вы уже знаете или о чем думали), должна быть частью вопроса. Комментарии предназначены для уточнения запросов или советов по улучшению. Пожалуйста, отредактируйте свой вопрос и добавьте в него всю необходимую информацию.   -  person Bodo    schedule 06.11.2019
comment
@shellter Я мог бы сделать это, однако это больше вопрос информатики, поэтому я думаю, что он должен быть здесь в этой форме. Было бы неодобрительно, если бы я перефразировал это в сторону математических вопросов, например. сосредоточившись на математических решениях, а не на конкретной реализации?   -  person Sebastian Müller    schedule 07.11.2019
comment
@Bodo Хороший вопрос, я соответствующим образом отредактировал вопросы и надеюсь, что теперь все в порядке.   -  person Sebastian Müller    schedule 07.11.2019


Ответы (1)


Я придумал следующее:

Это сообщает об элементе с наивысшим баллом с суммой его баллов и баллов его ближайших соседей. Когда используется соседний объект, об этом отдельно не сообщается.

Я предлагаю использовать дерево точек обзора в качестве метрического индекса.

Алгоритм будет выглядеть так:

  1. построить метрический индекс из строк и их оценок
  2. построить максимальную кучу из строк и их оценок
  3. для строки с наивысшим баллом в максимальной куче:
  4. используйте метрический индекс, чтобы найти ближайшие строки
  5. напечатайте строку и сумму ее очков и ближайших к ней строк
  6. удалить из индекса метрики строку и каждую из ближайших к ней строк
  7. удалить из максимальной кучи строку и каждую из ближайших строк
  8. повторяйте 3-7, пока максимальная куча не станет пустой

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

  1. построить метрический индекс из строк и их оценок
  2. построить максимальную кучу из строк и их оценок
  3. построить используемую таблицу из пустого набора
  4. для строки с наивысшим баллом в максимальной куче:
  5. если эта строка находится в используемой таблице: начать со следующей строки
  6. используйте метрический индекс, чтобы найти ближайшие строки
  7. удалить все соседние строки, которые находятся в используемой таблице
  8. напечатайте строку и сумму ее очков и ближайших к ней строк
  9. добавить ближайшие строки в используемую таблицу
  10. повторяйте 4-9, пока максимальная куча не станет пустой

Я не могу предоставить анализ сложности.

Я думал о втором алгоритме. Часть, которая, как мне показалось, была медленной, заключалась в проверке соседства с использованным столом. В этом нет необходимости, так как удаление из дерева точек наблюдения может быть выполнено за линейное время. При поиске соседей запоминайте, где они были найдены, а затем удаляйте их позже, используя эти местоположения. Если в качестве точки наблюдения используется сосед, пометьте его как удаленный, чтобы поиск не возвращал его, но в противном случае оставьте его в покое. Это, я думаю, восстанавливает его ниже квадратичного. В противном случае это было бы что-то вроде количества элементов, умноженных на размер окрестности.


В ответ на комментарий. Проблема заключалась в том, что "Строки с меньшим числом сворачиваются в строки с большим числом". как таковой, это вычисляет это. Это не жадное приближение, которое могло бы привести к неоптимальному результату, поскольку нечего было максимизировать или минимизировать. Это точный алгоритм. Он возвращает элемент с наивысшим баллом в сочетании с баллом его окрестности.

Это можно рассматривать как назначение лидера каждому соседству таким образом, чтобы у каждого элемента был не более одного лидера, и этот лидер на данный момент имеет наибольший общий балл. Это можно рассматривать как ориентированный граф.

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

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

person Dan D.    schedule 07.11.2019
comment
Это похоже на жадный алгоритм, который не гарантирует необязательное решение, но должен быть достаточно хорошим и эффективным. Я полагаю, вы не знаете ни одного программного обеспечения, в котором это реализовано? Кроме того, что вы подразумеваете под метрическим индексом? Фрейм данных? - person Sebastian Müller; 07.11.2019
comment
Вы правы, я не указал, что максимизировать. Я полагаю, что при этом эта стратегия не может считаться жадной (с чем я был бы согласен, так как я все равно не ищу гарантированного оптимального решения). Я приму это всего через несколько дней на случай, если у кого-то будет реальная реализация, так как я хотел избежать ее реализации самостоятельно. Если бы мне пришлось (возможно, на питоне), не могли бы вы уточнить, что вы подразумеваете под metric index? - person Sebastian Müller; 08.11.2019
comment
Я пытаюсь реализовать вышеизложенное в python, но борюсь с пунктом 7, поскольку максимальные кучи позволяют удалять только максимальные элементы (heapq.heappop), но не любые другие элементы (например, близлежащие укусы). docs.python.org/3.7/library/heapq.html. Рад поделиться кодом или обсудить - person Sebastian Müller; 12.11.2019
comment
Вот почему я описал версию, которая не требовала удаления, вторую версию и примечание ко второй версии, в которой используется набор для хранения списка удаленных элементов, чтобы их можно было игнорировать при извлечении из максимальной кучи. И по мере их обнаружения их можно удалить из набора. - person Dan D.; 13.11.2019