public static void approximate_betweenness(LightWeightGraph G, int M, List <int> seeds, List <double> btws)
        {
            int V = G.Nodes.Count(); //int V = G.size();

            for (int i = 0; i < V; i++)
            {
                btws.Add(0);
            }
            List <List <Tuple <int, double> > > H = new List <List <Tuple <int, double> > >(); // whg_t H;

            build_betweenness_hypergraph(G, H, M, seeds);

            //btws = new double[V];
            for (int i = 0; i < H.Count; i++)
            {
                //rep(i, H.size()) {
                List <Tuple <int, double> > whe = H[i]; // whe_t & whe = H[i];
                for (int j = 0; j < whe.Count; j++)
                {
                    //rep(j, whe.size()) {
                    int v = whe[j].Item1;
                    btws[v] += whe[j].Item2;
                }
            }
        }
예제 #2
0
        public Partition GetPartition()
        {
            LightWeightGraph lwg = (_reassignNodes) ? GetAttackedGraphWithReassignment() : GetAttackedGraph();

            //Get our cluster Assignment
            List <List <int> > componentList = lwg.GetComponents();

            //Setup our Clusters
            List <Cluster> clusterList = new List <Cluster>();

            for (int i = 0; i < componentList.Count; i++)
            {
                Cluster c = new Cluster(i);
                foreach (var n in componentList[i])
                {
                    c.AddPoint(new ClusteredItem(lwg[n].Label));
                }
                clusterList.Add(c);
            }

            String meta = "VAT: \nRemoved Count:" + NumNodesRemoved + "\n"
                          + String.Join(",", _nodeRemovalOrder.GetRange(0, NumNodesRemoved));

            return(new Partition(clusterList, g, meta));
        }
예제 #3
0
        //Vat computes given a graph
        public Integrity(LightWeightGraph lwg, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = new List <int>();
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            bool threaded = Settings.Threading.ThreadHVAT;

            //This is where our estimate for Vat is calculated
            for (int n = 0; n < g.NumNodes - 1; n++)  // was g.NumNodes / 2
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);

                //get the betweeness
                Console.WriteLine("Getting betweenness for node " + n);
                double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
                                      BetweenessCentrality.BrandesBcNodes(gItter);
                //get the index of the maximum
                int indexMaxBetweeness = betweeness.IndexOfMax();
                int labelOfMax         = gItter.Nodes[indexMaxBetweeness].Label;

                //now we should add it to our list
                _nodeRemovalOrder.Add(labelOfMax);
                _removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateIntegrity(_removedNodes);
                if (vat < _minVat)
                {
                    _minVat          = vat;
                    _numNodesRemoved = n + 1;
                }
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
        static void restricted_bfs(LightWeightGraph G, int s, Dictionary <int, int> baseline_dists, Dictionary <int, int> nums, bool[] is_seed, HashSet <int> domain)
        {
            int        qh = 0;
            List <int> q  = new List <int>();
            //baseline_dists = new Dictionary<int, int>();
            Dictionary <int, int> dists = new Dictionary <int, int>();
            //nums = new Dictionary<int, int>();
            int myValue;

            if (baseline_dists.TryGetValue(s, out myValue) && baseline_dists[s] != 0)
            {
                return;
            }
            if (!domain.Contains(s))
            {
                return;
            }

            q.Add(s);
            dists[s] = 0;
            nums[s]  = 1;
            while (qh != (int)q.Count())
            {
                int u = q[qh++];
                for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                {
                    int v = G.Nodes[u].Edge[i];
                    if (!domain.Contains(v) || is_seed[v])
                    {
                        continue;
                    }
                    if (baseline_dists[v] != baseline_dists[u] + 1)
                    {
                        continue;
                    }

                    if (!dists.TryGetValue(v, out myValue) || dists[v] == dists[u] + 1)
                    {
                        //nums[v] += nums[u];
                        nums.TryGetValue(u, out myValue);
                        try
                        {
                            nums.Add(v, myValue);
                        }
                        catch (System.ArgumentException)
                        {
                            int myValue2;
                            nums.TryGetValue(v, out myValue2);
                            nums[v] = myValue + myValue2;
                        }
                    }
                    if (!dists.TryGetValue(v, out myValue))
                    {
                        dists[v] = dists[u] + 1;
                        q.Add(v);
                    }
                }
            }
        }
        /// <summary>
        /// Calculates Betweeness centrality of the edges in an undirected graph
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static NodeEdgeBetweeness BrandesBcEdges(LightWeightGraph g)
        {
            var edgeMap  = g.GetEdgeIndexMap();
            int numNodes = g.NumNodes;
            int numEdges = edgeMap.Count;

            double[] bcEdge = new double[numEdges];
            double[] bcNode = new double[numNodes];
            for (int v = 0; v < numNodes; v++)
            {
                //Get a shortest path, if weighted use Dikstra, if unweighted use BFS
                ShortestPathProvider asp = (g.IsWeighted) ? new DikstraProvider2(g, v) :
                                           new BFSProvider(g, v) as ShortestPathProvider;

                //numberOfShortestPaths = sigma
                double[] deltaNode = new double[numNodes];
                while (asp.S.Count > 0)
                {
                    int    w     = asp.S.Pop();
                    double coeff = (1.0f + deltaNode[w]) / (double)asp.numberOfShortestPaths[w];
                    foreach (int n in  asp.fromList[w])
                    {
                        //make sure the first index is the smallest, this is an undirected graph
                        KeyValuePair <int, int> edgeNodePair = (w < n)
                            ? new KeyValuePair <int, int>(w, n)
                            : new KeyValuePair <int, int>(n, w);

                        int    edgeIndex    = edgeMap[edgeNodePair];
                        double contribution = asp.numberOfShortestPaths[n] * coeff;
                        bcEdge[edgeIndex] += contribution;
                        deltaNode[n]      += contribution;
                    }
                    //Add the betweeness contribution to W
                    if (v != w)
                    {
                        bcNode[w] += deltaNode[w];
                    }
                }
            }

            //divide all by 2 (undirected)
            for (int v = 0; v < numEdges; v++)
            {
                bcEdge[v] /= 2f;
            }

            for (int v = 0; v < numNodes; v++)
            {
                bcNode[v] /= 2f;
            }

            return(new NodeEdgeBetweeness()
            {
                EdgeBetweeness = bcEdge, NodeBetweeness = bcNode
            });
        }
 /// <summary>
 /// Make a deep Copy of a Graph
 /// </summary>
 /// <param name="g">LightWeightGraph to copy</param>
 public LightWeightGraph(LightWeightGraph g)
     : base(DataType.Graph)
 {
     NumNodes = g.NumNodes;
     Nodes    = new LightWeightNode[NumNodes];
     for (int i = 0; i < NumNodes; i++)
     {
         Nodes[i] = new LightWeightNode(g[i]);
     }
     IsWeighted = g.IsWeighted;
 }
        static void restricted_bfs(LightWeightGraph G, int s, int[] baseline_dists, int[] nums, bool[] is_seed)
        {
            int        V = G.Nodes.Count();
            int        qh = 0, qt = 0;
            List <int> q = new List <int>(V);

            for (int i = 0; i < V; i++)
            {
                q.Add(0);
            }


            int[] dists = new int[V];
            for (int i = 0; i < dists.Length; i++)
            {
                dists[i] = -1;
            }
            //nums = new int[V];

            if (baseline_dists[s] != 0)
            {
                return;
            }

            q[qt++]  = s;
            dists[s] = 0;
            nums[s]  = 1;
            while (qh != qt)
            {
                int u = q[qh++];
                for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                {
                    int v = G.Nodes[u].Edge[i];
                    if (is_seed[v])
                    {
                        continue;
                    }
                    if (baseline_dists[v] != baseline_dists[u] + 1)
                    {
                        continue;
                    }

                    if (dists[v] == -1 || dists[v] == dists[u] + 1)
                    {
                        nums[v] += nums[u];
                    }
                    if (dists[v] == -1)
                    {
                        dists[v] = dists[u] + 1;
                        q[qt++]  = v;
                    }
                }
            }
        }
