/// <summary>
        /// Initializes a new <see cref="ConnectedSubgraph"/> instance with the specified main
        /// vertex.
        /// </summary>
        /// <param name="mainVertex">The main vertex of the connected subgraph.</param>
        /// <remarks>
        /// <para>The main vertex of a connected subgraph is used to identify all other vertices in
        /// it and is the only vertex that is certain to remain in the connected subgraph when
        /// edges are removed.</para>
        /// </remarks>
        public ConnectedSubgraph(Vertex mainVertex)
        {
            _mainVertex = mainVertex;
            _connectedVertices = new HashSet<Vertex> { _mainVertex };
            _weaklyConnectedSubgraphs = new Dictionary<Vertex, WeaklyConnectedSubgraph>
            {
                // The main vertex of the connected subgraph belongs to its strongly connected
                // portion by definition
                { _mainVertex, null },
            };

            AddOtherConnectedVertices(_mainVertex);
        }
 /// <summary>
 /// Adds a vertex to the list of vertices in the weakly connected portion of the connected
 /// subgraph.
 /// </summary>
 /// <param name="vertex">The vertex which should be added to the list of vertices.</param>
 public void AddConnectedVertex(Vertex vertex)
 {
     _connectedVertices.Add(vertex);
 }
 /// <summary>
 /// Initializes a new <see cref="WeaklyConnectedSubgraph"/> instance with the specified
 /// anshor vertex.
 /// </summary>
 /// <param name="anchorVertex">The anchor vertex of the weakly connected portion of the
 /// connected subgraph.</param>
 /// <remarks>
 /// <para>The anchor vertex is the only vertex from the strongly connected portion of the
 /// connected subgraph which connects it to the weakly connected portion.</para>
 /// </remarks>
 public WeaklyConnectedSubgraph(Vertex anchorVertex)
 {
     _anchorVertex = anchorVertex;
     _connectedVertices = new HashSet<Vertex>();
 }
 /// <summary>
 /// Checks if a vertex belongs to the weakly connected portion of the connected subgraph.
 /// </summary>
 /// <param name="vertex">The vertex which should be checked.</param>
 /// <returns><see langword="true"/> if the vertex belongs to the weakly connected portion
 /// of the connected subgraph.
 /// </returns>
 public bool ContainsVertex(Vertex vertex)
 {
     return _connectedVertices.Contains(vertex);
 }
        /// <summary>
        /// Adjusts the weakly connected portions of the connected subgraph which two vertices
        /// might belong to immediately after adding an edge between them, possibly reintegrating
        /// them back into the strongly connected portion of the connected subgraph.
        /// </summary>
        /// <param name="vertex1">The first vertex which might belong to a weakly connected portion
        /// of the connected subgraph.</param>
        /// <param name="vertex2">The second vertex which might belong to a weakly connected
        /// portion of the connected subgraph.</param>
        private void AdjustWeaklyConnectedSubgraphs(Vertex vertex1, Vertex vertex2)
        {
            WeaklyConnectedSubgraph weaklyConnectedSubgraph1 = _weaklyConnectedSubgraphs[vertex1];
            WeaklyConnectedSubgraph weaklyConnectedSubgraph2 = _weaklyConnectedSubgraphs[vertex2];

            // If both vertices belong to the same weakly connected portion of the connected
            // subgraph or to the strongly connected portion of the connected subgraph nothing
            // needs to be recalculated
            if (weaklyConnectedSubgraph1 == weaklyConnectedSubgraph2)
                return;

            if (weaklyConnectedSubgraph1 == null)
            {
                // If the first vertex belongs to the strongly connected portion of the connected
                // subgraph and the second vertex belongs to a weakly connected portion, only
                // integrate the weakly connected portion back into the strongly connected portion
                // if the first vertex is the main vertex of the connected subgraph or differs from
                // the anchor vertex of the weakly connected portion
                if (vertex1 == _mainVertex || vertex1 != weaklyConnectedSubgraph2.AnchorVertex)
                    IntegrateWeaklyConnectedSubgraph(weaklyConnectedSubgraph2);
            }
            else if (weaklyConnectedSubgraph2 == null)
            {
                // If the second vertex belongs to the strongly connected portion of the connected
                // subgraph and the first vertex belongs to a weakly connected portion, only
                // integrate the weakly connected portion back into the strongly connected portion
                // if the second vertex is the main vertex of the connected subgraph or differs
                // from the anchor vertex of the weakly connected portion
                if (vertex2 == _mainVertex || vertex1 != weaklyConnectedSubgraph1.AnchorVertex)
                    IntegrateWeaklyConnectedSubgraph(weaklyConnectedSubgraph1);
            }
            else
            {
                // If both vertices belong to different weakly connected portions of the connected
                // subgraph, integrate both of them back into the strongly connected portion
                IntegrateWeaklyConnectedSubgraph(weaklyConnectedSubgraph1);
                IntegrateWeaklyConnectedSubgraph(weaklyConnectedSubgraph2);
            }
        }
        /// <summary>
        /// Adds a vertex to the list of vertices in the connected subgraph and then recursively
        /// adds all vertices directly connected to it. The vertex is added to the list because it
        /// is directly connected to a base vertex which is already in the list of vertices.
        /// </summary>
        /// <param name="vertex">The vertex which should be added to the list of vertices.</param>
        /// <param name="baseVertex">The base vertex which the specified vertex is directly
        /// connected to.</param>
        /// <remarks>
        /// <para>If the specified vertex is not yet in the list of vertices, it is be added to a
        /// suitable weakly connected portion of the connected subgraph.</para>
        /// <para>If the specified vertex is already in the list of vertices, the method checks if
        /// they belong to one or two weakly connected portions of the connected subgraph and
        /// integrates them back into the strongly connected portion of the connected subgraph, if
        /// eligible.</para>
        /// </remarks>
        private void AddConnectedVertex(Vertex vertex, Vertex baseVertex)
        {
            if (_connectedVertices.Contains(vertex))
            {
                if (!IsVertexStronglyConnected(vertex))
                    AdjustWeaklyConnectedSubgraphs(vertex, baseVertex);
                else if (!IsVertexStronglyConnected(baseVertex))
                    AdjustWeaklyConnectedSubgraphs(baseVertex, vertex);
            }
            else
            {
                _connectedVertices.Add(vertex);

                WeaklyConnectedSubgraph weaklyConnectedSubgraph =
                    (IsVertexStronglyConnected(baseVertex)
                        ? new WeaklyConnectedSubgraph(baseVertex)
                        : _weaklyConnectedSubgraphs[baseVertex]);
                weaklyConnectedSubgraph.AddConnectedVertex(vertex);
                _weaklyConnectedSubgraphs.Add(vertex, weaklyConnectedSubgraph);

                AddOtherConnectedVertices(vertex);
            }
        }
 /// <summary>
 /// Adds all vertices which are directly connected to a specific base vertex to the list of
 /// vertices in the connected subgraph. The base vertex itself must have already been added
 /// to the list of vertices in the connected subgraph.
 /// </summary>
 /// <param name="baseVertex">The base vertex which is already in the list of vertices.
 /// </param>
 private void AddOtherConnectedVertices(Vertex baseVertex)
 {
     foreach (Vertex directlyConnectedVertex in baseVertex.ConnectedVertices)
     {
         AddConnectedVertex(directlyConnectedVertex, baseVertex);
     }
 }
 /// <summary>
 /// Checks if a vertex belongs to the strongly connected portion of the connected subgraph.
 /// </summary>
 /// <param name="vertex">The vertex which should be checked.</param>
 /// <returns><see langword="true"/> if the vertex belongs to the strongly connected portion
 /// of the connected subgraph.</returns>
 public bool IsVertexStronglyConnected(Vertex vertex)
 {
     return (_weaklyConnectedSubgraphs[vertex] == null);
 }
        /// <summary>
        /// Checks if adding an edge between two vertices in the connected subgraph will expand
        /// the strongly connected portion of the connected subgraph.
        /// </summary>
        /// <param name="vertex1">The first vertex which might be connected.</param>
        /// <param name="vertex2">The second vertex which might be connected.</param>
        /// <returns>see langword="true"/> if adding an edge between the two vertices will expand
        /// the strongly connected portion of the connected subgraph.</returns>
        public bool CheckWillConnectStrongly(Vertex vertex1, Vertex vertex2)
        {
            WeaklyConnectedSubgraph weaklyConnectedSubgraph1 = _weaklyConnectedSubgraphs[vertex1];
            WeaklyConnectedSubgraph weaklyConnectedSubgraph2 = _weaklyConnectedSubgraphs[vertex2];

            // If both vertices belong to the same weakly connected portion of the connected
            // subgraph or to the strongly connected portion of the connected subgraph, adding the
            // edge will not expand the strongly connected portion
            if (weaklyConnectedSubgraph1 == weaklyConnectedSubgraph2)
                return false;

            // If the first vertex belongs to the strongly connected portion of the connected
            // subgraph, adding the edge will expand the strongly connected portion when the first
            // vertex is the main vertex of the connected subgraph or differs from the anchor
            // vertex of the weakly connected portion of the connected subgraph which contains the
            // second vertex
            if (weaklyConnectedSubgraph1 == null)
            {
                return (vertex1 == _mainVertex
                        || vertex1 != weaklyConnectedSubgraph2.AnchorVertex);
            }

            // If the second vertex belongs to the strongly connected portion of the connected
            // subgraph, adding the edge will expand the strongly connected portion when the second
            // vertex is the main vertex of the connected subgraph or differs from the anchor
            // vertex of the weakly connected portion of the connected subgraph which contains the
            // first vertex
            if (weaklyConnectedSubgraph2 == null)
            {
                return (vertex2 == _mainVertex
                    || vertex1 != weaklyConnectedSubgraph1.AnchorVertex);
            }

            // If both vertices belong to different weakly connected portions of the connected
            // subgraph, adding the edge will integrate both weakly connected portions back into
            // the strongly connected portion
            return true;
        }
