NeoPZ
diamtr.cpp
Go to the documentation of this file.
1 #include "sloan.h"
2 
4 int diamtr_ (int64_t *n, int64_t *e2, int64_t *adj, int64_t *
5  xadj, int64_t *mask, int64_t *ls, int64_t *xls, int64_t *hlevel, int64_t *snode, int64_t *nc)
6 {
7  /* System generated locals */
8  int64_t i__1, i__2;
9  /* Local variables */
10  static int64_t node, i, j, enode, depth, width, hsize, istop, jstop, istrt, jstrt, degree, mindeg, ewidth, sdepth;
11 
12 /* INPUT: */
13 /* ------ */
14 /* N - The total number of nodes in the graph */
15 /* E2 - Twice the number of edges in the graph = XADJ(N+1)-1 */
16 /* ADJ - Adjacency list for all nodes in the graph */
17 /* - List of length 2E where E is the number of edges in */
18 /* the graph and 2E = XADJ(N+1)-1 */
19 /* XADJ - Index vector for ADJ */
20 /* - Nodes adjacent to node I are found in ADJ(J), where */
21 /* J = XADJ(I),XADJ(I)+1, ..., XADJ(I+1)-1 */
22 /* - Degree of node I given by XADJ(I=1)-XADJ(I) */
23 /* MASK - Masking vector for graph */
24 /* - Visible nodes have MASK = 0, node invisible otherwise */
25 /* LS - Undefined */
26 /* XLS - Undefined */
27 /* HLEVEL - Undefined */
28 /* SNODE - Undefined */
29 /* NC - Undefined */
30 
31 /* OUTPUT: */
32 /* ------- */
33 /* N - Unchanged */
34 /* E2 - Unchanged */
35 /* ADJ - Unchanged */
36 /* XADJ - Unchanged */
37 /* MASK - List of distances of nodes from the end node */
38 /* LS - List of nodes in the component */
39 /* XLS - Not used */
40 /* HLEVEL - Not used */
41 /* SNODE - Starting node for numbering */
42 /* NC - The number of nodes in this component of graph */
43 
44 /* SUBROUTINES CALLED: ROOTLS, ISORTI */
45 /* ------------------- */
46 /* NOTE: SNODE and ENODE define a pseudo-diameter */
47 
48 /* PROGRAMMER: Scott Sloan */
49 /* ----------- */
50 
51 /* LAST MODIFIED: 10 March 1989 Scott Sloan */
52 /* ***********************************************************************
53  */
54 
55 
56 /* Choose first guess for starting node by min degree */
57 /* Ignore nodes that are invisible (MASK NE 0) */
58 
59  /* Parameter adjustments */
60  --hlevel;
61  --xls;
62  --ls;
63  --mask;
64  --xadj;
65  --adj;
66 
67  /* Function Body */
68  mindeg = *n;
69  i__1 = *n;
70  for (i = 1; i <= i__1; ++i)
71  {
72  if (mask[i] == 0)
73  {
74  degree = xadj[i + 1] - xadj[i];
75  if (degree < mindeg)
76  {
77  *snode = i;
78  mindeg = degree;
79  }
80  }
81 /* L10: */
82  }
83 
84 /* Generate level structure for node with min degree */
85 
86  i__1 = *n + 1;
87  rootls_ (n, snode, &i__1, e2, &adj[1], &xadj[1], &mask[1], &ls[1], &xls[1],
88  &sdepth, &width);
89 
90 /* Store number of nodes in this component */
91 
92  *nc = xls[sdepth + 1] - 1;
93 
94 /* Iterate to find start and end nodes */
95 
96 L15:
97 
98 /* Store list of nodes that are at max distance from starting node */
99 /* Store their degrees in XLS */
100  hsize = 0;
101  istrt = xls[sdepth];
102  istop = xls[sdepth + 1] - 1;
103  i__1 = istop;
104  for (i = istrt; i <= i__1; ++i)
105  {
106  node = ls[i];
107  ++hsize;
108  hlevel[hsize] = node;
109  xls[node] = xadj[node + 1] - xadj[node];
110 /* L20: */
111  }
112 
113 /* Sort list of nodes in ascending sequence of their degree */
114 /* Use insertion sort algorithm */
115  if (hsize > 1)
116  {
117  isorti_ (&hsize, &hlevel[1], n, &xls[1]);
118  }
119 
120 /* Remove nodes with duplicate degrees */
121 
122  istop = hsize;
123  hsize = 1;
124  degree = xls[hlevel[1]];
125  i__1 = istop;
126  for (i = 2; i <= i__1; ++i)
127  {
128  node = hlevel[i];
129  if (xls[node] != degree)
130  {
131  degree = xls[node];
132  ++hsize;
133  hlevel[hsize] = node;
134  }
135 /* L25: */
136  }
137 
138 /* Loop over nodes in skrunken level */
139 
140  ewidth = *nc + 1;
141  i__1 = hsize;
142  for (i = 1; i <= i__1; ++i)
143  {
144  node = hlevel[i];
145 
146 /* Form rooted level structures for each node in skrunken level */
147 
148  rootls_ (n, &node, &ewidth, e2, &adj[1], &xadj[1], &mask[1], &ls[1], &
149  xls[1], &depth, &width);
150  if (width < ewidth)
151  {
152 
153 /* Level structure was not aborted during assembly */
154 
155  if (depth > sdepth)
156  {
157 
158 /* Level structure of greater depth found */
159 /* Store new starting node, new max depth, and begin */
160 /* a new iteration */
161 
162  *snode = node;
163  sdepth = depth;
164  goto L15;
165  }
166 /* Level struture width for this end node is smallest so far */
167 /* store end node and new min width */
168 
169  enode = node;
170  ewidth = width;
171  }
172 /* L30: */
173  }
174 
175 /* Generate level structure rooted at end node if necessary */
176 
177  if (node != enode)
178  {
179  i__1 = *nc + 1;
180  rootls_ (n, &enode, &i__1, e2, &adj[1], &xadj[1], &mask[1], &ls[1], &
181  xls[1], &depth, &width);
182  }
183 /* Store distances of each node from end node */
184 
185  i__1 = depth;
186  for (i = 1; i <= i__1; ++i)
187  {
188  jstrt = xls[i];
189  jstop = xls[i + 1] - 1;
190  i__2 = jstop;
191  for (j = jstrt; j <= i__2; ++j)
192  {
193  mask[ls[j]] = i - 1;
194 /* L40: */
195  }
196 /* L50: */
197  }
198  return 0;
199 }
int diamtr_(int64_t *n, int64_t *e2, int64_t *adj, int64_t *xadj, int64_t *mask, int64_t *ls, int64_t *xls, int64_t *hlevel, int64_t *snode, int64_t *nc)
Purpose: Find nodes which define a pseudo-diameter of a graph and store distances from end node...
Definition: diamtr.cpp:4
int rootls_(int64_t *, int64_t *root, int64_t *maxwid, int64_t *, int64_t *adj, int64_t *xadj, int64_t *mask, int64_t *ls, int64_t *xls, int64_t *depth, int64_t *width)
Definition: rootls.cpp:4
void degree(int root, int adj_num, int adj_row[], int adj[], int mask[], int deg[], int *iccsze, int ls[], int node_num)
Definition: rcm.cpp:875
int isorti_(int64_t *nl, int64_t *list, int64_t *, int64_t *key)
Definition: isorti.cpp:4