예제 #8
0
        //Vat computes given a graph
        public VAT(LightWeightGraph lwg, float alpha = 1.0f, float beta = 0.0f)
        {
            //set our alpha and beta variables
            this.alpha = alpha; this.beta = beta;

            //first we set our variables up
            removedNodes     = new bool[lwg.NumNodes];
            nodeRemovalOrder = new List <int>();
            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            //This is where our estimate for Vat is calculated
            for (int n = 0; n < g.NumNodes / 2; n++)  // this was 32, I think a typo?
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, removedNodes);

                //get the betweeness
                float[] BC = BetweenessCentrality.BrandesBcNodes(gItter);

                //get the index of the maximum
                int indexMaxBC = BC.IndexOfMax();
                int labelOfMax = gItter.Nodes[indexMaxBC].Label;

                //now we should add it to our list
                nodeRemovalOrder.Add(labelOfMax);
                removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                float vat = CalculateVAT(removedNodes);
                if (vat < minVat)
                {
                    minVat          = vat;
                    numNodesRemoved = n + 1;
                }
                Console.WriteLine("Node {0} removed", n);
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < removedNodes.Length; i++)
            {
                removedNodes[i] = false;
            }
            for (int i = 0; i < numNodesRemoved; i++)
            {
                removedNodes[nodeRemovalOrder[i]] = true;
            }

            //hillclimbing would go here
        }
예제 #9
0
        public Integrity(LightWeightGraph lwg, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f, List <int> nodeRemovalOrder = null, int numNodesRemoved = 0)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = nodeRemovalOrder;
            _numNodesRemoved  = numNodesRemoved;
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            //bool threaded = Settings.Threading.ThreadHVAT;
            //This is where our estimate for Vat is calculated
            for (int n = 0; n < g.NumNodes; n++)  // This was evaluating g.Numnodes/2
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);

                //now we should add it to our list
                int labelOfMax = _nodeRemovalOrder[n];
                //_nodeRemovalOrder.Add(labelOfMax);
                _removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateIntegrity(_removedNodes);
                if (vat < _minVat)
                {
                    _minVat          = vat;
                    _numNodesRemoved = n + 1;
                }
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
        }         // end bfs

        static void bfs(LightWeightGraph G, int s, Dictionary <int, int> dists, Dictionary <int, int> nums, HashSet <int> alive)
        {
            int        qh = 0;
            List <int> q  = new List <int>();

            // dists = new Dictionary<int, int>();
            // nums = new Dictionary<int, int>();
            dists.Clear();
            nums.Clear();

            if (!alive.Contains(s))
            {
                return;
            }

            q.Add(s);
            dists[s] = 0;
            nums[s]  = 1;
            int myValue;

            while (qh != (int)q.Count())
            {
                int u = q[qh++];
                for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                {
                    int v = G.Nodes[u].Edge[i];
                    if (!alive.Contains(v))
                    {
                        continue;
                    }

                    if (!dists.TryGetValue(v, out myValue) || dists[v] == dists[u] + 1)
                    {
                        //nums[v] += nums[u];
                        nums.TryGetValue(u, out myValue);
                        try { nums.Add(v, myValue); }
                        catch (System.ArgumentException)
                        {
                            int myValue2;
                            nums.TryGetValue(v, out myValue2);
                            nums[v] = myValue + myValue2;
                        }
                    }
                    if (!dists.TryGetValue(v, out myValue))
                    {
                        dists[v] = dists[u] + 1;
                        q.Add(v);
                    }
                }
            }
        }
