Пройдите вверх по ориентированному графику в c# (DAG)

#c# #recursion #directed-acyclic-graphs

Вопрос:

У меня есть простой график без циклов/с несколькими ребрами.

Он всегда направлен вниз.

введите описание изображения здесь

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

 class Edge
{
   public string FromNodeId {get; set;}
   public string ToNodeId{get; set;}
}

class Node
{
   public int Id {get; set;}
   public string Name {get; set;}
}
 

Мне нужно пройти вверх по графику из-за определенной бизнес-логики.

  1. Как называется алгоритм, когда мне нужно рекурсивно посетить каждый узел?
  2. Что может быть отправной точкой для рекурсивного перебора списка ребер вверх по графику?

Ответ №1:

вот метод просмотра графика снизу вверх.

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

             class Edge
            {
                public int FromNodeId { get; set; }
                public int ToNodeId { get; set; }
            }
            class Node // nodes from 0 or 1 to infinit
            {
                public int Id { get; set; }
                public string Name { get; set; }
            }

            void fromBottom(List<Edge> Edges,List<Node> Nodes, Node current)  
            {
                var willVisit = Edges.Where(x => x.ToNodeId == current.Id).ToList();
                if (willVisit.FirstOrDefault()==null)
                {
                    // do your stuff for the last node
                }
                else
                {
                    foreach(var nd in willVisit)
                    {
                        fromBottom(Edges, Nodes,Nodes.Where(x=>x.Id==nd.FromNodeId).First());
                    }
                }
            }
 

вот метод просмотра графика сверху вниз.

             void fromTop(List<Edge> Edges,List<Node> Nodes, Node current)  
            {
                var willVisit = Edges.Where(x => x.FromNodeId == current.Id).ToList();
                if (willVisit.FirstOrDefault()==null)
                {
                    // do your stuff for the last node 
                }
                else
                {
                    foreach(var nd in willVisit)
                    {
                        fromTop(Edges, Nodes,Nodes.Where(x=>x.Id==nd.ToNodeId).First());
                    }
                }
            }
 

примечание.чтобы избежать многократного посещения узла, вы можете добавить логическую переменную в свою структуру для проверки посещения и проверить ее позже в цикле foreach.

Комментарии:

1. Привет, Амин, спасибо за помощь. Код работает таким образом, что график проходит только по одному возможному пути, например: R, Q, M, L, G,E,B,A,но код не перебирает все возможные пути из R,Q,N,L или R,Q,O,L или R, Q, P, L .

2. Я не уверен, что мой комментарий выше верен. Я все еще отлаживаю большой график, и это занимает целую вечность, может быть, за 10 минут я посещаю те, которые указаны выше 3 возможных путей (rofl). Имеет ли это какое-то отношение к вашей ЗАМЕТКЕ о посещении узла несколько раз? В режиме отладки я также могу продолжить отладку после этого обхода, но процесс никогда не возвращается в мою visual studio… которая занята процессором на 18% .

3. Возможно, лучший намек на то, что должно сработать: от узла L я иду налево к J, но он также должен работать, чтобы подняться до узлов G и H.

4. здравствуйте, для посещения узла несколько раз я не добавил условие для него, и для пропуска посещения всеми возможными способами это невозможно, потому что внутри цикла для каждого у вас есть все узлы, у которых есть «fromNodeId», поэтому невозможно пропустить некоторые узлы

5. thx работал, мой vs2019 был каким-то образом сломан…