00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "bfs.h"
00019 #include "dijkstra.h"
00020 #include "kkutils.h"
00021 #include <stdlib.h>
00022 #include <math.h>
00023
00024 int common_neighbors(vtx_data * graph, int v, int u, int *v_vector)
00025 {
00026
00027 int neighbor;
00028 int num_shared_neighbors = 0;
00029 int j;
00030 for (j = 1; j < graph[u].nedges; j++) {
00031 neighbor = graph[u].edges[j];
00032 if (v_vector[neighbor] > 0) {
00033
00034 num_shared_neighbors++;
00035 }
00036 }
00037 return num_shared_neighbors;
00038 }
00039 void fill_neighbors_vec_unweighted(vtx_data * graph, int vtx, int *vtx_vec)
00040 {
00041
00042
00043 int j;
00044 for (j = 1; j < graph[vtx].nedges; j++) {
00045 vtx_vec[graph[vtx].edges[j]] = 1;
00046 }
00047 }
00048
00049 void empty_neighbors_vec(vtx_data * graph, int vtx, int *vtx_vec)
00050 {
00051 int j;
00052
00053
00054 for (j = 1; j < graph[vtx].nedges; j++) {
00055 vtx_vec[graph[vtx].edges[j]] = 0;
00056 }
00057 }
00058
00059
00060
00061
00062 static DistType **compute_apsp_dijkstra(vtx_data * graph, int n)
00063 {
00064 int i;
00065 DistType *storage;
00066 DistType **dij;
00067
00068 storage = N_GNEW(n * n, DistType);
00069 dij = N_GNEW(n, DistType *);
00070 for (i = 0; i < n; i++)
00071 dij[i] = storage + i * n;
00072
00073 for (i = 0; i < n; i++) {
00074 dijkstra(i, graph, n, dij[i]);
00075 }
00076 return dij;
00077 }
00078
00079 static DistType **compute_apsp_simple(vtx_data * graph, int n)
00080 {
00081
00082
00083 int i;
00084 DistType *storage = N_GNEW(n * n, int);
00085 DistType **dij;
00086 Queue Q;
00087
00088 dij = N_GNEW(n, DistType *);
00089 for (i = 0; i < n; i++) {
00090 dij[i] = storage + i * n;
00091 }
00092 mkQueue(&Q, n);
00093 for (i = 0; i < n; i++) {
00094 bfs(i, graph, n, dij[i], &Q);
00095 }
00096 freeQueue(&Q);
00097 return dij;
00098 }
00099
00100 DistType **compute_apsp(vtx_data * graph, int n)
00101 {
00102 if (graph->ewgts)
00103 return compute_apsp_dijkstra(graph, n);
00104 else
00105 return compute_apsp_simple(graph, n);
00106 }
00107
00108 DistType **compute_apsp_artifical_weights(vtx_data * graph, int n)
00109 {
00110 DistType **Dij;
00111
00112
00113
00114 float *old_weights = graph[0].ewgts;
00115
00116 compute_new_weights(graph, n);
00117 Dij = compute_apsp_dijkstra(graph, n);
00118 restore_old_weights(graph, n, old_weights);
00119 return Dij;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129 static void
00130 split_by_place(double *place, int *nodes, int first, int last, int *middle)
00131 {
00132 unsigned int splitter =
00133 rand() * ((unsigned) (last - first)) / RAND_MAX + (unsigned) first;
00134 int val;
00135 double place_val;
00136 int left = first + 1;
00137 int right = last;
00138 int temp;
00139
00140 val = nodes[splitter];
00141 nodes[splitter] = nodes[first];
00142 nodes[first] = val;
00143 place_val = place[val];
00144
00145 while (left < right) {
00146 while (left < right && place[nodes[left]] <= place_val)
00147 left++;
00148 while (left < right && place[nodes[right]] >= place_val)
00149 right--;
00150 if (left < right) {
00151 temp = nodes[left];
00152 nodes[left] = nodes[right];
00153 nodes[right] = temp;
00154 left++;
00155 right--;
00156
00157 }
00158 }
00159
00160
00161 if (place[nodes[left]] > place_val)
00162 left = left - 1;
00163 *middle = left;
00164 nodes[first] = nodes[*middle];
00165 nodes[*middle] = val;
00166 }
00167
00168 double distance_kD(double **coords, int dim, int i, int j)
00169 {
00170
00171 double sum = 0;
00172 int k;
00173 for (k = 0; k < dim; k++) {
00174 sum +=
00175 (coords[k][i] - coords[k][j]) * (coords[k][i] - coords[k][j]);
00176 }
00177 return sqrt(sum);
00178 }
00179
00180 static float* fvals;
00181 static int
00182 fcmpf (int* ip1, int* ip2)
00183 {
00184 float d1 = fvals[*ip1];
00185 float d2 = fvals[*ip2];
00186 if (d1 < d2) return -1;
00187 else if (d1 > d2) return 1;
00188 else return 0;
00189 }
00190
00191 void quicksort_placef(float *place, int *ordering, int first, int last)
00192 {
00193 if (first < last) {
00194 fvals = place;
00195 qsort(ordering+first, last-first+1, sizeof(ordering[0]), (qsort_cmpf)fcmpf);
00196 }
00197 }
00198
00199
00200
00201
00202
00203
00204 void quicksort_place(double *place, int *ordering, int first, int last)
00205 {
00206 if (first < last) {
00207 int middle;
00208 #ifdef __cplusplus
00209 split_by_place(place, ordering, first, last, middle);
00210 #else
00211 split_by_place(place, ordering, first, last, &middle);
00212 #endif
00213 quicksort_place(place, ordering, first, middle - 1);
00214 quicksort_place(place, ordering, middle + 1, last);
00215 }
00216 }
00217
00218 void compute_new_weights(vtx_data * graph, int n)
00219 {
00220
00221
00222 int i, j;
00223 int nedges = 0;
00224 float *weights;
00225 int *vtx_vec = N_GNEW(n, int);
00226 int deg_i, deg_j, neighbor;
00227
00228 for (i = 0; i < n; i++) {
00229 nedges += graph[i].nedges;
00230 }
00231 weights = N_GNEW(nedges, float);
00232
00233 for (i = 0; i < n; i++) {
00234 vtx_vec[i] = 0;
00235 }
00236
00237 for (i = 0; i < n; i++) {
00238 graph[i].ewgts = weights;
00239 fill_neighbors_vec_unweighted(graph, i, vtx_vec);
00240 deg_i = graph[i].nedges - 1;
00241 for (j = 1; j <= deg_i; j++) {
00242 neighbor = graph[i].edges[j];
00243 deg_j = graph[neighbor].nedges - 1;
00244 weights[j] =
00245 (float) (deg_i + deg_j -
00246 2 * common_neighbors(graph, i, neighbor,
00247 vtx_vec));
00248 }
00249 empty_neighbors_vec(graph, i, vtx_vec);
00250 weights += graph[i].nedges;
00251 }
00252 free(vtx_vec);
00253 }
00254
00255 void restore_old_weights(vtx_data * graph, int n, float *old_weights)
00256 {
00257 int i;
00258 free(graph[0].ewgts);
00259 graph[0].ewgts = NULL;
00260 if (old_weights != NULL) {
00261 for (i = 0; i < n; i++) {
00262 graph[i].ewgts = old_weights;
00263 old_weights += graph[i].nedges;
00264 }
00265 }
00266 }