Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
kkutils.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <neatogen/bfs.h>
12#include <neatogen/dijkstra.h>
13#include <neatogen/kkutils.h>
14#include <stdlib.h>
15#include <math.h>
16#include <util/alloc.h>
17#include <util/sort.h>
18
19size_t common_neighbors(vtx_data *graph, int u, int *v_vector) {
20 // count number of common neighbors of 'v_vector' and 'u'
21 int neighbor;
22 size_t num_shared_neighbors = 0;
23 for (size_t j = 1; j < graph[u].nedges; j++) {
24 neighbor = graph[u].edges[j];
25 if (v_vector[neighbor] > 0) {
26 // a shared neighbor
27 num_shared_neighbors++;
28 }
29 }
30 return num_shared_neighbors;
31}
32void fill_neighbors_vec_unweighted(vtx_data * graph, int vtx, int *vtx_vec)
33{
34 /* a node is NOT a neighbor of itself! */
35 /* unlike the other version of this function */
36 for (size_t j = 1; j < graph[vtx].nedges; j++) {
37 vtx_vec[graph[vtx].edges[j]] = 1;
38 }
39}
40
41void empty_neighbors_vec(vtx_data * graph, int vtx, int *vtx_vec)
42{
43 /* a node is NOT a neighbor of itself! */
44 /* unlike the other version ofthis function */
45 for (size_t j = 1; j < graph[vtx].nedges; j++) {
46 vtx_vec[graph[vtx].edges[j]] = 0;
47 }
48}
49
50/* compute_apsp_dijkstra:
51 * Assumes the graph has weights
52 */
54{
55 int i;
56
57 DistType *storage = gv_calloc((size_t)(n * n), sizeof(DistType));
58 DistType **dij = gv_calloc(n, sizeof(DistType*));
59 for (i = 0; i < n; i++)
60 dij[i] = storage + i * n;
61
62 for (i = 0; i < n; i++) {
63 dijkstra(i, graph, n, dij[i]);
64 }
65 return dij;
66}
67
69{
70 /* compute all pairs shortest path */
71 /* for unweighted graph */
72 int i;
73 DistType *storage = gv_calloc((size_t)(n * n), sizeof(DistType));
74
75 DistType **dij = gv_calloc(n, sizeof(DistType*));
76 for (i = 0; i < n; i++) {
77 dij[i] = storage + i * n;
78 }
79 for (i = 0; i < n; i++) {
80 bfs(i, graph, n, dij[i]);
81 }
82 return dij;
83}
84
86{
87 if (graph->ewgts)
89 else
90 return compute_apsp_simple(graph, n);
91}
92
94 DistType **Dij;
95 /* compute all-pairs-shortest-path-length while weighting the graph */
96 /* so high-degree nodes are distantly located */
97
98 float *old_weights = graph[0].ewgts;
99
102 restore_old_weights(graph, n, old_weights);
103 return Dij;
104}
105
106
107/**********************/
108/* */
109/* Quick Sort */
110/* */
111/**********************/
112
113double distance_kD(double **coords, int dim, int i, int j)
114{
115 /* compute a k-D Euclidean distance between 'coords[*][i]' and 'coords[*][j]' */
116 double sum = 0;
117 int k;
118 for (k = 0; k < dim; k++) {
119 sum +=
120 (coords[k][i] - coords[k][j]) * (coords[k][i] - coords[k][j]);
121 }
122 return sqrt(sum);
123}
124
125static int fcmpf(const void *a, const void *b, void *context) {
126 const int *ip1 = a;
127 const int *ip2 = b;
128 float *fvals = context;
129 float d1 = fvals[*ip1];
130 float d2 = fvals[*ip2];
131 if (d1 < d2) {
132 return -1;
133 }
134 if (d1 > d2) {
135 return 1;
136 }
137 return 0;
138}
139
140void quicksort_placef(float *place, int *ordering, int first, int last)
141{
142 if (first < last) {
143 gv_sort(ordering + first, last - first + 1, sizeof(ordering[0]), fcmpf, place);
144 }
145}
146
147static int cmp(const void *a, const void *b, void *context) {
148 const int *x = a;
149 const int *y = b;
150 const double *place = context;
151
152 if (place[*x] < place[*y]) {
153 return -1;
154 }
155 if (place[*x] > place[*y]) {
156 return 1;
157 }
158 return 0;
159}
160
161void quicksort_place(double *place, int *ordering, int size) {
162 gv_sort(ordering, size, sizeof(ordering[0]), cmp, place);
163}
164
166{
167 /* Reweight graph so that high degree nodes will be separated */
168
169 int i;
170 size_t nedges = 0;
171 int *vtx_vec = gv_calloc(n, sizeof(int));
172 size_t deg_i, deg_j;
173 int neighbor;
174
175 for (i = 0; i < n; i++) {
176 nedges += graph[i].nedges;
177 }
178 float *weights = gv_calloc(nedges, sizeof(float));
179
180 for (i = 0; i < n; i++) {
181 graph[i].ewgts = weights;
183 deg_i = graph[i].nedges - 1;
184 for (size_t j = 1; j <= deg_i; j++) {
185 neighbor = graph[i].edges[j];
186 deg_j = graph[neighbor].nedges - 1;
187 weights[j] =
188 (float)(deg_i + deg_j - 2 * common_neighbors(graph, neighbor, vtx_vec));
189 }
190 empty_neighbors_vec(graph, i, vtx_vec);
191 weights += graph[i].nedges;
192 }
193 free(vtx_vec);
194}
195
196void restore_old_weights(vtx_data * graph, int n, float *old_weights)
197{
198 int i;
199 free(graph[0].ewgts);
200 graph[0].ewgts = NULL;
201 if (old_weights != NULL) {
202 for (i = 0; i < n; i++) {
203 graph[i].ewgts = old_weights;
204 old_weights += graph[i].nedges;
205 }
206 }
207}
static agxbuf last
last message
Definition agerror.c:29
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
void bfs(int vertex, vtx_data *graph, int n, DistType *dist)
Definition bfs.c:25
static void dijkstra(Dict_t *Q, Agraph_t *G, Agnode_t *n)
Definition dijkstra.c:188
void free(void *)
node NULL
Definition grammar.y:163
Agraph_t * graph(char *name)
Definition gv.cpp:30
static DistType ** compute_apsp_dijkstra(vtx_data *graph, int n)
Definition kkutils.c:53
static DistType ** compute_apsp_simple(vtx_data *graph, int n)
Definition kkutils.c:68
void compute_new_weights(vtx_data *graph, int n)
Definition kkutils.c:165
void quicksort_place(double *place, int *ordering, int size)
Definition kkutils.c:161
double distance_kD(double **coords, int dim, int i, int j)
Definition kkutils.c:113
void fill_neighbors_vec_unweighted(vtx_data *graph, int vtx, int *vtx_vec)
Definition kkutils.c:32
size_t common_neighbors(vtx_data *graph, int u, int *v_vector)
Definition kkutils.c:19
DistType ** compute_apsp(vtx_data *graph, int n)
Definition kkutils.c:85
void restore_old_weights(vtx_data *graph, int n, float *old_weights)
Definition kkutils.c:196
DistType ** compute_apsp_artificial_weights(vtx_data *graph, int n)
Definition kkutils.c:93
void empty_neighbors_vec(vtx_data *graph, int vtx, int *vtx_vec)
Definition kkutils.c:41
void quicksort_placef(float *place, int *ordering, int first, int last)
Definition kkutils.c:140
static int fcmpf(const void *a, const void *b, void *context)
Definition kkutils.c:125
static int cmp(const void *a, const void *b, void *context)
Definition kkutils.c:147
#define neighbor(t, i, edim, elist)
Definition make_map.h:41
static const int dim
static int nedges
total no. of edges used in routing
Definition routespl.c:31
qsort with carried along context
static void gv_sort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
qsort with an extra state parameter, ala qsort_r
Definition sort.h:35
int DistType
Definition sparsegraph.h:37