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; } } }
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)); }
//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; } } } }
//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 }
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); } } } }
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); }
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); } }
//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); }
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); }
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]; }
//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; }
//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; } }