예제 #11
0
        public BFSProvider(LightWeightGraph g, int startV)
            : base(g.Nodes.Length)
        {
            int numNodes = g.Nodes.Length;

            numberOfShortestPaths[startV] = 1;
            bool[] isVisited = new bool[numNodes];
            int[]  dist      = new int[numNodes];

            for (int i = 0; i < numNodes; i++)
            {
                fromList[i] = new List <int>(5);
            }

            //now we need to set our node to 0
            dist[startV] = 0;

            Queue <int> Q = new Queue <int>();

            Q.Enqueue(startV);
            isVisited[startV] = true;
            while (Q.Count > 0)
            {
                //Grab an item
                int v = Q.Dequeue();
                S.Push(v);
                var nodeV = g.Nodes[v];
                int dV    = dist[v];

                int edgeCount = nodeV.Count;
                for (int i = 0; i < edgeCount; i++)
                {
                    int w = nodeV.Edge[i];

                    if (!isVisited[w])
                    {
                        Q.Enqueue(w);
                        isVisited[w] = true;
                        dist[w]      = dV + 1;
                    }
                    if (dist[w] == (dV + 1))
                    {
                        numberOfShortestPaths[w] += numberOfShortestPaths[v];
                        fromList[w].Add(v);
                    }
                }
            }
        }
        /// <summary>
        /// Calculates Node based Betweeness Centrality using multiple threads
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static double[] ParallelBrandesBcNodes2(LightWeightGraph g)
        {
            int numNodes   = g.NumNodes;
            int numThreads = Settings.Threading.NumThreadsBc;
            int numExtra   = numNodes % numThreads;

            double[] bcMap = new double[numNodes];
            //Create our threads use a closure to get our return arrays

            int i = 0;

            while (i < numNodes)
            {
                int               numT          = (numNodes - i > numExtra) ? numThreads : numExtra;
                CountdownEvent    cde           = new CountdownEvent(numT);
                BetweenessCalc2[] threadResults = new BetweenessCalc2[numT];
                for (int t = 0; t < numT; t++)
                {
                    int             tIndex  = t;
                    BetweenessCalc2 tResult = new BetweenessCalc2(g, i + t);
                    threadResults[tIndex] = tResult;
                    ThreadPool.QueueUserWorkItem(tResult.ThreadPoolCallback, cde);
                }
                cde.Wait();
                for (int t = 0; t < numT; t++)
                {
                    var threadR = threadResults[t].delta;
                    for (int n = 0; n < numNodes; n++)
                    {
                        bcMap[n] += threadR[n];
                    }
                }
                i += numThreads;
            }

            //divide all by 2 (undirected)
            for (int v = 0; v < numNodes; v++)
            {
                bcMap[v] /= 2f;
            }

            return(bcMap);
        }
예제 #13
0
        public BFSProvider(LightWeightGraph g, int v)
            : base(g.Nodes.Length)
        {
            int numNodes = g.Nodes.Length;
            numberOfShortestPaths[v] = 1;
            bool[] isVisited = new bool[numNodes];

            //we must set each node to infinite distance
            for (int i = 0; i < numNodes; i++)
            {
                g.Nodes[i].NodeWeight = float.MaxValue;
                fromList[i] = new List<int>(5);
            }

            //now we need to set our node to 0
            g.Nodes[v].NodeWeight = 0.0f;

            Queue<int> Q = new Queue<int>();
            Q.Enqueue(v);
            isVisited[v] = true;
            while (Q.Count > 0)
            {
                //Grab an item
                int u = Q.Dequeue();
                this.S.Push(u);
                var nodeU = g.Nodes[u];
                int edgeCount = nodeU.Count;
                for (int i = 0; i < edgeCount; i++)
                {
                    int w = nodeU.Edge[i];
                    if (!isVisited[w])
                    {
                        float newWeight = nodeU.NodeWeight + 1.0f;
                        numberOfShortestPaths[w] += numberOfShortestPaths[u];
                        g.Nodes[w].NodeWeight = newWeight;
                        Q.Enqueue(w);
                        isVisited[w] = true;
                        fromList[w].Add(u);
                    }
                }
            }
        }
        //typedef std::vector<std::vector<int> > g_t;
        //typedef std::vector<int> he_t;
        //typedef std::vector<he_t> hg_t;
        //typedef std::vector<std::pair<int, double> > whe_t;
        //typedef std::vector<whe_t> whg_t;

        /*********/
        /*  BFS  */
        /*********/

        static void bfs(LightWeightGraph G, int s, int[] dists, int[] nums)
        {
            int V = G.Nodes.Count();
            int qh = 0, qt = 0;

            int[] q = new int[V];

            //dists = new int[V];  // initialize with -1
            for (int i = 0; i < V; i++)
            {
                dists[i] = -1;
            }
            //nums = new int[V];
            for (int i = 0; i < V; i++)
            {
                nums[i] = 0;
            }
            q[qt++]  = s;
            dists[s] = 0;
            nums[s]  = 1;
            while (qh != qt)
            {
                int u = q[qh++];
                for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                {
                    int v = G.Nodes[u].Edge[i];

                    if (dists[v] == -1 || dists[v] == dists[u] + 1)
                    {
                        nums[v] += nums[u];
                    }
                    if (dists[v] == -1)
                    {
                        dists[v] = dists[u] + 1;
                        q[qt++]  = v;
                    }
                } //for loop ends here
            }
        }         // end bfs
        public static double[] BrandesBcNodes(LightWeightGraph g)
        {
            int numnodes = g.NumNodes;

            double[] bcMap = new double[numnodes];
            double[] delta = new double[numnodes];
            for (int v = 0; v < numnodes; v++)
            {
                //Get a shortest path, if weighted use Dikstra, if unweighted use BFS
                ShortestPathProvider asp = (g.IsWeighted) ? new DikstraProvider2(g, v) :
                                           new BFSProvider(g, v) as ShortestPathProvider;
                Array.Clear(delta, 0, numnodes);

                while (asp.S.Count > 0)
                {
                    int w     = asp.S.Pop();
                    var wList = asp.fromList[w];
                    foreach (int n in wList)
                    {
                        delta[n] += ((double)asp.numberOfShortestPaths[n] / (double)asp.numberOfShortestPaths[w]) * (1.0f + delta[w]);
                    }
                    if (w != v)
                    {
                        bcMap[w] += delta[w];
                    }
                }
            }

            //divide all by 2 (undirected)
            for (int v = 0; v < numnodes; v++)
            {
                bcMap[v] /= 2f;
            }

            return(bcMap);
        }
        /**************************/
        /*  Building Hypergraphs  */
        /**************************/


        static void build_betweenness_hypergraph(LightWeightGraph G, List <List <Tuple <int, double> > > H, int M, List <int> seeds, List <Tuple <int, int> > pairs = null)
        {
            Random r = new Random();
            int    V = G.Nodes.Count();

            bool[] is_seed = new bool[V];
            for (int i = 0; i < seeds.Count; i++)
            {
                is_seed[seeds[i]] = true;
            }

            for (int j = 0; j < M; j++)
            {
                int s = r.Next(0, V), t = r.Next(0, V);
                //if (pairs) pairs->push_back(std::make_pair(s, t));
                if (pairs != null)
                {
                    pairs.Add(new Tuple <int, int>(s, t));
                }
                int[] dists           = new int[V];
                int[] nums            = new int[V];
                int[] nums_with_seeds = new int[V];
                bfs(G, s, dists, nums);

                restricted_bfs(G, s, dists, nums_with_seeds, is_seed);

                int      qh = 0, qt = 0;
                int[]    q     = new int[V];    // std::vector<int> q(V);
                bool[]   added = new bool[V];   //  std::vector<bool> added(V);
                double[] btws  = new double[V]; // std::vector<double> btws(V);
                List <Tuple <int, double> > whe = new List <Tuple <int, double> >();
                //std::vector<std::pair<int, double>> whe;
                //whe_t whe;
                q[qt++]  = t;
                added[t] = true;

                while (qh != qt)
                {
                    int u = q[qh++];
                    if (u == s)
                    {
                        continue;
                    }

                    for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                    {                               //rep(i, G[u].size()) {
                        int v = G.Nodes[u].Edge[i]; //int v = G[u][i];
                        if (dists[v] == dists[u] - 1)
                        {
                            if (added[v] == false)
                            {
                                q[qt++]  = v;
                                added[v] = true;
                            }
                        }
                        else if (dists[v] == dists[u] + 1)
                        {
                            double k = 0;
                            k += (double)nums_with_seeds[u] / nums[v];
                            if (nums_with_seeds[v] != 0)
                            {
                                if (!is_seed[v])
                                {
                                    k += btws[v] / nums_with_seeds[v] * nums_with_seeds[u];
                                }
                            }
                            btws[u] += k;
                        }
                    }
                    whe.Add(new Tuple <int, double>(u, btws[u]));
                    //whe.push_back(std::make_pair(u, btws[u]));
                }
                H.Add(whe); // H.push_back(whe);
            }
        }
