예제 #1
0
        /// <summary>
        /// constructs a sub-tree
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="visitedEdges"></param>
        /// <param name="startEdge"></param>
        /// <returns></returns>
        private MinimumSpanningTree <T> ConstructSubTree(FeatureGraph <T> graph,
                                                         HashSet <int> visitedEdges,
                                                         Edge <T> startEdge)
        {
            // Manages the tree being constructed.
            var tree = new MinimumSpanningTree <T>();

            // Manages the list of candidate edges
            var tempEdges = new UniqueEdgeList <T>();

            // Seed of the breadth first search (BFS)
            tempEdges.AddEdge(startEdge);

            // Start BFS
            while (tempEdges.Count > 0)
            {
                // Sort the edges based on distace.
                tempEdges.Sort();

                Edge <T> shortestEdge  = null;
                var      edgesToRemove = new List <Edge <T> >();

                // Find the shortest edge...
                foreach (var edge in tempEdges.Edges)
                {
                    var edgeSeen   = tree.HasEdgeBeenSeen(edge);
                    var vertexSeen = tree.HasEdgeVerticesBeenSeen(edge);

                    // Make sure that we havent seen this edge.
                    if (edgeSeen)
                    {
                        continue;
                    }

                    if (vertexSeen)
                    {
                        visitedEdges.Add(edge.ID);
                        edgesToRemove.Add(edge);
                        continue;
                    }

                    shortestEdge = edge;
                    tree.AddEdge(shortestEdge);
                    break;
                }

                // Remove any edges that have been used up..
                edgesToRemove.ForEach(x => tempEdges.RemoveEdge(x));
                edgesToRemove.ForEach(x => graph.RemoveEdge(x));

                // We didnt find an edge, so we have nothing else to connect...
                if (shortestEdge == null)
                {
                    // Make sure that we assert that there are no edges left...should be the case here!
                    System.Diagnostics.Debug.Assert(tempEdges.Count == 0);
                    break;
                }

                visitedEdges.Add(shortestEdge.ID);

                // Removes the shortest edge from the graph...
                graph.RemoveEdge(shortestEdge);

                var adjacentEdges = graph.GetAdjacentEdgesFromEdgeVertices(shortestEdge);
                //adjacentEdges.Sort();

                tempEdges.AddEdges(adjacentEdges.Edges);

                // Remove the shortest edge from the list of available edges left...
                tempEdges.RemoveEdge(shortestEdge);
            }

            return(tree);
        }
예제 #2
0
        /// <summary>
        /// Creates clusters based on the MST's linear relationship made via construction.  Cutoff is the score (length) per edge
        /// that is allowed.
        /// </summary>
        /// <param name="mst">Minimum Spanning Tree</param>
        /// <param name="cutoff">Cutoff score</param>
        /// <returns>List of clusters</returns>
        private List <U> CreateClusters(MinimumSpanningTree <T> mst, double cutoff)
        {
            var clusters = new List <U>();

            if (mst.LinearRelationship.Count < 1)
            {
                return(clusters);
            }

            var currentCluster = new U();
            var hashedFeatures = new HashSet <T>(); // Tracks the current feature

            // These are the features that dont ever get included into a cluster...
            // This can only happen if the MST building picked a bunch of low-life features that
            // dont ever construct a graph...
            var lowLifeFeatures = new List <T>();

            for (var i = 0; i < mst.LinearRelationship.Count; i++)
            {
                // note this isnt O(n^2), this is just the search for a sub cluster
                //
                var currentEdge = mst.LinearRelationship[i];
                var vertexA     = currentEdge.VertexA;
                var vertexB     = currentEdge.VertexB;

                var seenA = hashedFeatures.Contains(vertexA);
                var seenB = hashedFeatures.Contains(vertexB);

                if (currentEdge.Length < cutoff)
                {
                    if (!seenA)
                    {
                        hashedFeatures.Add(vertexA);
                        currentCluster.AddChildFeature(vertexA);
                    }

                    if (!seenB)
                    {
                        hashedFeatures.Add(vertexB);
                        currentCluster.AddChildFeature(vertexB);
                    }
                }
                else
                {
                    if (currentCluster.Features.Count > 0)
                    {
                        clusters.Add(currentCluster);
                    }

                    currentCluster = new U();
                    if (!seenA && !seenB)
                    {
                        // I DONT KNOW WHAT TO DO WITH THESE ASSHOLES!
                        lowLifeFeatures.Add(vertexA);
                        lowLifeFeatures.Add(vertexB);

                        // We dont hash these guys yet, because later we'll see if they hit the market
                        // with their fake DVD's
                    }
                    else if (!seenA)
                    {
                        currentCluster.AddChildFeature(vertexA);
                        hashedFeatures.Add(vertexA);
                    }
                    else
                    {
                        hashedFeatures.Add(vertexB);
                        currentCluster.AddChildFeature(vertexB);
                    }
                }
            }

            // Make sure we add the current cluster if it's not full yet...
            if (currentCluster.Features.Count > 0)
            {
                clusters.Add(currentCluster);
            }

            foreach (var lowLife in lowLifeFeatures)
            {
                if (!hashedFeatures.Contains(lowLife))
                {
                    var cluster = new U();
                    cluster.AddChildFeature(lowLife);
                    clusters.Add(cluster);
                }
            }

            return(clusters);
        }