FormationControlSimulation/SOURCE/networks-toolbox/edgeBetweenness.m

118 lines
3.8 KiB
Matlab
Raw Normal View History

2019-06-17 14:31:50 +07:00
% 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