Graphviz 14.0.5~dev.20251117.1017
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 of this function */
45 for (size_t j = 1; j < graph[vtx].nedges; j++) {
46 vtx_vec[graph[vtx].edges[j]] = 0;
47 }
48}
49
52{
53 int i;
54
55 DistType *storage = gv_calloc((size_t)(n * n), sizeof(DistType));
56 DistType **dij = gv_calloc(n, sizeof(DistType*));
57 for (i = 0; i < n; i++)
58 dij[i] = storage + i * n;
59
60 for (i = 0; i < n; i++) {
61 ngdijkstra(i, graph, n, dij[i]);
62 }
63 return dij;
64}
65
67{
68 /* compute all pairs shortest path */
69 /* for unweighted graph */
70 int i;
71 DistType *storage = gv_calloc((size_t)(n * n), sizeof(DistType));
72
73 DistType **dij = gv_calloc(n, sizeof(DistType*));
74 for (i = 0; i < n; i++) {
75 dij[i] = storage + i * n;
76 }
77 for (i = 0; i < n; i++) {
78 bfs(i, graph, n, dij[i]);
79 }
80 return dij;
81}
82
84{
85 if (graph->ewgts)
87 else
88 return compute_apsp_simple(graph, n);
89}
90
92 DistType **Dij;
93 /* compute all-pairs-shortest-path-length while weighting the graph */
94 /* so high-degree nodes are distantly located */
95
96 float *old_weights = graph[0].ewgts;
97
100 restore_old_weights(graph, n, old_weights);
101 return Dij;
102}
103
104
105/**********************/
106/* */
107/* Quick Sort */
108/* */
109/**********************/
110
111double distance_kD(double **coords, int dim, int i, int j)
112{
113 /* compute a k-D Euclidean distance between 'coords[*][i]' and 'coords[*][j]' */
114 double sum = 0;
115 int k;
116 for (k = 0; k < dim; k++) {
117 sum +=
118 (coords[k][i] - coords[k][j]) * (coords[k][i] - coords[k][j]);
119 }
120 return sqrt(sum);
121}
122
123static int fcmpf(const void *a, const void *b, void *context) {
124 const int *ip1 = a;
125 const int *ip2 = b;
126 float *fvals = context;
127 float d1 = fvals[*ip1];
128 float d2 = fvals[*ip2];
129 if (d1 < d2) {
130 return -1;
131 }
132 if (d1 > d2) {
133 return 1;
134 }
135 return 0;
136}
137
138void quicksort_placef(float *place, int *ordering, int first, int last)
139{
140 if (first < last) {
141 gv_sort(ordering + first, last - first + 1, sizeof(ordering[0]), fcmpf, place);
142 }
143}
144
145static int cmp(const void *a, const void *b, void *context) {
146 const int *x = a;
147 const int *y = b;
148 const double *place = context;
149
150 if (place[*x] < place[*y]) {
151 return -1;
152 }
153 if (place[*x] > place[*y]) {
154 return 1;
155 }
156 return 0;
157}
158
159void quicksort_place(double *place, int *ordering, int size) {
160 gv_sort(ordering, size, sizeof(ordering[0]), cmp, place);
161}
162
164{
165 /* Reweight graph so that high degree nodes will be separated */
166
167 int i;
168 size_t nedges = 0;
169 int *vtx_vec = gv_calloc(n, sizeof(int));
170 size_t deg_i, deg_j;
171 int neighbor;
172
173 for (i = 0; i < n; i++) {
174 nedges += graph[i].nedges;
175 }
176 float *weights = gv_calloc(nedges, sizeof(float));
177
178 for (i = 0; i < n; i++) {
179 graph[i].ewgts = weights;
181 deg_i = graph[i].nedges - 1;
182 for (size_t j = 1; j <= deg_i; j++) {
183 neighbor = graph[i].edges[j];
184 deg_j = graph[neighbor].nedges - 1;
185 weights[j] =
186 (float)(deg_i + deg_j - 2 * common_neighbors(graph, neighbor, vtx_vec));
187 }
188 empty_neighbors_vec(graph, i, vtx_vec);
189 weights += graph[i].nedges;
190 }
191 free(vtx_vec);
192}
193
194void restore_old_weights(vtx_data * graph, int n, float *old_weights)
195{
196 int i;
197 free(graph[0].ewgts);
198 graph[0].ewgts = NULL;
199 if (old_weights != NULL) {
200 for (i = 0; i < n; i++) {
201 graph[i].ewgts = old_weights;
202 old_weights += graph[i].nedges;
203 }
204 }
205}
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)
compute vector dist of distances of all nodes from vertex
Definition bfs.c:22
void free(void *)
node NULL
Definition grammar.y:181
Agraph_t * graph(char *name)
Definition gv.cpp:32
static DistType ** compute_apsp_dijkstra(vtx_data *graph, int n)
assumes the graph has weights
Definition kkutils.c:51
static DistType ** compute_apsp_simple(vtx_data *graph, int n)
Definition kkutils.c:66
void compute_new_weights(vtx_data *graph, int n)
Definition kkutils.c:163
void quicksort_place(double *place, int *ordering, int size)
Definition kkutils.c:159
double distance_kD(double **coords, int dim, int i, int j)
Definition kkutils.c:111
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:83
void restore_old_weights(vtx_data *graph, int n, float *old_weights)
Definition kkutils.c:194
DistType ** compute_apsp_artificial_weights(vtx_data *graph, int n)
Definition kkutils.c:91
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:138
static int fcmpf(const void *a, const void *b, void *context)
Definition kkutils.c:123
static int cmp(const void *a, const void *b, void *context)
Definition kkutils.c:145
void ngdijkstra(int vertex, vtx_data *graph, int n, DistType *dist)
Definition dijkstra.c:139
#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:32
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:24
int DistType
Definition sparsegraph.h:38