39#define LT(p,q) ((p).dist < (q).dist)
40#define EQ(p,q) ((p).dist == (q).dist)
62#define sub(h,i) (LIST_GET((h), (i)))
73#define left(i) (2*(i))
74#define right(i) (2*(i)+1)
75#define parent(i) ((i)/2)
76#define insideHeap(h,i) ((i)<h->heapSize)
77#define greaterPriority(h,i,j) \
78 (LT(h->data[i],h->data[j]) || ((EQ(h->data[i],h->data[j])) && (rand()%2)))
111 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
112 edge.left = ordering[i];
113 edge.right = ordering[i + 1];
114 edge.dist = place[ordering[i + 1]] - place[ordering[i]];
117 for (
size_t j = (n - 1) / 2; n != 0 && j !=
SIZE_MAX; j--) {
138 size_t newSize = h->
maxSize * 2;
150static int cmp(
const void *a,
const void *b,
void *context) {
153 const double *place = context;
155 if (place[*x] < place[*y]) {
158 if (place[*x] > place[*y]) {
165 pairs_t* pairs_stack) {
173 size_t *ordering =
gv_calloc(n,
sizeof(
size_t));
174 size_t *inv_ordering =
gv_calloc(n,
sizeof(
size_t));
176 for (
size_t i = 0; i < n; i++) {
179 gv_sort(ordering, n,
sizeof(ordering[0]),
cmp, place);
180 for (
size_t i = 0; i < n; i++) {
181 inv_ordering[ordering[i]] = i;
188 for (
size_t i = 1; i < n; i++) {
189 left[ordering[i]] = ordering[i - 1];
191 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
192 right[ordering[i]] = ordering[i + 1];
203 size_t left_index = inv_ordering[
pair.left];
204 size_t right_index = inv_ordering[
pair.right];
205 if (left_index > 0) {
206 size_t neighbor = ordering[left_index - 1];
210 new_pair.right =
pair.right;
217 if (right_index < n - 1) {
218 size_t neighbor = ordering[right_index + 1];
221 new_pair.left =
pair.left;
239 for (
size_t i = 0; i <
graph[u].nedges; i++) {
240 if (
graph[u].edges[i] == v) {
258 int *degrees =
gv_calloc(n,
sizeof(
int));
260 size_t new_nedges = 2 *
top + n;
262 int *edges =
gv_calloc(new_nedges,
sizeof(
int));
263 float *weights =
gv_calloc(new_nedges,
sizeof(
float));
265 for (
size_t i = 0; i < n; i++) {
268 for (
size_t i = 0; i <
top; i++) {
270 degrees[
pair.left]++;
271 degrees[
pair.right]++;
275 for (
size_t i = 0; i < new_nedges; i++) {
280 for (
size_t i = 0; i < n; i++) {
282 new_graph[i].
ewgts = weights;
283 new_graph[i].
edges = edges;
284 assert(i <= INT_MAX);
287 weights += degrees[i];
294 while (
pop(edges_stack, &
pair)) {
295 assert(
pair.left <= INT_MAX);
296 assert(
pair.right <= INT_MAX);
306 pairs_t pairs_stack = {0};
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
#define greaterPriority(h, i, j)
static void find_closest_pairs(double *place, size_t n, int num_pairs, pairs_t *pairs_stack)
static void initHeap(PairHeap *h, double *place, size_t *ordering, size_t n)
static vtx_data * construct_graph(size_t n, pairs_t *edges_stack)
static void freeHeap(PairHeap *h)
void closest_pairs2graph(double *place, int n, int num_pairs, vtx_data **graph)
static bool extractMax(PairHeap *h, Pair *max)
static void add_edge(vtx_data *graph, int u, int v)
static void heapify(PairHeap *h, size_t i)
static void insert(PairHeap *h, Pair edge)
static int cmp(const void *a, const void *b, void *context)
static gstack_t * push(gstack_t *s, Agraph_t *subg)
Agraph_t * graph(char *name)
Arithmetic helper functions.
static Agedge_t * top(edge_stack_t *sp)
type-generic dynamically expanding list
#define LIST_DROP_BACK(list)
#define LIST_IS_EMPTY(list)
#define LIST_PUSH_BACK(list, item)
#define neighbor(t, i, edim, elist)
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
size_t right
the right node in the pair
size_t left
the left node in the pair
size_t nedges
no. of neighbors, including self