Как найти все слова на доске Boggle с помощью динамического программирования?

Я записался на курс «Алгоритмы, часть II» на Coursera, и одно из заданий - для прохождения игры Boggle: http://coursera.cs.princeton.edu/algs4/assignments/boggle.html

Кодекс чести требует, чтобы я не публиковал решение публично, поэтому вот псевдокод базового алгоритма.

visit:
  word <- board[i][j]
  start <- dictionary.match(word, start)
  if start is not null
      visited[i][j] <- true
      word <- prefix + word
      if word is longer than min required length 
          words <- words + word

      for (x, y) ∊ adj(i, j)
          if not visited(x, y)
            visit (x, y)

  visited[i][j] <- false

Словарь реализован с использованием Trie.

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

Оказывается, мы можем использовать изящную технику динамического программирования, чтобы быстро проверить, можно ли построить слово (в данном случае из словаря) с доски!

Вот основная идея идеи динамического программирования:

Чтобы слово длины k (конечное положение) было найдено в [i, j] -м месте доски, k-1-я буква этого слова должна быть расположена в одной из соседних ячеек [i, j].

Базовый случай k = 1.

Буква длины 1 будет найдена (конечное положение) в [i, j] -й ячейке доски, если единственная буква в слове соответствует букве в [i, j] -м месте доски.

Как только наша таблица динамического программирования заполнена базовым случаем, мы можем построить поверх него для любого слова длины k, k> 1.

К сожалению, автор плохо объяснил, и я не могу понять его решение. Я бы хотел, и надеюсь, что кто-нибудь здесь сможет мне это объяснить.

P.S .:

  1. Не дубликат этого вопроса, так как он не использует DP; пожалуйста, держите эти счастливые пальцы под контролем.

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

Спасибо!


person Abhijit Sarkar    schedule 12.07.2018    source источник
comment
@JimGarrison На самом деле этот вопрос был бы не по теме CodeReview, поскольку Psuedocode не принимается. CodeReview требует полного рабочего кода с контекстом.   -  person Summer    schedule 12.07.2018
comment
@JimGarrison Поскольку этот вопрос содержит псевдокод и не содержит реального кода, у него нет шансов на Code Review. Не рекомендуйте сайт, если вы хотя бы не прочитали и не поняли его справочный центр.   -  person Mast    schedule 12.07.2018
comment
Похоже, идея dp имеет некоторые недостатки, например, алгоритм сначала начинает заполнять таблицу dp с 1 символом слова, затем 2, затем 3, но я не думаю, что он может проверить случай, когда символ (ы) повторно используются   -  person Pham Trung    schedule 12.07.2018
comment
По сути, то, что он пытается сделать, это для слова w длины k в словаре, если слово существует - заканчивается в позиции (i, j) доски , то существует путь длины k, начинающийся с (i, j), который содержит буквы w в обратном порядке. Хотя я не уверен в правильности его псевдокода, основная идея основана на получении пути длиной k, где все буквы w сопоставляются с соседними узлами. пути.   -  person ichantz    schedule 12.07.2018
comment
В исходной ссылке кто-то уже упоминал benqiang zhuNovember 14, 2016 at 4:41 PM the 3rd method works if it allows using one character repeatedly as long as not continuously. For example, 'dad' was found if 'da' is on the board. 'lee' was not found if 'le' in on the board.   -  person Pham Trung    schedule 12.07.2018
comment
@PhamTrung Назначение не позволяет использовать одну и ту же сетку дважды в слове, как и настоящая игра Boggle. «папа» или «ли» возможно только в том случае, если «d» и «e» были соответственно повторены на досках.   -  person Abhijit Sarkar    schedule 12.07.2018
comment
Как я уже сказал, алгоритм dp не может справиться с этим случаем, это просто неправильно. Я думаю, что владелец блога уже написал некоторый код на C ++, попробуйте протестировать его на этом кейсе.   -  person Pham Trung    schedule 12.07.2018
comment
@PhamTrung Я не жду готового решения или даже правильного, я просто понимаю идею, которую он (смутно) излагает. Если вы поняли, о чем он говорит, не сдерживайтесь, опубликуйте здесь ответ, объясняющий идею. Кто знает, возможно, мы найдем изъян в его рассуждениях и исправим его.   -  person Abhijit Sarkar    schedule 12.07.2018


Ответы (1)


Идея DP (неправильного) решения проста, если предположить, что мы хотим проверить, существует ли слово «яблоко» в таблице.

  • Давайте создадим таблицу dp[k][n][n], где dp[a][x][y] означает, что префикс слова длиной a может заканчиваться на ячейке (x, y).

    [a][p][p]
    [x][x][l]
    [x][x][e]
    

Для приведенной выше таблицы dp[1][0][0] = true, поскольку длина префикса 1 для apple равна a, dp[2][0][1] = true и т. Д.

  • Итак, как проверить, истинно ли dp[a][x][y]? проверить все соседние ячейки (x,y), и если у одного из его соседей есть dp[a - 1][][] = true, значит dp[a][x][y] также истинно. В нашем примере для ячейки (0,2), dp[3][0][2] = true в качестве одного из своих соседей ячейка (0,1) имеет dp[2][0][1] = true
  • По умолчанию все dp[0][x][y] = true
  • Для любой ячейки (x, y), если dp[length of word][x][y] = true -> слово существует в таблице.

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

Например, если нам нужно найти слово apa и с приведенной выше таблицей

dp[1][0][0] = true -> dp[2][0][1] = true -> dp[3][0][0] = true
person Pham Trung    schedule 12.07.2018
comment
Итак, либо нам нужно создать таблицу dp для каждого слова, либо нам нужно знать максимальную длину всех слов из словаря, верно? - person Abhijit Sarkar; 12.07.2018
comment
@AbhijitSarkar, если вы спросите о деталях реализации, это другой вопрос. Используя dp снизу вверх, вы можете полностью повторно использовать один-единственный dp[2][n][n], не влияя на временную сложность. - person Pham Trung; 13.07.2018
comment
@Pham Trung, значит, решение DP здесь не сработает? Поскольку он может рассматривать один и тот же символ ячейки более одного раза. - person tusharRawat; 23.03.2020