Кодирование ориентированного графа в виде чисел

Допустим, у меня есть ориентированный граф с одним корнем и без циклов. Я хотел бы добавить тип для каждого узла (например, как целое число с некоторым настраиваемым порядком) со следующим свойством:

if Node1.type <= Node2.type then there exists a path from Node1 to Node2

Обратите внимание, что топологическая сортировка на самом деле удовлетворяет обратному свойству:

if there exists a path from Node1 to Node2 then Node1.type <= Node2.type

поэтому его нельзя использовать здесь.

Теперь обратите внимание, что здесь нельзя использовать целые числа с естественным порядком, потому что можно сравнивать каждые 2 целых числа, то есть порядок целых чисел является линейным, а дерево не обязательно таким.

Вот пример. Предположим, что граф имеет 4 узла A, B, C, D и 4 стрелки:

A->B, A->C, B->D, C->D

Так это бриллиант. Теперь мы можем положить

A.type = 00
B.type = 01
C.type = 10
D.type = 11

где справа у нас есть целые числа в двоичном формате. Сравнение определяется побитово:

(X <= Y) if and only if (n-th bit of X <= n-th bit of Y for all n)

Итак, я предполагаю, что такой порядок можно использовать, вопрос в том, как построить значения из данного графика? Я даже не уверен, всегда ли существует решение. Любые подсказки?

ОБНОВЛЕНИЕ: Поскольку есть некоторое недопонимание терминологии, которую я использую, позвольте мне быть более подробным: меня интересует ориентированный ациклический граф, в котором есть ровно один узел без предшественников (он же корень) и есть не более одной стрелки между любыми двумя узлами. Примером может служить алмаз. Он не должен иметь один лист (т. е. узел без потомков). Каждый узел может иметь несколько предшественников и несколько преемников. Можно сказать, что это частично упорядоченный набор с наименьшим элементом (т. е. уникальным глобально минимальным элементом).


person freakish    schedule 14.06.2016    source источник
comment
Если Node1.type <= Node2.type никогда не выполняется, то требование тривиально выполняется.   -  person n. 1.8e9-where's-my-share m.    schedule 14.06.2016
comment
@н.м. Я не уверен, что понял, не хочешь уточнить?   -  person freakish    schedule 14.06.2016
comment
Если a < b then there's a path from a to b. Если a < b ложно, то все утверждение истинно.   -  person n. 1.8e9-where's-my-share m.    schedule 14.06.2016
comment
Подождите, у вас есть дерево или DAG?   -  person n. 1.8e9-where's-my-share m.    schedule 14.06.2016
comment
@н.м. Похоже на DAG, а не на дерево. Я думаю, он имел в виду древовидный ориентированный граф, который действительно является DAG.   -  person Patrice Gahide    schedule 14.06.2016
comment
@н.м. then the whole statement is true Вы имеете в виду, что вы не можете определить, существует ли путь, если !a<b? Я это понимаю. Было бы идеально иметь отношения if and only if, но мне это не нужно.   -  person freakish    schedule 14.06.2016
comment
@н.м. В чем разница между DAG и деревом?   -  person freakish    schedule 14.06.2016
comment
en.wikipedia.org/wiki/Tree_(graph_theory) en.wikipedia.org/wiki/Directed_acyclic_graph   -  person n. 1.8e9-where's-my-share m.    schedule 14.06.2016
comment
@н.м. Так разница в том, что дерево не направлено? Тогда меня интересует DAG.   -  person freakish    schedule 14.06.2016
comment
Нет, разница не в том, что дерево ненаправленное — дерево может быть направленным или нет, а неориентированное дерево всегда можно сделать (или считать) направленным, выбрав произвольную корневую вершину и направив все ребра от нее. Разница в том, что в ориентированном дереве каждая вершина, кроме корня, имеет ровно одно входящее ребро, тогда как вершина в DAG может иметь произвольное количество входящих ребер.   -  person j_random_hacker    schedule 14.06.2016
comment
@j_random_hacker Хорошо, поэтому терминология, которую я использую, может быть не на 100% правильной, но меня интересует ориентированный ациклический граф, в котором между любыми двумя узлами находится не более 1 стрелки и существует ровно один узел без предшественников. Я обновлю вопрос.   -  person freakish    schedule 14.06.2016


Ответы (3)


Для любой DAG вы можете определить x <= y как "есть путь от x до y". Это отношение является частичным порядком. Я полагаю, что вопрос заключается в том, как эффективно представить это отношение.

Для каждой вершины X определите ¡X как множество вершин, достижимых из X (включая само X). Два утверждения

  • ¡X является подмножеством ¡Y
  • X достижим из Y

эквивалентны.

Закодируйте эти наборы как наборы битов (N-битные двоичные числа), и все готово.

person n. 1.8e9-where's-my-share m.    schedule 14.06.2016
comment
Я на самом деле удивлен, насколько это просто. Два эквивалентных утверждения были тем, чего я не видел. Спасибо! - person freakish; 14.06.2016

Вы называете отношение <=, но оно обязательно не полное (то есть: может быть, что для данной пары a и b ни a <= b, ни b <= a).

Вот одна из идей, как это определить.

Если ваши узлы пронумерованы 0, 1..., N-1, вы можете определить type следующим образом:

type(i) = (1 << i) + sum(1 << (N + j), for j such that Path(i, j))

И определите <= следующим образом:

type1 <= type2 if (type1 >> N) & type2 != 0

