Сериализация графа

Я ищу простой алгоритм для «сериализации» ориентированного графа. В частности, у меня есть набор файлов с взаимозависимостями в порядке их выполнения, и я хочу найти правильный порядок во время компиляции. Я знаю, что это должно быть довольно обычное дело - компиляторы делают это постоянно, - но мой гугл-фу сегодня был слабым. Какой для этого нужно алгоритм?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
44
0
39 729
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Пока это DAG, этот простой обход на основе стека должен быть тривиальным.

Да, вот как ты это делаешь. Это называется поиском в глубину (DFS). И если вы не уверены, что у вас есть DAG, вы должны проверить задние края, иначе цикл отправит вас в бесконечный цикл.

sleske 30.09.2009 19:42

Я придумал довольно наивный рекурсивный алгоритм (псевдокод):

Map<Object, List<Object>> source; // map of each object to its dependency list
List<Object> dest; // destination list

function resolve(a):
    if (dest.contains(a)) return;
    foreach (b in source[a]):
        resolve(b);
    dest.add(a);

foreach (a in source):
    resolve(a);

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

У кого-нибудь есть что-нибудь получше?

вместо foreach используйте while, поддерживайте два указателя, просматривающих данные a: ведущий, который выполняет двойные шаги, а конечный, который выполняет одиночные шаги. Ведущий указатель обрабатывает фактические разрешения, и если он когда-либо переходит конечный указатель, возникает цикл.

Tenderdude 19.01.2017 20:11
Ответ принят как подходящий

Топологическая сортировка (из Википедии):

In graph theory, a topological sort or topological ordering of a directed acyclic graph (DAG) is a linear ordering of its nodes in which each node comes before all nodes to which it has outbound edges. Every DAG has one or more topological sorts.

Псевдокод:

L ← Empty list where we put the sorted elements
Q ← Set of all nodes with no incoming edges
while Q is non-empty do
    remove a node n from Q
    insert n into L
    for each node m with an edge e from n to m do
        remove edge e from the graph
        if m has no other incoming edges then
            insert m into Q
if graph has edges then
    output error message (graph has a cycle)
else 
    output message (proposed topologically sorted order: L)

Эх ... скопировал прямо с википедии?

Benjol 06.10.2008 11:00

Спасибо. Помог мне сопоставить тот факт, что дерево зависимостей можно отсортировать с помощью этого метода. :-)

Shamasis Bhattacharya 09.12.2013 15:40

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

Да, топологическая сортировка невозможна, если граф содержит циклы. Это соответствует реальному миру: если я попрошу вас сделать A перед B, и B перед A, вы не сможете меня удовлетворить ;-).

sleske 30.09.2009 18:41

Другие вопросы по теме