Недавно я приобрел Inferring Phylogenies Джозефом Фелсенштейном, который представляет собой отличную книгу о математических и вычислительных методах для вывода филогенетических деревьев и играл с реализацией некоторых алгоритмов, которые он описывает.«переизбыточная» чисто функциональная структура данных дерева
В частности, я заинтересован в том, чтобы использовать это в функциональной настройке с постоянными структурами данных, так как многие методы включают в себя прохождение через пространство возможных деревьев, и было бы неплохо дешево запомнить историю того, (по сравнению с «мирами» в this blog post), легко кэшировать ранее вычисленные значения для поддеревьев и т. д.
Проблема заключается в том, что многие методы включают в себя «переучивание» деревьев, который я не могу понять, как делать дешево чисто функциональным способом. В основном я нужен способ захвата идеи, что каждый из следующих (с использованием Clojure обозначений, представляющие дерева как векторы):
[:a [:b [:c :d]]]
[:b [:a [:c :d]]]
[:a [:b [:d :c]]]
[:b [:a [:d :c]]]
[[:a :b] [:c :d]]
[[:c :d] [:a :b]]
[:c [:d [:a :b]]]
[:d [:c [:a :b]]]
[:c [:d [:b :a]]]
[:d [:c [:b :a]]]
представляют одни и те же данные, и отличаются только где корень помещается; каждый из них представляет некорневое дерево:
a b
\/
|
/\
c d
Я хотел бы иметь возможность перемещаться в одну из этих дерев с застежкой-молнией, а затем вызвать функцию reroot
, которая будет возвращать новое дерево, который застегнул в таком что корень находится в текущем loc
.
В книге Felsenstein описывает структуру данных для дешевки rerootable дерева, которое выглядит примерно следующая поспешно сделали диаграмму
, в которых круги являются структурами, а стрелки являются указателями. Кольца структур являются внутренними узлами на дереве, и как только у нас есть ссылка на один, мы можем переместить его туда, выполнив некоторую замену указателя. К сожалению, это мутирующая операция и требует взаимных ссылок, обе из которых невозможны в чисто функциональной настройке.
Я чувствую, что должен быть способ сделать то, что я хочу, используя молнии, но я играл с clojure.core/zip
на некоторое время и никуда не уходил.
Кто-нибудь знает о реализации чего-то подобного или имеет предложения по вещам, которые я должен прочитать/документы, которые я должен посмотреть/идеи о том, как это сделать?
Спасибо!
Структура проще (и быстрее) адаптироваться, если вы используете наборы, а не векторы/списки для коллекции соседних узлов. – Thumbnail