Это моя первая попытка использовать (то, что я понимаю) динамическое программирование. Я пытаюсь решить эту интересную проблему: A* Admissible Heuristic for die rolling on gridПамять динамического программирования в Haskell
q
функции пытается рекурсия в обратном направлении, отслеживание ориентации матрицы (visited
технически следующая ячейка, но «посетил» с точки зрения рекурсии для предотвращения бесконечные петли назад и вперед). Хотя я не уверен, что ответ, который он предоставляет, является лучшим решением, тем не менее, он, похоже, дает ответ.
Я надеюсь, что идеи о том, как реализовать какое-то запоминание, чтобы ускорить его - я безуспешно пытался реализовать что-то вроде memoized_fib
(видело here) с lookup
вместо !!
, отображения q
к списку сочетаний (i,j)
но получил Nothing
, а не каламбур.
Haskell код:
import Data.List (minimumBy)
import Data.Ord (comparing)
fst3 (a,b,c) = a
rollDie [email protected][left,right,top,bottom,front,back] move
| move == "U" = [left,right,front,back,bottom,top]
| move == "D" = [left,right,back,front,top,bottom]
| move == "L" = [top,bottom,right,left,front,back]
| move == "R" = [bottom,top,left,right,front,back]
dieTop die = die!!2
leftBorder = max 0 (min startColumn endColumn - 1)
rightBorder = min columns (max startColumn endColumn + 1)
topBorder = endRow
bottomBorder = startRow
infinity = 6*rows*columns
rows = 10
columns = 10
startRow = 1
startColumn = 1
endRow = 6
endColumn = 6
dieStartingOrientation = [4,3,1,6,2,5] --left,right,top,bottom,front,back
q i j visited
| i < bottomBorder || i > topBorder
|| j < leftBorder || j > rightBorder = (infinity,[1..6],[])
| i == startRow && j == startColumn = (dieTop dieStartingOrientation,dieStartingOrientation,[])
| otherwise = (pathCost + dieTop newDieState,newDieState,move:moves)
where previous
| visited == (i, j-1) = zip [q i (j+1) (i,j),q (i-1) j (i,j)] ["L","U"]
| visited == (i, j+1) = zip [q i (j-1) (i,j),q (i-1) j (i,j)] ["R","U"]
| otherwise = zip [q i (j-1) (i,j),q i (j+1) (i,j),q (i-1) j (i,j)] ["R","L","U"]
((pathCost,dieState,moves),move) = minimumBy (comparing (fst3 . fst)) previous
newDieState = rollDie dieState move
main = putStrLn (show $ q endRow endColumn (endRow,endColumn))
Я думаю, что это поможет, если вы вывесили вашу попытку, что не работает. – svick
Я долгое время стучал головой о проблему воспоминания в Haskell некоторое время назад. Я не помню подробностей, но в конце концов мне это удалось (я думаю, у меня могли возникнуть другие проблемы, такие как утечки пространства) путем определения экземпляра массива, чтобы значение для любого заданного индекса вычислялось в терминах других элементов массива. Тогда ленивая оценка заставляла все элементы массива «заполняться» в правильном порядке, что казалось немного волшебным (хотя я был более рад, чем доволен). IOW структура данных «ведет», функция «следует». –
@j_random_hacker, пожалуйста, ознакомьтесь с применяемым алгоритмом кубиков - 300x300 за 2.13 секунды без таблиц и меньшей суммой, чем у Павла A *, круто или что? http://stackoverflow.com/questions/16547724/a-admissible-heuristic-for-die-rolling-on-grid/16629766#16629766 –