예제 #17
0
        //Vat computes given a graph
        public VatABC(LightWeightGraph lwg, int M, int k, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = new List <int>();
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            bool threaded = Settings.Threading.ThreadHVAT;
            //This is where our estimate for Vat is calculated

            // Get the adaptive betweenness rankings
            List <int>    seeds = new List <int>();
            List <double> btwss = new List <double>();

            // next step using k = g.Numnodes/2
            NetMining.Graphs.AdaptiveBetweennessCentrality.adaptive_approximate_betweenness(lwg, M, g.NumNodes / 2, seeds, btwss);
            for (int n = 0; n < g.NumNodes / 2; n++)
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                //sw.Restart();
                //get the betweeness
                //double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
                //    BetweenessCentrality.BrandesBcNodes(gItter);
                //sw.Stop();
                //Console.WriteLine("{0} {1}ms", n+1, sw.ElapsedMilliseconds);
                //get the index of the maximum
                //int indexMaxBetweeness = betweeness.IndexOfMax();
                int indexMaxBetweeness = n;
                //int labelOfMax = gItter.Nodes[indexMaxBetweeness].Label;
                int labelOfMax = seeds[n];

                //now we should add it to our list
                _nodeRemovalOrder.Add(labelOfMax);
                _removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateVAT(_removedNodes);
                if (vat < _minVat)
                {
                    _minVat          = vat;
                    _numNodesRemoved = n + 1;
                }
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
        /// <summary>
        /// Calculates Node based Betweeness Centrality using multiple threads
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static double[] ParallelBrandesBcNodes(LightWeightGraph g)
        {
            int numNodes      = g.NumNodes;
            int numThreads    = Settings.Threading.NumThreadsBc;
            int workSize      = numNodes / numThreads;
            int workSizeExtra = numNodes % numThreads;

            //Start getting a randomized work load
            List <int> nodes = new List <int>(numNodes);

            for (int i = 0; i < numNodes; i++)
            {
                nodes.Add(i);
            }
            nodes.Shuffle();

            //Create an array of work items for each thread and assign the nodes in a randomized order
            int[][] workItems = new int[numThreads][];
            for (int t = 0; t < numThreads; t++)
            {
                int size = workSize + (t == (numThreads - 1) ? workSizeExtra : 0);
                workItems[t] = new int[size];
                for (int i = 0; i < size; i++)
                {
                    workItems[t][i] = nodes[t * workSize + i];
                }
            }

            //Create our threads use a closure to get our return arrays
            BetweenessCalc[] threadResults = new BetweenessCalc[numThreads];
            //ManualResetEvent[] waitHandles = new ManualResetEvent[numThreads];
            CountdownEvent cde = new CountdownEvent(numThreads);

            for (int t = 0; t < numThreads; t++)
            {
                int tIndex = t;
                //waitHandles[tIndex] = new ManualResetEvent(false);
                BetweenessCalc tResult = new BetweenessCalc(g, workItems[tIndex]);
                threadResults[tIndex] = tResult;
                ThreadPool.QueueUserWorkItem(tResult.ThreadPoolCallback, cde);
            }
            cde.Wait();
            //WaitHandle.WaitAll(waitHandles);

            //Create our betweeness map and sum all of the thread results
            double[] bcMap = new double[numNodes];
            for (int t = 0; t < numThreads; t++)
            {
                var threadR = threadResults[t].BcMap;
                for (int n = 0; n < numNodes; n++)
                {
                    bcMap[n] += threadR[n];
                }
            }

            //divide all by 2 (undirected)
            for (int v = 0; v < numNodes; v++)
            {
                bcMap[v] /= 2f;
            }

            return(bcMap);
        }
예제 #19
0
        public Scattering(LightWeightGraph lwg, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f, List <int> nodeRemovalOrder = null, int numNodesRemoved = 0)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = nodeRemovalOrder;
            _numNodesRemoved  = numNodesRemoved;
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            //bool threaded = Settings.Threading.ThreadHVAT;
            //This is where our estimate for Vat is calculated
            for (int n = 0; n < g.NumNodes; n++)  // This was evaluating g.Numnodes/2
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                //sw.Restart();
                //get the betweeness
                //double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
                //    BetweenessCentrality.BrandesBcNodes(gItter);
                //sw.Stop();
                //Console.WriteLine("{0} {1}ms", n+1, sw.ElapsedMilliseconds);
                //get the index of the maximum
                //int indexMaxBetweeness = betweeness.IndexOfMax();
                //int labelOfMax = gItter.Nodes[indexMaxBetweeness].Label;

                //now we should add it to our list
                int labelOfMax = _nodeRemovalOrder[n];
                //_nodeRemovalOrder.Add(labelOfMax);
                _removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateScattering(_removedNodes);
                if (vat < _minVat)
                {
                    _minVat          = vat;
                    _numNodesRemoved = n + 1;
                }
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
 internal BetweenessCalc(LightWeightGraph g, int[] work)
 {
     _g    = g;
     _work = work;
     BcMap = new double[g.NumNodes];
 }
        public static void adaptive_approximate_betweenness(LightWeightGraph G, int M, int k, List <int> seeds, List <double> btwss)
        {
            int V = G.Nodes.Count(); //int V = G.size();

            bool[] is_seed = new bool[V];
            seeds.Clear();
            btwss.Clear();

            List <List <Tuple <int, double> > > H     = new List <List <Tuple <int, double> > >(); //whg_t H;
            List <Tuple <int, int> >            pairs = new List <Tuple <int, int> >();

            build_betweenness_hypergraph(G, H, M, seeds, pairs);

            // preprocess using H
            double[] degrees = new double[V]; // std::vector<double> degrees(V);
            //std::vector<std::vector<int>> vertex_to_heids(V);
            List <List <int> > vertex_to_heids = new List <List <int> >(V);

            for (int i = 0; i < V; i++)
            {
                vertex_to_heids.Add(new List <int>());
            }
            //std::vector<std::unordered_set<int>> vertices_in_whes(H.size());
            List <HashSet <int> > vertices_in_whes = new List <HashSet <int> >(H.Count);

            for (int i = 0; i < H.Count; i++)
            {
                vertices_in_whes.Add(new HashSet <int>());
            }
            for (int i = 0; i < H.Count; i++)
            {
                //rep(i, H.size()) {
                List <Tuple <int, double> > whe = H[i]; // whe_t & whe = H[i];whe_t & whe = H[i];
                for (int j = 0; j < whe.Count; j++)
                {
                    //rep(j, whe.size()) {
                    int v = whe[j].Item1;
                    degrees[v] += whe[j].Item2;
                    vertex_to_heids[v].Add(i);
                    vertices_in_whes[i].Add(v);
                }
                vertices_in_whes[i].Add(pairs[i].Item1);
                vertices_in_whes[i].Add(pairs[i].Item2);
            }

            PriorityQueue <Tuple <double, int> > pq = new PriorityQueue <Tuple <double, int> >();

            for (int u = 0; u < V; u++)
            {
                pq.push(new Tuple <double, int>(degrees[u], u));
            }
            //rep(u, V) pq.push(std::make_pair(degrees[u], u));
            double[] current_degrees = new double[degrees.Length];
            for (int i = 0; i < current_degrees.Length; i++)
            {
                current_degrees[i] = degrees[i];
            }
            //std::vector<double> current_degrees = degrees;
            //std::vector<bool> vertex_done(V);
            bool[] vertex_done = new bool[V];

            //while (!pq.empty() && (int)seeds.size() < k)
            while (pq.Count > 0 && (int)seeds.Count < k)
            {
                Console.WriteLine("seeds.cont = " + seeds.Count);
                double weight = pq.top().Item1;
                int    u      = pq.top().Item2;
                pq.pop();
                if (vertex_done[u])
                {
                    continue;
                }
                if (Math.Abs(weight - current_degrees[u]) > eps)
                {
                    continue;
                }
                vertex_done[u] = true;

                seeds.Add(u);
                is_seed[u] = true;
                btwss.Add(weight);

                for (int i = 0; i < vertex_to_heids[u].Count; i++)
                {
                    //rep(i, vertex_to_heids[u].size()) {
                    int heid = vertex_to_heids[u][i];
                    List <Tuple <int, double> > whe = H[heid]; // whe_t & whe = H[heid];
                    //whe_t new_whe = make_hyperedge(G, pairs[heid].first, pairs[heid].second, is_seed, vertices_in_whes[heid]);
                    List <Tuple <int, double> > new_whe   = make_hyperedge(G, pairs[heid].Item1, pairs[heid].Item2, is_seed, vertices_in_whes[heid]);
                    SortedDictionary <int, int> make_sure = new SortedDictionary <int, int>();
                    for (int j = 0; j < new_whe.Count; j++)
                    {
                        make_sure[new_whe[j].Item1] = j;
                    }
                    //rep(j, new_whe.size()) make_sure[new_whe[j].first] = j;

                    for (int j = 0; j < whe.Count; j++)
                    {
                        //rep(j, whe.size()) {
                        int v = whe[j].Item1;
                        if (vertex_done[v])
                        {
                            continue;
                        }
                        int myValue;
                        if (!make_sure.TryGetValue(v, out myValue))
                        {
                            make_sure.Add(v, 0);
                        }
                        if (whe[j].Item2 != new_whe[make_sure[v]].Item2)
                        {
                            current_degrees[v] -= whe[j].Item2;
                            current_degrees[v] += new_whe[make_sure[v]].Item2;
                            whe[j]              = new Tuple <int, double>(v, new_whe[make_sure[v]].Item2);
                            //whe[j].Item2 = new_whe[make_sure[v]].Item2;
                        }
                        pq.push(new Tuple <double, int>(current_degrees[v], v));
                    }
                }
            }
        }
        public static List <Tuple <int, double> > make_hyperedge(LightWeightGraph G, int s, int t, bool[] is_seed, HashSet <int> vertices_in_whe)
        {
            List <Tuple <int, double> > whe             = new List <Tuple <int, double> >(); //whe_t whe;
            Dictionary <int, double>    btws            = new Dictionary <int, double>();
            Dictionary <int, int>       dists           = new Dictionary <int, int>();
            Dictionary <int, int>       nums            = new Dictionary <int, int>();
            Dictionary <int, int>       nums_with_seeds = new Dictionary <int, int>();

            bfs(G, s, dists, nums, vertices_in_whe);

            restricted_bfs(G, s, dists, nums_with_seeds, is_seed, vertices_in_whe);

            HashSet <int> added = new HashSet <int>();
            int           qh    = 0;
            List <int>    q     = new List <int>();

            q.Add(t);
            while (qh != (int)q.Count())
            {
                int u = q[qh++];
                if (u == s)
                {
                    continue;
                }

                for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                {
                    //rep(i, G[u].size()) {
                    int v = G.Nodes[u].Edge[i];
                    if (!vertices_in_whe.Contains(v))
                    {
                        continue;                               // if (!vertices_in_whe.count(v)) continue;
                    }
                    if (!dists.ContainsKey(v))
                    {
                        continue;                        //if (!dists.count(v)) continue;
                    }
                    if (dists[v] == dists[u] - 1)
                    {
                        if (!added.Contains(v)) //if (!added.count(v))
                        {
                            q.Add(v);
                            added.Add(v);
                        }
                    }
                    else if (dists[v] == dists[u] + 1)
                    {
                        double k = 0;
                        int    myValue;
                        bool   exists = nums_with_seeds.TryGetValue(u, out myValue);
                        if (exists)
                        {
                            k += (double)nums_with_seeds[u] / nums[v];
                        }
                        else
                        {
                            nums_with_seeds.Add(u, 0);
                            k += (double)nums_with_seeds[u] / nums[v];
                        }
                        if (!nums_with_seeds.TryGetValue(v, out myValue))
                        {
                            nums_with_seeds.Add(v, 0);
                        }
                        if (nums_with_seeds[v] != 0)
                        {
                            if (!is_seed[v])
                            {
                                double myValue3;
                                if (!btws.TryGetValue(v, out myValue3))
                                {
                                    btws.Add(v, 0);
                                }
                                k += btws[v] / nums_with_seeds[v] * nums_with_seeds[u];
                            }
                        }
                        //btws[u] += k;
                        double myValue2;
                        btws.TryGetValue(u, out myValue2);
                        try
                        {
                            btws.Add(u, myValue2);
                        }
                        catch (System.ArgumentException)
                        {
                            btws[u] = myValue2 + k;
                        }
                    }
                }
            }
            foreach (int itm in added)
            //for (auto it = added.begin(); it != added.end(); ++it)
            {
                int u = itm;
                //whe.push_back(std::make_pair(u, btws[*it]));
                double myValue;
                btws.TryGetValue(u, out myValue);
                //whe.Add(new Tuple<int, double>(u, btws[u]));
                whe.Add(new Tuple <int, double>(u, myValue));
            }
            return(whe);
        }
예제 #23
0
        public DikstraProvider2(LightWeightGraph g, int v) : base(g.Nodes.Length)

        {
            int numNodes = g.Nodes.Length;

            numberOfShortestPaths[v] = 1;
            fromList = new List <int> [numNodes]; //List of nodes (we will use this to
            //countPostcessors = new int[numNodes]; //This will hold a count of the number of shortestpaths stemming from

            //we must set each node to infinite distance
            for (int i = 0; i < numNodes; i++)
            {
                g.Nodes[i].NodeWeight = float.MaxValue;
                fromList[i]           = new List <int>(5);
            }
            //now we need to set our node to 0
            g.Nodes[v].NodeWeight = 0.0f;

            //now we need to setup our heap
            ADT.IndexedItem[] items = new IndexedItem[numNodes];
            for (int i = 0; i < numNodes; i++)
            {
                var n = g.Nodes[i];
                items[i] = new IndexedItem(n.Id, n.NodeWeight);
            }
            MinHeapDikstra minHeap = new MinHeapDikstra(numNodes, items[v]);

            //dikstra main
            while (!minHeap.isEmpty())
            {
                var h = minHeap.extractMin();

                int uIndex = h.NodeIndex;
                this.S.Push(uIndex);
                //check all edges
                var u          = g.Nodes[uIndex];
                int uEdgeCount = g.Nodes[uIndex].Count;
                for (int i = 0; i < uEdgeCount; i++)
                {
                    float newWeight    = h.NodeWeight + u.EdgeWeights[i];
                    int   toIndex      = u.Edge[i];
                    var   to           = items[toIndex];
                    float toNodeWeight = to.NodeWeight;
                    if (newWeight < toNodeWeight)
                    {
                        to.NodeWeight = newWeight;
                        fromList[toIndex].Clear();
                        fromList[toIndex].Add(uIndex);
                        numberOfShortestPaths[toIndex] = numberOfShortestPaths[uIndex];
                        if (to.HeapIndex == -1) //first encounter
                        {
                            minHeap.addItem(to);
                        }
                        else
                        {
                            minHeap.decreaseKey(to.HeapIndex);
                        }
                    }
                    else if (newWeight == toNodeWeight)
                    {
                        fromList[toIndex].Add(uIndex);//Add the node
                        numberOfShortestPaths[toIndex] += numberOfShortestPaths[uIndex];
                    }
                }
            }
        }
        /*************************/
        /*  Betweenness  */
        /*************************/


        public static void exact_betweenness(LightWeightGraph G, List <int> seeds, List <double> wbtws)
        {
            int V = G.Nodes.Count(); //int V = G.size();

            for (int i = 0; i < V; i++)
            {
                wbtws.Add(0);
            }
            bool[] is_seed = new bool[V];

            for (int i = 0; i < seeds.Count; i++)
            {
                is_seed[seeds[i]] = true;                                   //.Length
            }
            //rep(i, seeds.size()) is_seed[seeds[i]] = true;

            //wbtws = new double[V];

            for (int s = 0; s < V; s++)
            {
                //rep(s, V) {
                double[] btws = new double[V];

                int[] dists           = new int[V];
                int[] nums            = new int[V];
                int[] nums_with_seeds = new int[V];
                bfs(G, s, dists, nums);

                restricted_bfs(G, s, dists, nums_with_seeds, is_seed);

                int[] out_degree = new int[V];
                for (int u = 0; u < V; u++)
                {
                    //rep(u, V) {
                    for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                    {
                        //rep(i, G[u].size()) {
                        int v = G.Nodes[u].Edge[i]; //int v = G[u][i];
                        if (dists[v] == dists[u] + 1)
                        {
                            out_degree[u]++;
                        }
                    }
                }

                int   qh = 0, qt = 0;
                int[] q = new int[V];
                for (int u = 0; u < V; u++)
                {
                    //rep(u, V)
                    if (out_degree[u] == 0)
                    {
                        q[qt++] = u;
                    }
                }

                while (qh != qt)
                {
                    int u = q[qh++];
                    if (u == s)
                    {
                        continue;
                    }

                    //rep(i, G[u].size()) {
                    for (int i = 0; i < G.Nodes[u].Edge.Count(); i++)
                    {
                        int v = G.Nodes[u].Edge[i]; //int v = G[u][i];
                        if (dists[v] == dists[u] - 1)
                        {
                            if (--out_degree[v] == 0)
                            {
                                q[qt++] = v;
                            }
                        }
                        else if (dists[v] == dists[u] + 1)
                        {
                            double k = 0;
                            k += (double)nums_with_seeds[u] / nums[v];
                            if (nums_with_seeds[v] != 0)
                            {
                                if (!is_seed[v])
                                {
                                    k += btws[v] / nums_with_seeds[v] * nums_with_seeds[u];
                                }
                            }
                            btws[u] += k;
                        }
                    }
                }
                for (int u = 0; u < V; u++)
                {
                    //rep(u, V) {
                    if (is_seed[u])
                    {
                        continue;
                    }
                    wbtws[u] += btws[u];
                }
            }
        }
 internal BetweenessCalc2(LightWeightGraph g, int work)
 {
     _g    = g;
     v     = work;
     delta = new double[g.NumNodes];
 }
예제 #26
0
        //Vat computes given a graph
        public HyperVAT(List <List <int> > overlaps, LightWeightGraph lwg, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //int graphSize = lwg.NumNodes;
            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = new List <int>();
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            bool threaded = Settings.Threading.ThreadHVAT;

            //This is where our estimate for Vat is calculated
            // we start by removing the overlaps one at a time
            double[] betweeness = new double[overlaps.Count];
            for (int n = 0; n < overlaps.Count; n++)
            {
                //get the graph
                _removedNodes = new bool[lwg.NumNodes];
                for (int w = 0; w < overlaps[n].Count; w++)
                {
                    int removed = overlaps[n][w];
                    _removedNodes[removed] = true;
                }
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                //sw.Restart();
                //get the betweeness

                //double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
                //    BetweenessCentrality.BrandesBcNodes(gItter);
                //sw.Stop();
                //Console.WriteLine("{0} {1}ms", n+1, sw.ElapsedMilliseconds);
                //get the index of the maximum
                //int indexMaxBetweeness = betweeness.IndexOfMax();
                //int labelOfMax = gItter.Nodes[indexMaxBetweeness].Label;

                //now we should add it to our list
                //_nodeRemovalOrder.Add(labelOfMax);
                //_removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateVAT(_removedNodes);
                betweeness[n] = vat;
                if (vat < _minVat)
                {
                    _minVat           = vat;
                    _nodeRemovalOrder = overlaps[n];
                    _numNodesRemoved  = overlaps[n].Count;
                }
            }

            // This is the 2D node removal-------------------------------------
            for (int i = 0; i < overlaps.Count; i++)
            {
                for (int j = i + 1; j < overlaps.Count; j++)
                {
                    _removedNodes = new bool[lwg.NumNodes];
                    List <int> remNodeCombined = overlaps[i].Union(overlaps[j]).ToList();
                    remNodeCombined.Sort();

                    for (int w = 0; w < remNodeCombined.Count; w++)
                    {
                        int removed = remNodeCombined[w];
                        _removedNodes[removed] = true;
                        LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                        double           vat    = CalculateVAT(_removedNodes);
                        if (vat < _minVat)
                        {
                            _minVat           = vat;
                            _nodeRemovalOrder = remNodeCombined;
                            _numNodesRemoved  = remNodeCombined.Count;
                        }
                    }
                }
            }

            //-------------------------------
            //This is the 3d node removal ----------------------------
            for (int i = 0; i < overlaps.Count; i++)
            {
                for (int j = i + 1; j < overlaps.Count; j++)
                {
                    for (int k = 0; k < overlaps.Count; k++)
                    {
                        _removedNodes = new bool[lwg.NumNodes];
                        List <int> remNodeCombined = overlaps[i].Union(overlaps[j]).Union(overlaps[k]).ToList();
                        remNodeCombined.Sort();

                        for (int w = 0; w < remNodeCombined.Count; w++)
                        {
                            int removed = remNodeCombined[w];
                            _removedNodes[removed] = true;
                            LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                            double           vat    = CalculateVAT(_removedNodes);
                            if (vat < _minVat)
                            {
                                _minVat           = vat;
                                _nodeRemovalOrder = remNodeCombined;
                                _numNodesRemoved  = remNodeCombined.Count;
                            }
                        }
                    }
                }
            }

            /* //4d
             * for (int i = 0; i < overlaps.Count; i++)
             * {
             * for (int j = i + 1; j < overlaps.Count; j++)
             * {
             *     for (int k = 0; k < overlaps.Count; k++)
             *     {
             *         for (int h = 0; h < overlaps.Count; h++)
             *         {
             *
             *         _removedNodes = new bool[lwg.NumNodes];
             *         List<int> remNodeCombined = overlaps[i].Union(overlaps[j]).Union(overlaps[k]).Union(overlaps[h]).ToList();
             *         remNodeCombined.Sort();
             *
             *             for (int w = 0; w < remNodeCombined.Count; w++)
             *             {
             *                 int removed = remNodeCombined[w];
             *                 _removedNodes[removed] = true;
             *                 LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
             *                 double vat = CalculateVAT(_removedNodes);
             *                 if (vat < _minVat)
             *                 {
             *                     _minVat = vat;
             *                     _nodeRemovalOrder = remNodeCombined;
             *                     _numNodesRemoved = remNodeCombined.Count;
             *                 }
             *
             *             }
             *         }
             *     }
             * }
             * }
             */
            //Now we need to set up S to reflect the actual minimum
            int indexMinBetweeness = betweeness.IndexOfMin();

            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }

            //_nodeRemovalOrder.Add(3);
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
        //construct a subgraph using some exclusion rules
        public LightWeightGraph(LightWeightGraph lwg, bool[] S)
            : base(DataType.Graph)
        {
            int sSize = S.Count(c => c);

            //Setup our node array to be filled
            Nodes      = new LightWeightNode[lwg.NumNodes - sSize];
            NumNodes   = Nodes.Length;
            IsWeighted = lwg.IsWeighted;

            int nodeID = 0;

            int[] oldIDToNewID = new int[lwg.NumNodes];
            int[] oldLabel     = new int[NumNodes];
            //Now we need to itterate over each node in lwg
            for (int v = 0; v < lwg.NumNodes; v++)
            {
                if (!S[v])
                {
                    oldIDToNewID[v]  = nodeID;
                    oldLabel[nodeID] = lwg.Nodes[v].Label;
                    nodeID++;
                }
            }

            List <int>[]    edgesList      = new List <int> [NumNodes];
            List <double>[] edgeWeightList = new List <double> [NumNodes];
            for (int i = 0; i < lwg.NumNodes - sSize; i++)
            {
                edgesList[i]      = new List <int>();
                edgeWeightList[i] = new List <double>();
            }

            //now we should add our edges
            nodeID = 0;
            for (int v = 0; v < lwg.NumNodes; v++)
            {
                if (!S[v]) //if this is not a removed node we should add the edges
                {
                    var edges       = lwg.Nodes[v].Edge;
                    var edgeWeights = lwg.Nodes[v].EdgeWeights;
                    //Go through all of the edges and only add those not removed
                    for (int u = 0; u < lwg.Nodes[v].Count; u++)
                    {
                        int edgeTo = edges[u];
                        if (!S[edgeTo]) //this edge is still valid so we should add it
                        {
                            edgesList[nodeID].Add(oldIDToNewID[edgeTo]);
                            if (lwg.IsWeighted)
                            {
                                edgeWeightList[nodeID].Add(edgeWeights[u]);
                            }
                        }
                    }
                    nodeID++;
                }
            }

            for (int i = 0; i < NumNodes; i++)
            {
                Nodes[i] = new LightWeightNode(i, oldLabel[i], lwg.IsWeighted, edgesList[i], (IsWeighted) ? edgeWeightList[i] : null);
            }
        }
        //Vat computes given a graph
        public HyperVATDeg(List <List <int> > overlaps, LightWeightGraph lwg, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = new bool[lwg.NumNodes];
            _nodeRemovalOrder = new List <int>();
            _reassignNodes    = reassignNodes;

            //We will make a copy of the graph and set the label equal to the index
            g = new LightWeightGraph(lwg, _removedNodes);
            for (int i = 0; i < g.NumNodes; i++)
            {
                g.Nodes[i].Label = i;
            }

            if (lwg.NumNodes <= 2)
            {
                return;
            }

            bool threaded = Settings.Threading.ThreadHVAT;

            int[] overlapsSize = new int[overlaps.Count];
            for (int i = 0; i < overlaps.Count; i++)
            {
                overlapsSize[i] = overlaps[i].Count;
            }

            //This is where our estimate for Vat is calculated
            for (int n = 0; n < 15; n++)
            {
                //get the graph
                LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
                //sw.Restart();
                //get the betweeness
                //double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
                BetweenessCentrality.BrandesBcNodes(gItter);
                //sw.Stop();
                //Console.WriteLine("{0} {1}ms", n+1, sw.ElapsedMilliseconds);
                //get the index of the maximum
                int maxsize            = 0;
                int indexMaxBetweeness = 0;
                for (int i = 0; i < overlapsSize.Length; i++)
                {
                    if (overlapsSize[i] > maxsize)
                    {
                        maxsize            = overlapsSize[i];
                        indexMaxBetweeness = i;
                    }
                }

                //int indexMaxBetweeness = overlapsSize.IndexOfMax();
                int labelOfMax = gItter.Nodes[indexMaxBetweeness].Label;

                //now we should add it to our list
                // look in overlaps for a set that contains labelOfMax
                //for (int i = 0; i < overlaps.Count; i++)
                // {
                //    if (overlaps[i].Contains(labelOfMax))
                //    {
                _nodeRemovalOrder = _nodeRemovalOrder.Union(overlaps[indexMaxBetweeness]).ToList();
                for (int j = 0; j < overlaps[indexMaxBetweeness].Count; j++)
                {
                    _removedNodes[overlaps[indexMaxBetweeness][j]] = true;
                }
                overlapsSize[indexMaxBetweeness] = 0;
                //     }
                // }
                // _nodeRemovalOrder.Add(labelOfMax);
                // _removedNodes[labelOfMax] = true;
                //calculate vat and update the record
                double vat = CalculateVAT(_removedNodes);
                if (vat < _minVat)
                {
                    _minVat          = vat;
                    _numNodesRemoved = _nodeRemovalOrder.Count;
                }
            }

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }
 public LWGWithNodeDescriptors(NetVertDesciption[] descriptors, LightWeightGraph lwg)
 {
     Descriptors = descriptors;
     Lwg         = lwg;
 }
예제 #30
0
        //Vat computes given a graph
        public VATContrived(LightWeightGraph lwg, bool[] removedNodes, List <int> nodeRemovalOrder, int numNodesRemoved, bool reassignNodes = true, double alpha = 1.0f, double beta = 0.0f)
        {
            //set our alpha and beta variables
            Alpha = alpha; Beta = beta;

            //first we set our variables up
            _removedNodes     = removedNodes;
            _nodeRemovalOrder = nodeRemovalOrder;
            _reassignNodes    = reassignNodes;
            _numNodesRemoved  = numNodesRemoved;

            //We will make a copy of the graph and set the label equal to the index

            g = new LightWeightGraph(lwg);

            /* for (int i = 0; i < g.NumNodes; i++)
             *   g.Nodes[i].Label = i;
             *
             * if (lwg.NumNodes <= 2)
             *   return;
             *
             * bool threaded = Settings.Threading.ThreadHVAT;
             * //This is where our estimate for Vat is calculated
             * for (int n = 0; n < g.NumNodes / 2; n++)  // this was 32, I think a typo?
             * {
             *   //get the graph
             *   LightWeightGraph gItter = new LightWeightGraph(g, _removedNodes);
             *   //sw.Restart();
             *   //get the betweeness
             *   double[] betweeness = (threaded) ? BetweenessCentrality.ParallelBrandesBcNodes(gItter) :
             *       BetweenessCentrality.BrandesBcNodes(gItter);
             *   //sw.Stop();
             *   //Console.WriteLine("{0} {1}ms", n+1, sw.ElapsedMilliseconds);
             *   //get the index of the maximum
             *   int indexMaxBetweeness = betweeness.IndexOfMax();
             *   int labelOfMax = gItter.Nodes[indexMaxBetweeness].Label;
             *
             *   //now we should add it to our list
             *   _nodeRemovalOrder.Add(labelOfMax);
             *   _removedNodes[labelOfMax] = true;
             *   //calculate vat and update the record
             *   double vat = CalculateVAT(_removedNodes);
             *   if (vat < _minVat)
             *   {
             *       _minVat = vat;
             *       _numNodesRemoved = n + 1;
             *   }
             * }
             *
             */
            _minVat = CalculateVAT(_removedNodes);

            //Now we need to set up S to reflect the actual minimum
            for (int i = 0; i < _removedNodes.Length; i++)
            {
                _removedNodes[i] = false;
            }
            for (int i = 0; i < _numNodesRemoved; i++)
            {
                _removedNodes[_nodeRemovalOrder[i]] = true;
            }
        }