Esempio n. 10
0
 /// <summary>
 /// Checks if the vertex is directly connected to another vertex.
 /// </summary>
 /// <param name="otherVertex">The other vertex which should be checked.</param>
 /// <returns><see langword="true"/> if the specified vertex is directly connected to the
 /// current one.</returns>
 public bool IsConnectedToVertex(Vertex otherVertex)
 {
     return _connectedVertices.Contains(otherVertex);
 }
Esempio n. 11
0
        /// <summary>
        /// Removes the edge between the vertex and another vertex.
        /// </summary>
        /// <param name="otherVertex">The vertex which should be disconnected from the current one.
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// An attempt is made to disconnect the vertex from itself.
        /// 
        /// -or-
        /// No edge between the two vertices exists.
        /// </exception>
        /// <remarks>
        /// <para>The method removes the specified vertex from the list of directly connected
        /// vertices of the current vertex and vice versa.</para>
        /// </remarks>
        public void DisconnectFromVertex(Vertex otherVertex)
        {
            if (this == otherVertex)
                throw new InvalidOperationException("A vertex cannot be connected to itself.");
            if (!IsConnectedToVertex(otherVertex))
                throw new InvalidOperationException("No edge between the two vertices exists.");

            _connectedVertices.Remove(otherVertex);
            otherVertex._connectedVertices.Remove(this);
        }
Esempio n. 12
0
        /// <summary>
        /// Adds an edge between the vertex and another vertex.
        /// </summary>
        /// <param name="otherVertex">The vertex which should be connected to the current one.
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// An attempt is made to connect the vertex to itself.
        /// 
        /// -or-
        /// An edge between the two vertices already exists.
        /// </exception>
        /// <remarks>
        /// <para>The method adds the specified vertex to the list of directly connected vertices
        /// of the current vertex and vice versa.</para>
        /// </remarks>
        public void ConnectToVertex(Vertex otherVertex)
        {
            if (this == otherVertex)
                throw new InvalidOperationException("A vertex cannot be connected to itself.");
            if (IsConnectedToVertex(otherVertex))
            {
                throw new InvalidOperationException(
                    "An edge between the two vertices already exists.");
            }

            _connectedVertices.Add(otherVertex);
            otherVertex._connectedVertices.Add(this);
        }