//Stacked MST
        public static LightWeightGraph GetStackedMST(DistanceMatrix distances, int numMSTs)
        {
            int numNodes = distances.Count;

            //in a complete graph, there are n*(n-1)/2 edges
            //an MST contains n-1 edges
            //number of msts is n/2
            if (numMSTs > numNodes / 2)
            {
                numMSTs = numNodes / 2;
            }

            LightWeightNode[] nodes = new LightWeightNode[numNodes];

            List <int>[]    edges   = new List <int> [numNodes];
            List <double>[] weights = new List <double> [numNodes];
            //List<double>[] edgeWeights = new List<double>[numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edges[i]   = new List <int>();
                weights[i] = new List <double>();
            }

            //Add all of the distances to the Heap

            List <distXY> points = new List <distXY>();

            for (int x = 0; x < numNodes - 1; x++)
            {
                for (int y = x + 1; y < numNodes; y++)
                {
                    points.Add(new distXY(x, y, distances[x, y]));
                }
            }


            //Now we need to start making our MST
            for (int n = 0; n < numMSTs; n++)
            {
                MinHeapPriorityQueue <distXY> minheap = new MinHeapPriorityQueue <distXY>(((x, y) => x.Dist > y.Dist));
                minheap.addAll(points);

                DisjointSet ds = new DisjointSet(numNodes);
                int         k  = 0;
                while (k < numNodes - 1)
                {
                    distXY e = minheap.extractMin();
                    if (ds.diff(e.X, e.Y)) //different
                    {
                        ds.union(e.X, e.Y);
                        //change the dist
                        e.Dist = double.MaxValue;
                        //Add it
                        edges[e.X].Add(e.Y);
                        edges[e.Y].Add(e.X);
                        weights[e.X].Add(distances[e.X, e.Y]);
                        weights[e.Y].Add(distances[e.X, e.Y]);
                        k++;
                    }
                }
            }

            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new LightWeightNode(i, true, edges[i], weights[i]);
            }

            return(new LightWeightGraph(nodes, true));
        }
        //Knn based
        public static LightWeightGraph GetKNNGraph(DistanceMatrix distances, int numNeighbors)
        {
            int numNodes = distances.Count;
            var nodes    = new LightWeightNode[numNodes];

            List <int>[]    edgeLists   = new List <int> [numNodes];
            List <double>[] edgeWeights = new List <double> [numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edgeLists[i]   = new List <int>();
                edgeWeights[i] = new List <double>();
            }

            //prevent redundant edges
            HashSet <Tuple <int, int> > addedEdges = new HashSet <Tuple <int, int> >();

            //Our comparator
            MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan comp =
                new MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan((x, y) => { return(x.Item2 > y.Item2); });

            //Add Edges
            for (int i = 0; i < numNodes; i++)
            {
                //get list of edges
                List <Tuple <int, double> > edges = new List <Tuple <int, double> >();
                for (int j = 0; j < numNodes; j++)
                {
                    //Make sure we don't load our heap with repeated edges
                    if (i != j)
                    {
                        edges.Add(new Tuple <int, double>(j, distances[i, j]));
                    }
                }
                //Build the heap
                MinHeapPriorityQueue <Tuple <int, double> > heap = new MinHeapPriorityQueue <Tuple <int, double> >(comp);
                heap.addAll(edges);

                //Now add all of the neighbors
                for (int edgeNum = 0; edgeNum < numNeighbors; edgeNum++)
                {
                    if (heap.isEmpty())
                    {
                        break;
                    }

                    Tuple <int, double> e = heap.extractMin();

                    Tuple <int, int> edgeNodePair = (e.Item1 < i)
                            ? new Tuple <int, int>(e.Item1, i)
                            : new Tuple <int, int>(i, e.Item1);


                    //if (!addedEdges.Contains(edgeNodePair))
                    if (!addedEdges.Contains(edgeNodePair))
                    {
                        //make sure we don't add this edge again in the future
                        //addedEdges.Add(edgeNodePair);
                        addedEdges.Add(edgeNodePair);
                        //Add the double edge now
                        edgeLists[i].Add(e.Item1);
                        edgeLists[e.Item1].Add(i);
                        edgeWeights[i].Add((double)e.Item2);
                        edgeWeights[e.Item1].Add((double)e.Item2);
                    }
                }
            }

            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new LightWeightNode(i, true, edgeLists[i], edgeWeights[i]);
            }

            return(new LightWeightGraph(nodes, true));
        }
Example #3
0
        public LightWeightGraph GetLOOGraph(DistanceMatrix distances, int numNeighbors, bool[] exclusion = null, int numToLeaveOut = 0)
        {
            int numNodes = distances.Count;

            var nodes = new LightWeightGraph.LightWeightNode[numNodes];

            List <int>[]    edgeLists   = new List <int> [numNodes];
            List <double>[] edgeWeights = new List <double> [numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edgeLists[i]   = new List <int>();
                edgeWeights[i] = new List <double>();
            }

            //prevent redundant edges
            HashSet <Tuple <int, int> > addedEdges = new HashSet <Tuple <int, int> >();

            //Our comparator
            MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan comp = ((x, y) => x.Item2 > y.Item2);

            //Deal with _skipLast Choice
            int lastNeighbor = (_skipLast) ? numNodes - 1 : numNodes;

            //Add Edges
            for (int i = 0; i < lastNeighbor; i++)
            {
                if (exclusion != null && exclusion[i])
                {
                    continue;
                }
                // Deal with the leave one out
                double probability = (double)numToLeaveOut / numNodes;
                double rollDie     = rnd.NextDouble();
                if (rollDie < probability)
                {
                    //Console.WriteLine("Skipped Node " + i);
                    _numLeftOut++;
                    continue;
                }


                //get list of edges
                List <Tuple <int, double> > edges = new List <Tuple <int, double> >();
                for (int j = 0; j < numNodes; j++)
                {
                    //Make sure we don't load our heap with repeated edges
                    if (i != j)
                    {
                        edges.Add(new Tuple <int, double>(j, distances[i, j]));
                    }
                }
                //Build the heap
                MinHeapPriorityQueue <Tuple <int, double> > heap = new MinHeapPriorityQueue <Tuple <int, double> >(comp);
                heap.addAll(edges);

                //Now add all of the neighbors
                for (int edgeNum = 0; edgeNum < numNeighbors; edgeNum++)
                {
                    if (heap.isEmpty())
                    {
                        break;
                    }

                    Tuple <int, double> e = heap.extractMin();

                    Tuple <int, int> edgeNodePair = (e.Item1 < i)
                            ? new Tuple <int, int>(e.Item1, i)
                            : new Tuple <int, int>(i, e.Item1);


                    //if (!addedEdges.Contains(edgeNodePair))
                    if (!addedEdges.Contains(edgeNodePair))
                    {
                        //make sure we don't add this edge again in the future
                        //addedEdges.Add(edgeNodePair);
                        addedEdges.Add(edgeNodePair);
                        //Add the double edge now
                        edgeLists[i].Add(e.Item1);
                        edgeLists[e.Item1].Add(i);
                        edgeWeights[i].Add((double)e.Item2);
                        edgeWeights[e.Item1].Add((double)e.Item2);
                    }
                }
            }

            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new LightWeightGraph.LightWeightNode(i, true, edgeLists[i], edgeWeights[i]);
            }

            return(new LightWeightGraph(nodes, true));
        }