예제 #1
0
        /// <summary>
        /// Creates a thresholded geometric graph
        /// </summary>
        /// <param name="d">distance matrix used to construct the graph</param>
        /// <param name="threshold">the maximum allowed distance</param>
        /// <returns></returns>
        public static LightWeightGraph GetGeoGraph(DistanceMatrix d, double threshold)
        {
            //construct the geo graph
            int numNodes = d.Count;
            var nodes    = new LightWeightGraph.LightWeightNode[numNodes];

            //Create a list to hold edge values
            List <int>[]    edges   = new List <int> [numNodes];
            List <double>[] weights = new List <double> [numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edges[i] = new List <int>();
            }

            //Add Edges
            for (int i = 0; i < numNodes - 1; i++)
            {
                for (int j = i + 1; j < numNodes; j++)
                {
                    if (d[i, j] <= threshold)
                    {
                        edges[i].Add(j);
                        edges[j].Add(i);
                    }
                }
            }
            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new LightWeightGraph.LightWeightNode(i, true, edges[i], weights[i]);
            }

            return(new LightWeightGraph(nodes, true));
        }
예제 #2
0
        public LightWeightGraph GetNormalizedRandomGraph(DistanceMatrix d)
        {
            int numNodes = d.Count;
            var nodes    = new LightWeightGraph.LightWeightNode[numNodes];
            // make an array to hold all possible edges, less the edges in the mst
            List <oneNode> myDistances = new List <oneNode>();

            LightWeightGraph mst = LightWeightGraph.GetStackedMST(d, 1);

            LightWeightGraph.LightWeightNode[] mstNodes = mst.Nodes;

            //Create a list to hold edge values
            List <int>[]    edges   = new List <int> [numNodes];
            List <double>[] weights = new List <double> [numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edges[i]   = new List <int>();
                weights[i] = new List <double>();
            }

            double largestMSTEdge = 0.0;

            // add edges from the mst to the edges list, to facilitate adding additional edges later on
            // Also find the largest edge to use as a cutoff
            for (int i = 0; i < numNodes; i++)
            {
                for (int j = 0; j < mstNodes[i].Edge.Length; j++)
                {
                    largestMSTEdge = Math.Max(largestMSTEdge, mst[i].EdgeWeights[j]);
                    edges[i].Add(mstNodes[i].Edge[j]);
                    weights[i].Add(mstNodes[i].EdgeWeights[j]);
                }
            }
            largestMSTEdge *= _cutoffProp;
            // cycle through each possible edge
            // if the edge exists in the mst, continue
            // otherwise, add the edge to distances array, and add distance to the edge to the cummulative total
            for (int i = 0; i < numNodes - 1; i++)
            {
                for (int j = i + 1; j < numNodes; j++)
                {
                    double dist = d[i, j];
                    if (dist >= largestMSTEdge || mstNodes[i].Edge.Contains(j))
                    {
                        continue;
                    }
                    else
                    {
                        //Probability function goes here

                        double  addlProb = _normAlpha * (1.0 / Math.Exp(_xScale * dist / largestMSTEdge));
                        oneNode nd       = new oneNode {
                            prob = addlProb, fromNode = i, toNode = j, alreadyExists = false
                        };
                        myDistances.Add(nd);
                    }
                }
            }

            // walk through the array until you find the random number
            for (int m = 0; m < myDistances.Count; m++)
            {
                double rand = Utility.Util.Rng.NextDouble();
                if (myDistances[m].prob > rand)
                {
                    // we have found the edge to add.
                    // add the edge if it does not already exist
                    if (!myDistances[m].alreadyExists)
                    {
                        int    from = myDistances[m].fromNode;
                        int    to   = myDistances[m].toNode;
                        double dist = d[from, to];
                        edges[from].Add(to);
                        weights[from].Add(dist);
                        edges[to].Add(from);
                        weights[to].Add(dist);
                        myDistances[m].alreadyExists = true;
                    }
                }
            }

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

            return(new LightWeightGraph(nodes, true));
        }
예제 #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));
        }
예제 #4
0
        /// <summary>
        /// Creates a random graph, based on an mst.
        /// </summary>
        /// <param name="d">distance matrix used to construct the graph</param>
        /// <param name="alpha">the resulting average degree of the graph</param>
        /// /// <param name="expP">The probability of adding an edge depends on its distance: 1/d^expP</param>
        /// <returns></returns>
        public static LightWeightGraph GetRandomGraph(DistanceMatrix d, int alpha, double expP)
        {
            int numNodes = d.Count;

            var nodes = new LightWeightGraph.LightWeightNode[numNodes];

            // make an array to hold all possible edges, less the edges in the mst
            oneNode[] myDistances = new oneNode[numNodes * (numNodes - 1) / 2 - (numNodes - 1)];

            LightWeightGraph mst = LightWeightGraph.GetStackedMST(d, 1);

            LightWeightGraph.LightWeightNode[] mstNodes = mst.Nodes;
            int    myDistancesIndex = 0;
            double myDistancesTotal = 0;

            //Create a list to hold edge values
            List <int>[]    edges   = new List <int> [numNodes];
            List <double>[] weights = new List <double> [numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                edges[i] = new List <int>();
            }

            // add edges from the mst to the edges list, to facilitate adding additional edges later on
            for (int i = 0; i < numNodes; i++)
            {
                for (int j = 0; j < mstNodes[i].Edge.Length; j++)
                {
                    edges[i].Add(mstNodes[i].Edge[j]);
                }
            }


            // cycle through each possible edge
            // if the edge exists in the mst, continue
            // otherwise, add the edge to distances array, and add distance to the edge to the cummulative total
            for (int i = 0; i < numNodes - 1; i++)
            {
                for (int j = i + 1; j < numNodes; j++)
                {
                    if (mstNodes[i].Edge.Contains(j))
                    {
                        continue;
                    }
                    else
                    {
                        double addlProb = 1.0 / Math.Pow(d[i, j], expP);
                        myDistancesTotal += addlProb;
                        oneNode nd = new oneNode {
                            prob = myDistancesTotal, fromNode = i, toNode = j, alreadyExists = false
                        };
                        myDistances[myDistancesIndex] = nd;
                        myDistancesIndex++;
                    }
                }
            }

            // how many edges do we want to add?
            int desiredNewEdges = (alpha * numNodes) - (numNodes - 1);

            Random rnd = Utility.Util.Rng;

            // add edges randomly until we have added the desired number of edges
            while (desiredNewEdges > 0)
            {
                // generate a random number between 0 and myDistancesTotal
                double rand = rnd.NextDouble() * myDistancesTotal;

                // walk through the array until you find the random number
                for (int m = 0; m < myDistances.Length; m++)
                {
                    if (myDistances[m].prob > rand)
                    {
                        // we have found the edge to add.
                        // add the edge if it does not already exist
                        if (!myDistances[m].alreadyExists)
                        {
                            edges[myDistances[m].fromNode].Add(myDistances[m].toNode);
                            edges[myDistances[m].toNode].Add(myDistances[m].fromNode);
                            myDistances[m].alreadyExists = true;
                            desiredNewEdges--;
                            break;
                        }
                    }
                }
            }
            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new LightWeightGraph.LightWeightNode(i, true, edges[i], weights[i]);
            }

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