-
Notifications
You must be signed in to change notification settings - Fork 8
/
knottycentrality.m
162 lines (103 loc) · 3.7 KB
/
knottycentrality.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
function [nodes, kc] = knottycentrality(CIJ,compact)
% Attempts to find the sub-graph of CIJ with the highest value for
% knotty-centrality. Carries out a series of exhaustive searches on
% subsets of the nodes ranked by "indirect" betweenness centrality, then
% carries out a phase of hill-climbing to see whether the sub-graph can
% be improved by adding further nodes. Uses the Brain Connectivity
% Toolbox (Rubinov & Sporns, 2010) for betweenness centrality
%
% nodes = the sub-graph found
% kc = its knotty-centredness
% compact = 1 if compact knotty-centrality to be used, 0 otherwise
%
% Written by Murray Shanahan, October 2011
% REF: Shanahan M, Wildie M. Knotty-centrality: finding the connective core of a
% complex network. PLoS One. 2012;7(5):e36579. Epub 2012 May 9. PubMed PMID:
% 22590571; PubMed Central PMCID: PMC3348887.
N = length(CIJ);
CIJ = (CIJ > 0).*1; % binarise matrix - all non-zero weights become 1s
% Exhastive search phase
Exh = 10; % number of nodes for exhaustive search (2^Exh combinations)
Exh = min(Exh,N);
BC = betweenness_centrality(CIJ); % betweenness centralities (Rubinov & Sporns)
BC = BC/sum(BC); % normalise wrt total betweenness centrality
% Calculate indirect betweenness centrality
BC2 = zeros(1,N);
for i = 1:N
BC2(i) = BC(i)+(sum(CIJ(i,:).*BC(i)))+(sum(CIJ(:,i)'.*BC(i)));
end
[~, IxBC] = sort(BC2,'descend'); % rank nodes
nodes = [];
improving = 1;
while improving
L = length(nodes);
nodes_left = IxBC;
nodes_left = nodes_left(~ismember(nodes_left,nodes));
choices = nodes_left(1:min(Exh,end));
[nodes, kc] = BestPerm(nodes,choices,CIJ,compact,BC);
improving = length(nodes) > L;
end
% Hill climbing phase
nodes_left = 1:N;
nodes_left = nodes_left(~ismember(nodes_left,nodes));
improving = 1;
while improving && ~isempty(nodes_left)
best_kc = 0;
for i = 1:length(nodes_left)
node = nodes_left(i);
nodes2 = [nodes, node];
kc2 = KnottyCentrality(CIJ,nodes2,compact,BC);
if kc2 > best_kc
best_kc = kc2;
best_node = node;
end
end
if best_kc > kc
kc = best_kc;
nodes = [nodes, best_node];
nodes_left = nodes_left(nodes_left ~= best_node);
else
improving = 0;
end
end
end
function [nodes,kc] = BestPerm(given,choices,CIJ,compact,BC)
% Carries out exhaustive search to find a permutation of nodes in
% "choices" that when added to the nodes in "given" yields the highest
% value of knotty-centrality
if ~isempty(choices)
choices2 = choices(2:end);
new = choices(1);
[nodes1,kc1] = BestPerm([given, new],choices2,CIJ,compact,BC);
[nodes2,kc2] = BestPerm(given,choices2,CIJ,compact,BC);
if kc1 > kc2
nodes = nodes1;
kc = kc1;
else
nodes = nodes2;
kc = kc2;
end
else
nodes = given;
kc = KnottyCentrality(CIJ,nodes,compact,BC);
end
end
function kc = KnottyCentrality(CIJ,nodes,compact,BC)
% Returns knotty-centrality of the subgraph of CIJ comprising only
% "nodes" and the associated connections
if length(nodes) < 3
kc = 0;
else
CIJ = (CIJ > 0).*1; % binarise matrix
N = length(CIJ); % nodes in overall graph
M = length(nodes); % nodes in subgraph
BCtot = sum(BC(nodes));
p = ((N-M)/N); % proportion of nodes not in subgraph
RC = sum(sum(CIJ(nodes,nodes)))/(M*(M-1)); % density of subgraph
if compact
kc = p*BCtot*RC; % compact knotty-centrality
else
kc = BCtot*RC; % knotty-centrality
end
end
end