% Edge betweenness routine, based on the number of % shortest paths going through an edge. % Source: Newman, Girvan, "Finding and evaluating community structure in networks" % Note: Valid for undirected graphs only. % % INPUTs: edge list, mx3, m - number of edges % OUTPUTs: w - betweenness per edge, mx3 % % Other routines used: adj2edgeL.m, numNodes.m, numEdges.m, kneighbors.m % GB: last modified, Sep 29, 2012 function ew = edgeBetweenness(adj) el=adj2edgeL(adj); % the corresponding edge list n = numNodes(adj); % number of nodes m = numEdges(adj); % number of edges ew = zeros(size(el,1),3); % edge betweenness - output for s=1:n % across all (source) nodes % compute the distances and weights starting at source node i d=inf(n,1); w=inf(n,1); d(s)=0; w(s)=1; % source node distance and weight queue=[s]; % add to queue visited=[]; while not(isempty(queue)) j=queue(1); % pop first member visited=[visited j]; neigh=kneighbors(adj,j,1); % find all adjacent nodes, 1 step away for x=1:length(neigh) % add to queue if unvisited nei=neigh(x); if isempty(find(visited==nei)) && isempty(find(queue==nei)); queue=[queue nei]; end end for x=1:length(neigh) nei=neigh(x); if d(nei)==inf % not assigned yet d(nei)=1+d(j); w(nei)=w(j); elseif d(nei)<inf && d(nei)==d(j)+1 % assigned already, add the new path w(nei)=w(nei)+w(j); elseif d(nei)<inf && d(nei)<d(j)+1 'do nothing'; end end queue=queue(2:length(queue)); % remove the first element end eww = zeros(size(el,1),3); % edge betweenness for every source node (iteration) % find every leaf - no path from "s" to other vertices goes through the leaf leaves = find(d==max(d)); % farthest away from source for l=1:length(leaves) leaf=leaves(l); neigh=kneighbors(adj,leaf,1); nei2rem=[]; for x=1:length(neigh) if isempty(find(leaves==neigh(x))); nei2rem=[nei2rem neigh(x)]; end end neigh=nei2rem; % remove other leaves among the neighbors for x=1:length(neigh) indi=find(el(:,1)==neigh(x)); indj=find(el(:,2)==leaf); indij=intersect(indi,indj); % should be only one element at the intersection eww(indij,3)=w(neigh(x))/w(leaf); end end dsort=unique(d); dsort=-sort(-dsort); % reverse sort of unique distance values for x=1:length(dsort) leaves=find(d==dsort(x)); for l=1:length(leaves) leaf=leaves(l); neigh=kneighbors(adj,leaf,1); up_neigh=[]; down_neigh=[]; for x=1:length(neigh) if d(neigh(x))<d(leaf) up_neigh=[up_neigh neigh(x)]; elseif d(neigh(x))>d(leaf) down_neigh=[down_neigh neigh(x)]; end end sum_down_edges=0; for x=1:length(down_neigh) indi=find(el(:,1)==leaf); indj=find(el(:,2)==down_neigh(x)); indij=intersect(indi,indj); sum_down_edges=sum_down_edges+eww(indij,3); end for x=1:length(up_neigh) indi=find(el(:,1)==up_neigh(x)); indj=find(el(:,2)==leaf); indij=intersect(indi,indj); eww(indij,3)=w(up_neigh(x))/w(leaf)*(1+sum_down_edges); end end end for e=1:size(ew,1); ew(e,3)=ew(e,3)+eww(e,3); end end for e=1:size(ew,1) ew(e,1)=el(e,1); ew(e,2)=el(e,2); ew(e,3)=ew(e,3)/n/(n-1); % normalize by the total number of paths end