Pull to refresh

Comments 22

Из такого способа вычисления номера следует и практический смысл всей затеи. Собственно номера – прикольная штука, но не очень понятно, что с ней дальше делать
Если зная номер, можно «нарисовать» дерево, то вроде полезно. Вроде как покомпактнее (занимает меньше места), чем стандартный способ хранения дерева. Привели бы его для сравнения, там вроде ссылки на другие ноды используются?

Не компактнее, по крайней мере для относительно больших деревьев. Стандартный формат записи деревьев в бионформатике примерно такой: (((А, B), (C, D)), E). Буквы — имена листьев, скобки объединяют соседние узлы. Могут быть ещё всякие приблуды для информации о внутренних узлах, но в простейшем случае так. Для данного дерева размер записи 21 символ, считая пробелы. Это, если я ничего не напутал, №8. Три бита. So far, so good. Но размер записи растёт примерно линейно от числа листьев, а номера во всяком случае не медленнее чисел Каталана, то есть сильно хуже, чем квадратично. На практике полный вектор номеров узлов для дерева после десятка листьев весит сильно больше, чем его запись в стандартной нотации.


К тому же такое хранение будет некорректно. С точки зрения номеров ((A, B), C) = (A, (B,C)) = 3, а с точки зрения эволюционной информации в дереве это могут быть сильно разные штуки. Но это я со своей колокольни, конечно. Если кому-то надо хранить десятки тысяч топологий деревьев размером в десятки листьев, то может быть и выгода в хранении.

Тут двоичные деревья
Их хранят в массивах
Если именно топологию дерева кодировать (без payload в узлах), то достаточно по биту на каждый возможный узел/лист: 2^2^N (Где N — глубина дерева)
Завершающие нули можно отбросить.

Не уверен, что представляю описываемый вами формат хранения. Можете чуть подробнее рассказать или там ссылку кинуть?

Ошибся в расчетах.
Просто в голове засели сбалансированные бинарные деревья
Есть способ хранения бинарных деревьев в массиве:
image
Хранится как:
image
Для отображения только топологии этот массив можно представить в виде бинарного вектора. (1 — есть узел, 0 — нет узла)
Но для разреженных деревьев будет дико неэффективно.

В общем случае у (несбалансированного) дерева тогда будет несколько представлений, верно? Но каждое представление будет соответствовать только одному дереву, так что почему бы и нет. Можно в принципе придумать алгоритм, считающий для произвольной топологии наиболее короткое представление.

Эффективность будет сильно зависеть от сбалансированности дерева, в особенности количества (k, 1)-поддеревьев. Для каждого из них в правой части создаётся всегда столько же нулей, сколько узлов в k, минус 1. Любые (k,j)-поддеревья будут содержать в правой части меньше нулей, чем (k, 1), и тем меньше, чем k ближе к j. Размер представления получается где-то между 2n-1 и 2^n от числа листьев. Это без удаления завершающих нулей и ещё каких-нибудь оптимизаций.
В общем случае у (несбалансированного) дерева тогда будет несколько представлений

Это в смысле деревья:
и

равны?
Или я чего-то не понял?
Я как раз рассмотрел только простые оптимизации — удаление завершающих нулей и первой единицы.
Да, равны. Как и 0-1-2-3-4-5-7-8-11-12-13-14, например. Очевидно, оптимальная запись с точки зрения завершающих нулей вторая в вашем комментарии.

То есть, если я поменяю в корне правого и левого детей местами, то для вас дерево не изменится?

Ну, если мы хотим отбросить информацию о хиральности, то достаточно все деревья сортировать слева направо — это минимизирует запись, да.
Я бы сказал максимально минимизирует — достаточно запомнить номер разряда, где кончаются единицы и начинаются нули.

Но в большинстве случаев насколько я знаю, эта информация имеет значение…

Для большинства приложений (индексация данных, например) имеет. Но применительно к конкретно филогенетическим деревьям даже положение корня не всегда имеет значение, то есть деревья ((A, B), (C, D)) и ((C, (A, B)), D) часто считаются эквивалентными. Посмотрите, например, на КДПВ моего прошлого поста, там корня вообще нету. Зато очень важна информация, содержащаяся в листьях.

Больше похоже, что вы под деревом подразумеваете граф


A     C
 >---<
B     D

И дополнительные промежуточные вершины не должны влиять на эквивалентность таких графов.

