Принятие решения о том, полностью ли соответствует подстановочная строка другой подстановочной строке в наборе

9

Вот проблема, которая беспокоила меня некоторое время. Допустим, строка представляет собой последовательность из 1 и 0, а строка с подстановочными символами - это последовательность из 1, 0 и? S. Все строки и строки шаблона имеют одинаковую длину. Это стандартные подстановочные знаки UNIX; 10 ?? 1 соответствует 10011, 10111 и т. Д. - а? соответствует 1 или 0 в этой позиции. Еслиv а также w являются шаблонными строками, тогда мы пишем vw если каждая строка соответствует v также соответствует w,

Проблемы : дан наборS подстановочных строк и запрос v (также подстановочная строка), существует ли wS такой, что vw? А если нет, можем ли мы добавитьv в S эффективно?

Вот очевидное О(КмN) решение (где К это размер строк, мэто размер слова ОЗУ (обычно 32 или 64)): просмотрите каждый элемент списка и проверьте условие (которое может быть выполнено в 2 или 3 операциях с использованием бит-тиддлинга). Также проверьте, еслиvвес вмещает любой предмет веспока мы сканируем Еслиv не проходит наш тест, затем добавьте v к набору, и удалите весМы отметили.

Но это не достаточно быстро. Было бы здорово, если быО(журналN) решение или, в идеальном мире, сложность, подобная основному дереву (О(К)). Также нормально, чтобы запросы были примерно правильными : еслиvвесзатем верните да или нет; но если условие не выполняется, обязательно верните no.

Хотя это не помогает в худшем случае, вы можете предположить, что все элементы в Sограничены подстановочной строкой; то есть существуетv такой, что для всех весS, vвес,

Идеи, которые я пробовал

  • Строка подстановочных знаков образует полурешетку соединения. У нас может быть n-арное дерево, содержащее подстановочные строки; листья были бы подстановочными символами, а ветви - объединением всех детей. Если запрос и объединение несопоставимы, нам не нужно тратить время на сравнение со всеми дочерними элементами этой ветви. Кроме того, если мы производим обновление, а обновление оказывается больше, чем объединение, мы можем просто удалить всю ветку. К сожалению, это все ещеО(N) в худшем случае, и мы не всегда находим «лучшие» объединения для сканирования при добавлении элементов в дерево.
  • Можно сформировать корень из S, Мы знаем этоSограничен некоторой подстановочной строкой; Предположим, что это? 0? 0. Тогда все ветви дерева должны быть только на 1-м и 3-м битах строк. Если текущий бит, на который мы выполняем ответвление, равен 1, мы должны проверить? и 1 филиал; если это 0, мы проверяем? и 0 веток; если это так, мы только проверяем? филиал. Поскольку нам потенциально приходится брать несколько веток, это не очень хорошо (сложно обновить дерево по той же причине). Поскольку сопоставление является очень очень быстрой операцией, по сравнению с наивной стратегией больно выполнять много обходов в дереве (следование куче указателей намного дороже, чем выполнение некоторых OR и AND).

Связанных с работой

  • В сетевом сообществе эта проблема проявляется как «классификация пакетов», здесь представлен хороший обзор известных алгоритмов и структур данных . К сожалению, почти всегда делается предположение, что подстановочные строки соответствуют только префиксам, и запрос является кортежем таких строк. Конечно, мы всегда можем преобразовать общую подстановочную строку для соответствия этим критериям: 1? 00? 1 ?? есть (1,?, 0, 0,?, 1,?,?). Это не будет эффективным, хотя. Другое предположение состоит в том, что эти кортежи связаны с «цветом», и запрос должен возвращать цвет (а не только то, что он соответствует). Это делает проблему намного сложнее, потому что мы должны упорядочить кортежи (или это неоднозначно, какой из (0,?) И (?, 1) соответствует (0, 1)).

  • В сообществе алгоритмов я нашел много результатов, связанных с поиском подстрок, которые соответствуют "пофиг". Это значительно более сложная проблема, и я не могу использовать ни одну из техник.

В заключении

Спасибо за любую помощь!

Кристофер Монсанто
источник
1
Насколько большими могут быть строки? И почему вы не учитываете их длину в сложности? Очевидно, вам нужны строки, чтобы бытьΩ(LогN) иначе у тебя просто не было бы Nотдельные строки для работы. Также кажется интуитивным, что если вы позволитеО(N)длины строк, тогда вам придется посмотреть на все ваши строки в структуре данных в худшем случае ... есть ли ограничения на длину строки? Поли-логарифмическая?о(N)?
Артем Казнатчеев
Извините, если мне не ясно. Струны имеютО(1)размер; Вы можете думать о них как о 32 символах. «Строка» была просто удобной абстракцией для постановки задачи - они на самом деле представлены как (целочисленные, битовые маски) кортежи, так что я могу вычислить соединение иvвесвсего за несколько машинных операций. (Конечно, проблему можно естественным образом расширить на строки большего размера с постоянным размером, увеличив число целых и битовых полей).
Кристофер Монсанто
Мой вышеприведенный комментарий, вероятно, бесполезен для аргумента сложности :(. На самом деле нет никакой связи между размером строк и размером набора, если вы позволяете изменять размер строк. Если это так верно быть О(N)наихудший случай, к сожалению, но в любом случае меня больше интересует средний случай (или приближения).
Кристофер Монсанто

Ответы:

3

Как насчет использования конечного автомата? ЯзыкSконечно и, следовательно, регулярно. Даже после приведенных ниже преобразований все равно будет регулярно. Поэтому после обычных шагов по преобразованию регулярного выражения в детерминированный конечный автомат у вас будет распознаватель того, что вы хотите, который работает вО(К)время. Надеюсь, что эта идея все еще будет работать, если есть ошибки в том, что предлагается ниже.

Проблема в том, как бороться с подстановочным оператором: Подстановочный знак в подстановочной строке соответствует 0 или 1 в тестовой строке. Но поскольку мы пытаемся распознать подстановочные знаки, подстановочный знак в подстановочной строке соответствует 0, 1 или? в другой строке шаблона. Этот набор все еще регулярен, поэтому мы преобразовываем каждое вхождение? к регулярному выражению (0 | 1 |?), где вертикальная черта - обычный оператор чередования. Так что если весь ваш наборS равен {10 ?? 1, 0? 1? 0}, результирующее регулярное выражение будет (10 (0 | 1 |?) (0 | 1 |?) 1 | 0 (0 | 1 |?) 1 (0 | 1 |?) 0)

Что касается добавления строк в машину, недавно была проведена работа по постепенному изменению конечного автомата. См. Эту статью Daciuk et al. «Инкрементальное построение минимальных ациклических конечных автоматов».

Это помогает?

Застенчивый человек
источник
Да, я считал автоматы (то, что я делал с этим деревом, было похоже на то, как можно принять строку с автоматами). Однако я не нашел такой работы по постепенному построению указанных автоматов. Я проверю это, спасибо за указатель ShyPerson.
Кристофер Монсанто
Я процитировал статью Дачука и др., Потому что она казалась наиболее близкой к тому, чего вы пытаетесь достичь. Но я думаю, что стоит упомянуть, что проблема была решена совсем недавно для произвольных автоматов в конечных состояниях Карраско и Форкадой в их статье «Инкрементная конструкция и обслуживание минимальных автоматов в конечных состояниях»: mitpressjournals.org/doi/abs/10.1162/ …
ShyPerson
Хорошо, я не думаю, что я получу больше от этой темы, поэтому я принимаю ваш ответ. Спасибо!
Кристофер Монсанто