Как преобразовать направленный ациклический граф (DAG) в дерево

Я искал примеры C# для преобразования DAG в дерево.

есть ли у кого-нибудь примеры или указатели в правильном направлении?

Обновление Разъяснить

У меня есть график, содержащий список модулей, которые требуется загрузить моему приложению. Каждый модуль имеет список модулей, от которых он зависит. Например, вот мои модули, A, B C, D и E

  • A не имеет зависимостей
  • B зависит от A, C и E
  • C зависит от A
  • D зависит от конструкции
  • E зависит от C и A

Я хочу разрешить зависимости и создать дерево, которое выглядит так...

--A

--+--B

-----+--C

---------+--D

--+--E

Топологическая Сортировка

Спасибо за информацию, если я выполню топологическую сортировку и отменю вывод у меня будет следующий порядок

  • A
  • B
  • C
  • D
  • E

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

спасибо

Рогань

5 ответов


есть теоретический ответ графа и ответ программиста на это. Полагаю, вы сами справитесь с программистами. Для теоретико-графического ответа:

  • A DAG-это набор модулей, где никогда не случается, что A нуждается в B, и в то же время B (или один из модулей B нуждается) нуждается в A, в модулях-говорят: нет круговой зависимости. Я видел циклические зависимости (поиск примеров на форумах Gentoo), поэтому вы даже не можете быть на 100% уверены, что у вас есть DAG, но давайте предположим, что да. Это не очень сложно сделать проверку циклических зависимостей, поэтому я бы рекомендовал вам сделать это где-нибудь в вашем загрузчике модулей.
  • в дереве то, что никогда не может произойти, это то, что A зависит от B и C и что B и C зависят от D (алмаз), но это может произойти в DAG.
  • кроме того, дерево имеет ровно один корневой узел, но DAG может иметь несколько "корневых" узлов (т. е. модулей, от которых ничего не зависит). Например, такая программа, как GIMP, GIMP программа будет корневым узлом набора модулей, но для GENTOO почти любая программа с GUI является "корневым" узлом, а библиотеки и т. д.-их зависимостями. (Т. е. Оба Konqueror и Kmail зависят от Qtlib, но ничего не зависит от Konqueror, и ничего не зависит от Kmail)

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

однако, (программисты высокого уровня ответ) Если вам нужно дерево для графических представлений, вас интересуют только зависимости определенного модуля, а не то, что зависит от этого модуля. Приведу пример:--3-->

A depends on B and C
B depends on D and E
C depends on D and F

Я не могу показать это как дерево ASCII-art по той простой причине, что это не может быть преобразовано в дерево. Однако, если вы хотите показать, от чего зависит A, вы можете показать это:

A
+--B
|  +--D
|  +--E
+--C
   +--D
   +--F

Как вы видите, вы получаете двойные записи в своем дереве - в этом случае" только " D, но если вы это сделаете "развернуть все" на дереве Gentoo, я Гарантирую Вам, что ваше дерево будет иметь по крайней мере в 1000 раз больше узлов, поскольку есть модули. (есть по крайней мере 100 пакетов, которые зависят от Qt, поэтому все, от чего зависит Qt, будет присутствовать по крайней мере 100 раз в дереве).

Если у вас есть" большое "или" сложное " дерево, лучше всего развернуть дерево динамически, а не заранее, иначе у вас может быть очень интенсивный процесс памяти.

недостаток дерева выше является то, что при нажатии кнопки Открыть B, затем D, вы видите, что A и B зависят от D, но не также, что c зависит от D. Однако, в зависимости от ситуации, это может быть важно - если вы поддерживаете список загруженных модулей, при загрузке С вы видите, что вы загрузили уже, и не важно, что оно не заряжено для C, но для Б. Это загружается, что все, что имеет значение. Если вы динамически поддерживаете то, что напрямую зависит от определенного модуля, вы можете обрабатывать противоположную проблему (выгрузку) как что ж.

удачи!


DAG и дерево не одно и то же математически. Таким образом, любое преобразование вносит двусмысленность. Дерево по определению не имеет циклов периода.


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

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


Это зависит от того, как вы представляете свой DAG. Например, это может быть матрица смежности (a[i, j] = 1, Если есть ребро от узла i до узла j, иначе 0), или как система указателей, или как массив узлов и массив ребер....

далее, неясно, какое преобразование вы пытаетесь применить. Подключенный DAG is дерево, поэтому, боюсь, вам нужно немного прояснить свой вопрос.


вы можете сделать это, только если все поддеревья имеют один корневой узел.