ОТ АВТОРА

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

Для заполнения кроссворда всегда используется перебор. Мы ставим первое слово, затем все следующие, проверяя, чтобы буквы на пересечениях совпадали с буквами в словах, поставленных ранее. И так, пока все слова не будут поставлены. Казалось бы – нет ничего проще. Однако простой подсчет количества итераций подбора слов для кроссворда средней длины на 50 слов может изменить это мнение. Так, для установки любого слова, кроме первого, при наличии 1 000 слов соответствующей длины в базе и наличия всего одного заполненного ранее слова на пересечении, в среднем понадобится 1 000/33 = 30 итераций (нам, в среднем, нужно будет просмотреть 30 слов, прежде чем нам попадется слово, имеющее нужную букву на позиции заполненного ранее пересечения). При наличии более одного заполненного ранее слова-пересечения, это количество будет резко расти. Простой подсчет показывает, что для заполнения 50 слов, нам нужно выполнить 30^(50-1) итераций. Это миллиарды миллиардов итераций. Даже на современных компьютерах, это потребует дни и месяцы работы. И здесь на первое место выходит уже не собственно перебор, а алгоритм, который позволит сократить время генерации кроссворда на много порядков.

На дорожку…

Сразу, «на берегу», мы должны принять то, что генерация кроссворда будет состоять из двух этапов:

  • Анализ – создание плана генерации, основным результатом которого является определенная последовательность генерации слов кроссворда и другие данные, которые будут помогать на этапе генерации.
  • Генерация – последовательное заполнение сетки кроссворда словами, методом полного перебора всех возможных вариантов, с учетом данных, полученных на этапе анализа.

Далее я буду помечать решения, приведенные далее, к какому этапу они применимы.

Все опыты будут ставиться на кроссворде, приведенном на рисунке ниже.

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

И последнее. В статье будет опущено все, что касается генерации базы слов для программы. Эта часть «стоила» не менее 50% всего затраченного времени. Сейчас в базе более 158 тыс. слов, из которых более 125 тыс. являются уникальными. База в максимальной степени вычищена программным способом, однако все еще требует к себе внимания в ручном режиме. Я не стал каким либо способом закрывать или шифровать базу – она лежит открытая в текстовом виде в простейшем key-value формате. Вы можете удалить или добавить в ней слова, подкорректировать описания или полностью заменить своей (например, на другом языке).

Рассмотрим сам алгоритм подробнее

ОТ АВТОРА

Сайт создан в системе uCoz