Created
January 26, 2014 21:21
-
-
Save qnikst/8639653 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
У меня возникла следующая задача, не по работе, | |
а обучения ради, в результате которой возник | |
вопрос, а как правильно писать tying the knot | |
алгоритмы. (Сама задача решена, теперь остаётся вопрос как это сделать красиво) | |
Задача: | |
Полная задача это подсчёт очков в го, но она | |
разбита на подзадачи. | |
Текущая задача: Дана сетка в R^n, в узлах сетки или | |
стенка или пустое место, нужно на каждом пустом | |
месте поставить множество (Set) значений, куда | |
можно добраться из этой точки. | |
След задача, в дополнение к множеству записывать значение вычисленное на значений на границах. | |
Решить задачу хочется функционально, т.к. понятно, | |
что существует куча всем известных императивных | |
алгоритмов. | |
При решении этой задачи я столкнулся со следующей | |
проблемой (для простоты рассмотрим 1D), хочется | |
научить хацкель решать системы следующего вида: | |
a = 1 U b | |
b = 2 U a U c | |
c = 3 U b | |
Решение тут очевидное a = b = c = {1,2,3}, | |
но для хацкеля это цикл т.к. a = 1U2Ua... | |
Сразу же возникает идея разбить цикл, это | |
возможно если каждому множеству сопоставить | |
индекс, т.е.: | |
(a' = [1,b'], a = fromList $ concatMap (f [1]) a') | |
(b' = [2,a',c'], b = fromList $ concatMap (f [2] b') | |
Где f рекурсивно проходит выражения отфильтровывая | |
лишние элементы (переданные в параметре) | |
Но у этого решения достаточно высокая цена, для каждой | |
точки мы проводим вычисления заново т.е. заодно и тратится лишняя память, этого можно избежать двумя способами | |
1). Руками заменять b = concatMap.. на b=a, но это работает только для одномерных структур а так же для более сложных выражений | |
2). Делать таблицу кешей, но это тоже не идеальный вариант. | |
Другой вариант это использовать комбинатом неподвижной точки: | |
fa = fix (\f s -> | |
let s' = 1 U fb s | |
in if s == s' then s' else f s') | |
a = fa S.empty | |
Тут (если это сработает) мы вычисляем сразу все выражения, что является большим плюсом. | |
А как вообще обычно решают такие задачи? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
я хотел примерно такое: