QuickGraph - there is an algorithm for finding all parents (down to the root vertices) of the vertex set

In QuickGraph - there is an algorithm for finding all the parents (up to the root vertices) of the vertex set. In other words, the entire vertex that is located somewhere below them (along the path to the leaf nodes) introduces one or more vertices. Therefore, if the vertices were nodes and the edges were relationship-dependent, find all the nodes that will be affected by this set of nodes.

If it’s not so difficult to write one own algorithm?

+3
source share
3 answers

Here is what I used to search for a predecessor at a given vertex:

IBidirectionalGraph<int, IEdge<int>> CreateGraph(int vertexCount)
{
    BidirectionalGraph<int, IEdge<int>> graph = new BidirectionalGraph<int, IEdge<int>>(true);
    for (int i = 0; i < vertexCount; i++)
        graph.AddVertex(i);

    for (int i = 1; i < vertexCount; i++)
        graph.AddEdge(new Edge<int>(i - 1, i));

    return graph;
}

static public void Main()
{
    IBidirectionalGraph<int, IEdge<int>> graph = CreateGraph(5);

    var dfs = new DepthFirstSearchAlgorithm<int, IEdge<int>>(graph);            
    var observer = new VertexPredecessorRecorderObserver<int, IEdge<int>>();

    using (observer.Attach(dfs)) // attach, detach to dfs events
        dfs.Compute();

    int vertexToFind = 3;
    IEnumerable<IEdge<int>> edges;
    if (observer.TryGetPath(vertexToFind, out edges))
    {
        Console.WriteLine("To get to vertex '" + vertexToFind + "', take the following edges:");
        foreach (IEdge<int> edge in edges)
            Console.WriteLine(edge.Source + " -> " + edge.Target);
    }
}

, , dfs.Compute() (.. dfs.Compute(0)).

-Doug

+1

, , . , .

, , :

    public IEnumerable<T> GetParents(T vertexToFind)
    {
        IEnumerable<T> parents = null;

        if (this.graph.Edges != null)
        {
            parents = this.graph
                .Edges
                .Where(x => x.Target.Equals(vertexToFind))
                .Select(x => x.Source);
        }

        return parents;
    }
+1

You either need to maintain a reverse graph, or create a wrapper over a graph that reverses all edges. QuickGraph has a ReversedBidirectionalGraph class, which is a wrapper designed just for that, but it doesn't seem to work with algorithm classes due to generic type incompatibility. I had to create my own wrapper class:

class ReversedBidirectionalGraphWrapper<TVertex, TEdge> : IVertexListGraph<TVertex, TEdge> where TEdge : IEdge<TVertex> 
{
  private BidirectionalGraph<TVertex, TEdge> _originalGraph;
  public IEnumerable<TEdge> OutEdges(TVertex v)
    {
        foreach (var e in _graph.InEdges(v))
        {
            yield return (TEdge)Convert.ChangeType(new Edge<TVertex>(e.Target, e.Source), typeof(TEdge));
        }
    } //...implement the rest of the interface members using the same trick
}

Then run DFS or BFS on this wrapper:

var w = new ReversedBidirectionalGraphWrapper<int, Edge<int>>(graph);    
var result = new List<int>();    
var alg = new DepthFirstSearchAlgorithm<int, Edge<int>>(w);
alg.TreeEdge += e => result.Add(e.Target);    
alg.Compute(node);

Doug's answer is incorrect, because DFS will only visit the underlying subgraph. The previous observer does not help.

0
source

Source: https://habr.com/ru/post/1742932/


All Articles