-
Notifications
You must be signed in to change notification settings - Fork 1
/
root_find.m
151 lines (137 loc) · 4.06 KB
/
root_find.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
function [ root, level_num, level_row, level ] = root_find ( root, ...
adj_num, adj_row, adj, mask, node_num )
%*****************************************************************************80
%
%% ROOT_FIND finds a pseudo-peripheral node.
%
% Discussion:
%
% The diameter of a graph is the maximum distance (number of edges)
% between any two nodes of the graph.
%
% The eccentricity of a node is the maximum distance between that
% node and any other node of the graph.
%
% A peripheral node is a node whose eccentricity equals the
% diameter of the graph.
%
% A pseudo-peripheral node is an approximation to a peripheral node;
% it may be a peripheral node, but all we know is that we tried our
% best.
%
% The routine is given a graph, and seeks pseudo-peripheral nodes,
% using a modified version of the scheme of Gibbs, Poole and
% Stockmeyer. It determines such a node for the section subgraph
% specified by MASK and ROOT.
%
% The routine also determines the level structure associated with
% the given pseudo-peripheral node; that is, how far each node
% is from the pseudo-peripheral node. The level structure is
% returned as a list of nodes LS, and pointers to the beginning
% of the list of nodes that are at a distance of 0, 1, 2, ...,
% NODE_NUM-1 from the pseudo-peripheral node.
%
% Licensing:
%
% This code is distributed under the GNU LGPL license.
%
%
% Parameters:
%
% Input, integer ROOT a node in the the component of the graph for
% which a pseudo-peripheral node is sought.
%
% Input, integer ADJ_NUM, the number of adjacency entries.
%
% Input, integer ADJ_ROW(NODE_NUM+1). Information about row I is stored
% in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
%
% Input, integer ADJ(ADJ_NUM), the adjacency structure.
% For each row, it contains the column indices of the nonzero entries.
%
% Input, integer MASK(NODE_NUM), specifies a section subgraph. Nodes
% for which MASK is zero are ignored by FNROOT.
%
% Input, integer NODE_NUM, the number of nodes.
%
% Output, integer ROOT, the pseudo-peripheral node obtained.
%
% Output, integer LEVEL_NUM, is the number of levels in the level structure
% rooted at the node ROOT.
%
% Output, integer LEVEL_ROW(NODE_NUM+1), LEVEL(NODE_NUM), the
% level structure array pair containing the level structure found.
%
%
% Determine the level structure rooted at ROOT.
%
[ mask, level_num, level_row, level ] = level_set ( root, adj_num, ...
adj_row, adj, mask, node_num );
%
% Count the number of nodes in this level structure.
%
iccsze = level_row(level_num+1) - 1;
%
% Extreme case:
% A complete graph has a level set of only a single level.
% Every node is equally good (or bad).
%
if ( level_num == 1 )
return
end
%
% Extreme case:
% A "line graph" 0--0--0--0--0 has every node in its only level.
% By chance, we've stumbled on the ideal root.
%
if ( level_num == iccsze )
return
end
%
% Pick any node from the last level that has minimum degree
% as the starting point to generate a new level set.
%
while ( true )
mindeg = iccsze;
jstrt = level_row(level_num);
root = level(jstrt);
if ( jstrt < iccsze )
for j = jstrt : iccsze
node = level(j);
ndeg = 0;
kstrt = adj_row(node);
kstop = adj_row(node+1)-1;
for k = kstrt : kstop
nabor = adj(k);
if ( 0 < mask(nabor) )
ndeg = ndeg+1;
end
end
if ( ndeg < mindeg )
root = node;
mindeg = ndeg;
end
end
end
%
% Generate the rooted level structure associated with this node.
%
[ mask, level_num2, level_row, level ] = level_set ( root, adj_num, ...
adj_row, adj, mask, node_num );
%
% If the number of levels did not increase, accept the new ROOT.
%
if ( level_num2 <= level_num )
break
end
level_num = level_num2;
%
% In the unlikely case that ROOT is one endpoint of a line graph,
% we can exit now.
%
if ( iccsze <= level_num )
break
end
end
return
end