То есть type(i) кодирует значение i в младших N битах, а набор всех достижимых узлов - в старших N битах. Отношение <= ищет целевой узел в закодированном наборе достижимых узлов.

Это определение работает независимо от того, есть ли в графе циклы, и фактически просто кодирует произвольное отношение в вашем наборе узлов.

Вы можете сделать определение немного более эффективным, используя ceil(log2(N)) бит для кодирования номера узла (всего N + ceil(log2(N)) бит на type).

person Paul Hankin    schedule 14.06.2016
comment
:это обязательно не переходный Почему? Если есть путь из А в В и путь из В в С, то есть путь из А в С. - person n. 1.8e9-where's-my-share m.; 14.06.2016
comment
@н.м. Это означает, что отношение there exists a path транзитивно. Не отношение <=. Теоретически возможно, что <= не является транзитивным, даже если оно отображается в транзитивное отношение. Обратите внимание, что я не требую, чтобы <= сохранялось, если путь существует. Требовать от <= транзитивности было бы неплохо, но я не думаю, что это необходимо для моих целей. - person freakish; 14.06.2016
comment
О, да, это транзитивно. Но это не завершено. Я отредактирую ответ. - person Paul Hankin; 14.06.2016
comment
@PaulHankin На самом деле это свойство известно как совокупность. Для <= не требуется, чтобы он был частичным порядком. Мне нравится ваша идея, скоро попробую. - person freakish; 14.06.2016
comment
Итак, хотя это интересный подход, мне довольно сложно понять, что здесь происходит. Но спасибо за идею. - person freakish; 14.06.2016

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

Существующие ответы работают для общих отношений на общих ориентированных графах, что увеличивает размеры их представления до O (n) бит для n вершин. Поскольку у вас есть дерево, возможно более короткое представление O (log n) бит.

В дереве, направленном от корня, для любых двух вершин u и v множества листьев L(u) и L(v), достижимых из u и v соответственно, должны быть либо непересекающимися, либо одна из них должна быть подмножеством другой. Если они не пересекаются, то u недостижимо из v (и наоборот); если одно является собственным подмножеством другого, то то, что имеет меньший набор, достижимо из другого (и в этом случае то, у которого меньшее множество, обязательно будет иметь строго большую глубину). Если L(u) = L(v), то u достижимо из v тогда и только тогда, когда глубина (v) ‹ глубина (u), где глубина (u) — количество ребер на пути от корня к u. (В частности, если L(u) = L(v) и depth(u) = depth(v), то u = v.)

Мы можем кратко закодировать это отношение, заметив, что все листья, достижимые из данной вершины v, занимают непрерывный сегмент листьев, полученных при неупорядоченном обходе дерева. Таким образом, для любой заданной вершины v этот набор листьев может быть представлен парой целых чисел (first, last), где first идентифицирует первый лист (в порядке обхода), а last - последний. Тогда проверка существования пути от i к j очень проста — на псевдо-C++:

bool doesPathExist(int i, int j) {
    return x[i].first <= x[j].first && x[i].last >= x[j].last && depth[i] <= depth[j];
}

Обратите внимание, что если у каждой нелистовой вершины в дереве есть как минимум 2 дочерних вершины, то вам не нужно заморачиваться с глубинами, так как L(u) = L(v) подразумевает, что в этом случае u = v. (В моей исходной версии поста было сделано это предположение; теперь я исправил его, чтобы он работал, даже если это не так.)

person j_random_hacker    schedule 14.06.2016
comment
должно быть либо непересекающимся, либо одно должно быть подмножеством другого: это неверно в DAG. В частности, узел может иметь два входящих ребра, исходящих из разных поддеревьев. Пример алмаза, приведенный OP, является примером этого случая. - person Patrice Gahide; 14.06.2016
comment
@PatriceGahide: Первая строка вопроса ОП: допустим, у меня есть ориентированный граф, фактически дерево - person j_random_hacker; 14.06.2016
comment
Смотрите комментарии ОП. Мы имеем дело с DAG. - person Patrice Gahide; 14.06.2016
comment
@PatriceGahide: комментарии ОП указывают на то, что он/она очень запутался в том, с чем он/она имеет дело. - person j_random_hacker; 14.06.2016
comment
Возможно, но образец экземпляра (алмаз) ясно дает понять, что вы не можете предположить то, что я указал в своем первоначальном комментарии. - person Patrice Gahide; 14.06.2016
comment
@PatriceGahide: Вы правы, я работал над более ранней версией, в которой не было этого примера. Я добавлю предупреждение... и понизлю этот вопрос :( - person j_random_hacker; 14.06.2016
comment
@j_random_hacker Меня не смущает то, с чем я имею дело. В лучшем случае я могу не знать правильную терминологию, однако примера, который я привел, должно быть достаточно. Поэтому, если это решение не работает в алмазном случае, я не могу его использовать. - person freakish; 14.06.2016
comment
@freakish: Вы отредактировали свой вопрос, но он все еще содержит Допустим, у меня есть ориентированный граф, на самом деле дерево наверху - предложение, которое заставило меня тратить время на ответ, который не решает вашу проблему. . Пожалуйста удалите это. - person j_random_hacker; 14.06.2016
comment
@j_random_hacker Чувак, я не собираюсь ничего удалять. Теперь вопрос должен быть совершенно ясен. Мне жаль, что вы меня неправильно поняли. Но я уверяю вас, что я потратил много времени и на SO. Не придавай этому большого значения, серьезно. Кроме того, ваш ответ может быть полезен для некоторых других людей. - person freakish; 14.06.2016