Да и нет. В филогенетической практике такой граф называется «неукоренённым деревом» и действительно довольно часто используется. Но внутренних вершин степенью меньше тройки там нет, так что их наличие или отсутствие таки важно.
По-моему, получилась хорошая учебная задачка для студентов-программистов. Тут вам и рекурсия, и деревья, и приложение к реальным проблемам из биологии.

Скажем, на том же Haskell можно сделать совсем коротко.
import Data.Tree

n = Node "Node"

a = n [n [n [n [n [], n []], n []], n []],
       n [n [n [], n []], n [n [], n [n [n [], n []], n []]]]]
b = n [n [n [n [n [], n []], n []], n []],
       n [n [n [], n []], n [n [], n [n [], n []]]]]


num :: Tree t -> Int
num (Node _ [])       = 1
num (Node _ [t1, t2]) = k * (k - 1) `div` 2 + j + 1
    where (k, j)   = if n1 > n2 then (n1, n2) else (n2, n1)
          (n1, n2) = (num t1, num t2)

Как и можно ожидать, 'num a' возвращает 84, 'num b' возвращает 21.
Я что-то не понял — каким образом нумерация деревьев помогает решить задачу их кластеризации? Как будто бы это две совершенно разных задачи, нет?
Для кластеризации вроде как нужно задать метрику между деревьями, то есть определить функцию похожести деревьев, так? На рисунке два похожих дерева, но у одного номер 84, у другого — 21. Ну и как определить расстояние между ними?

А на векторах уже можно определить метрику дистанций (например, евклидову)

Как конкретно метрика определяется, поясните, пожалуйста.
На картинке в левом дереве 3 узла№2, 2 узла №3 и 2 узла №5, а в правом 3 узла№2, 2 узла №3 и 1 узел №5 (и сколько-то других узлов, но смотрим для примера на эти). За счёт этого топологии можно представить в виде векторов `(3, 2, 2)` и `(3, 2, 1)` и между ними уже считать евклидову дистанцию.
Да, спасибо, стало понятнее. Сверткой по номерам поддеревьев получаем вектор дерева. Но отражает ли норма разности таких векторов различие деревьев остаётся под вопросом ввиду нестабильности нумерации. Когда малое изменение дерева (добавление ветки) приводит к большим изменениям номеров веток.
Кажется, что можно найти более адекватные метрики.
На практике вроде как работает. Если никак не нормировать на размер поддерева, большую часть дистанции задаёт количество мелких поддеревьев (в пределах десятка листьев) тупо потому что их больше. Гляньте на последнюю картинку, там как раз наиболее значимые вынесены по бокам. И они как раз отражают интересующую авторов биологическую реальность гораздо больше, чем различия в номере корневого узла или его ближайших окрестностей.
Ну тогда можно было наверное еще проще поступить. В таких деревьях, насколько я понял, все узлы делятся на два типа — конечный и промежуточный (родительский). Это и есть базис для сравнения деревьев. Считаем количество тех и других узлов для каждого дерева и получаем вектор дерева. Возможно, такой метрики было бы достаточно.
Нельзя. Формулировка типа «X листьев, Y внутренних узлов» описывает не уникальное дерево, а огромный класс довольно разных деревьев. Не уверен даже, что для данного X может быть больше одного Y. А вектор номеров внутренних узлов однозначно описывает дерево.
Деревья сами по себе довольно простая структура (в смысле топологии). Почему бы не использовать для их сравнения такой инвариант графа, как его диаметр (максимальное расстояние между вершинами дерева) или чуть более сложный — суммарное значение расстояний?

Значение обоих инвариантов при заданном количестве узлов n известно для двух предельных деревьев — простой разомкнутой цепочки (максимальное) и для графа-звезды (минимальное). Для первого инварианта D(chain) = n-1, D(star) = 2. Для второго (сумма расстояний): Ds(chain) = (n-1)n(n+1)/6, а для звезды: Ds(star) = (n-1)^2.

Все остальные деревья (тут любые деревья, не только бинарные) расположены между этими предельными дистанциями. То есть по значению данных инвариантов можно судить о близости топологии деревьев — к чему ближе дерево: к цепочке (растянутое) или звезде (компактное). Во всяком случае метрика на основе расстояний выглядит прозрачной и обоснованной.
Нельзя по той же причине. Данное расстояние между двумя наиболее удалёнными узлами или сумма длин рёбер характерны для огромного класса очень разных (с биологической точки зрения) деревьев.
Sign up to leave a comment.

Articles