Analyzer.DConnectorMotifDetector.FilterDConnectorMotifs C# (CSharp) Method

FilterDConnectorMotifs() protected method

protected FilterDConnectorMotifs ( DConnectorMotif>.Dictionary oPotentialDConnectorMotifs ) : ICollection
oPotentialDConnectorMotifs DConnectorMotif>.Dictionary
return ICollection
        protected ICollection<Motif> FilterDConnectorMotifs
            (Dictionary<string, DConnectorMotif> oPotentialDConnectorMotifs)
        {
            Debug.Assert(oPotentialDConnectorMotifs != null);

            HashSet<Motif> currentDConnectorMotifs = new HashSet<Motif>();

            Dictionary<IVertex, DConnectorMotif> verticesAlreadyInDConnectorMotifs =
                new Dictionary<IVertex, DConnectorMotif>();

            // Select only those potential D-connector motifs that have at least
            // two span vertices.

            foreach (DConnectorMotif potentialMotif in
                oPotentialDConnectorMotifs.Values.Where(
                    oPotentialDConnectorMotif =>
                    oPotentialDConnectorMotif.SpanVertices.Count >= 2)
                )
            {
                // If any of the motif's span vertices are included in another
                // D-connector motif we need to pick the motif to keep
                //
                // If this weren't done, for example, the following ring of vertices 
                // would result in two redundant two-connector motifs:
                //
                // A-B-C-D-A

                List<DConnectorMotif> overlappingMotifs =
                    (from spanVertex in potentialMotif.SpanVertices
                     where verticesAlreadyInDConnectorMotifs.ContainsKey(spanVertex)
                     select verticesAlreadyInDConnectorMotifs[spanVertex])
                     .Distinct<DConnectorMotif>().ToList<DConnectorMotif>();

                if (overlappingMotifs.Count > 0)
                {
                    // Our bookkeeping should prevent more than one overlap
                    Debug.Assert(overlappingMotifs.Count == 1);

                    DConnectorMotif existingMotif = overlappingMotifs[0];

                    int potAnchors = potentialMotif.AnchorVertices.Count,
                        potSpanners = potentialMotif.SpanVertices.Count,
                        potTotal = potAnchors + potSpanners;

                    int existAnchors = existingMotif.AnchorVertices.Count,
                        existSpanners = existingMotif.SpanVertices.Count,
                        existTotal = existAnchors + existSpanners;

                    // Potential motif is larger in total size, so we favor it
                    // -- OR --
                    // Potential motif is equal in total size and has more spanners, which we favor over more anchors
                    if (potSpanners > existSpanners ||
                        (
                        potSpanners == existSpanners &&
                        potTotal > existTotal))
                    {

                        // Remove the existing motif from the list of motifs and the dictionary entries for its vertices
                        currentDConnectorMotifs.Remove(existingMotif);

                        foreach (IVertex existingSpanVertex in existingMotif.SpanVertices)
                        {
                            verticesAlreadyInDConnectorMotifs.Remove(existingSpanVertex);
                        }

                        foreach (IVertex existingAnchorVertex in existingMotif.AnchorVertices)
                        {
                            verticesAlreadyInDConnectorMotifs.Remove(existingAnchorVertex);
                        }

                        // Add the potential DConnectorMotif and record its vertices
                        AddDConnectorMotif(currentDConnectorMotifs, verticesAlreadyInDConnectorMotifs, potentialMotif);
                    }
                    else
                    {
                        // Potential motif is smaller than the existing one or is the same size with fewer spanners -- do nothing
                    }

                }
                // If all of the motifs span vertices are not included in others, add the DConnectorMotif and record its vertices
                else
                {
                    AddDConnectorMotif(currentDConnectorMotifs, verticesAlreadyInDConnectorMotifs, potentialMotif);
                }
            }

            return currentDConnectorMotifs;
        }