Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
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));
        }