Эффективный алгоритм скремблирования слов - PullRequest
11 голосов
/ 24 апреля 2009

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

Например, скажем, мне дан список букв: {e, e, h, r, s, t}. Мне нужно упорядочить их таким образом, чтобы они содержали максимальное количество слов. Если я заказываю эти буквы в "theres", в них содержатся слова "the", "there", "her", "here" и "ere". Таким образом, этот пример может иметь 5 баллов, поскольку он содержит 5 слов. Я хочу упорядочить буквы таким образом, чтобы набрать наибольшее количество баллов (содержать как можно больше слов).

Наивным алгоритмом было бы попытаться оценить каждую перестановку. Я считаю, что это O (n!), Поэтому 720 различных перестановок будут опробованы только для 6 букв выше (включая некоторые дубликаты, поскольку в примере e дважды). Конечно, для большего количества букв наивное решение быстро становится невозможным.

Алгоритм не должен на самом деле создавать самое лучшее решение, но он должен найти хорошее решение за разумное время. Для моего приложения простое угадывание ( Монте-Карло ) для нескольких миллионов перестановок работает довольно плохо, так что в настоящее время этот показатель лучше.

В настоящее время я использую алгоритм Aho-Corasick для оценки перестановок. Он ищет каждое слово в словаре всего за один проход по тексту, поэтому я считаю, что это довольно эффективно. Это также означает, что все слова хранятся в trie , но если для другого алгоритма требуется другое хранилище, это тоже хорошо. Я не беспокоюсь о настройке словаря, просто время выполнения заказа и поиска. При необходимости можно использовать даже нечеткий словарь, например Bloom Filter .

Для моего приложения список букв составляет около 100, а словарь содержит более 100 000 записей. Словарь никогда не меняется, но необходимо заказать несколько разных списков букв.

Я рассматриваю попытку алгоритма поиска пути . Я полагаю, что я мог бы начать со случайной буквы из списка в качестве отправной точки. Затем каждая оставшаяся буква будет использоваться для создания «пути». Я думаю, что это будет хорошо работать с алгоритмом оценки Aho-Corasick, так как оценки могут быть построены по одной букве за раз. Я еще не пробовал найти путь; может это даже не хорошая идея? Я не знаю, какой алгоритм поиска пути может быть лучшим.

Другой алгоритм, о котором я подумал, также начинается со случайной буквы. Затем в словаре будет выполняться поиск «богатых» ветвей, содержащих оставшиеся буквы. Ветви словаря, содержащие недоступные буквы, будут удалены. Я немного запутался в деталях того, как это будет работать точно, но это может полностью исключить перестановки выигрышей.

Ответы [ 4 ]

3 голосов
/ 25 апреля 2009

Вот идея, вдохновленная Марковскими цепями :

  1. Предварительно вычислите вероятности перехода букв в вашем словаре. Создайте таблицу с вероятностью того, что за любой буквой X будет следовать другая буква Y для всех пар букв на основе слов в словаре.
  2. Создание перестановок путем случайного выбора каждой следующей буквы из оставшегося пула букв на основе предыдущей буквы и таблицы вероятностей, пока все буквы не будут использованы. Запустите это много раз.
  3. Вы можете экспериментировать, увеличив «память» своей таблицы переходов - не смотрите только одну букву назад, а говорите 2 или 3. Это увеличивает таблицу вероятностей, но дает вам больше шансов на создание правильного слова.
3 голосов
/ 24 апреля 2009

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

2 голосов
/ 24 апреля 2009

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

Другой вариант для вашего алгоритма - построить наименьшее возможное слово из входного набора, а затем добавить по одной букве за раз, чтобы новое слово также было или содержало новое слово. Начните с нескольких разных начальных слов для каждого входного набора и посмотрите, куда он ведет.

Всего несколько пустых мыслей.

0 голосов
/ 24 апреля 2009

Может быть полезно проверить, как другие решили это: http://sourceforge.net/search/?type_of_search=soft&words=anagram

На этой странице вы можете создавать анаграммы онлайн. Я играл с этим некоторое время, и это очень весело. Это не объясняет подробно, как это делает свою работу, но параметры дают некоторое представление. http://wordsmith.org/anagram/advanced.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...