36#define LT(p,q) ((p).dist < (q).dist)
37#define EQ(p,q) ((p).dist == (q).dist)
47 pairs_push_back(
s,
copy);
53 if (pairs_is_empty(
s)) {
67#define sub(h,i) (*pairs_get((h), (i)))
78#define left(i) (2*(i))
79#define right(i) (2*(i)+1)
80#define parent(i) ((i)/2)
81#define insideHeap(h,i) ((i)<h->heapSize)
82#define greaterPriority(h,i,j) \
83 (LT(h->data[i],h->data[j]) || ((EQ(h->data[i],h->data[j])) && (rand()%2)))
85#define exchange(h,i,j) {Pair temp; \
87 h->data[i]=h->data[j]; \
122 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
123 edge.left = ordering[i];
124 edge.right = ordering[i + 1];
125 edge.dist = place[ordering[i + 1]] - place[ordering[i]];
128 for (
size_t j = (n - 1) / 2; n != 0 && j !=
SIZE_MAX; j--) {
149 size_t newSize = h->
maxSize * 2;
161static int cmp(
const void *a,
const void *b,
void *context) {
164 const double *place = context;
166 if (place[*x] < place[*y]) {
169 if (place[*x] > place[*y]) {
176 pairs_t* pairs_stack) {
184 size_t *ordering =
gv_calloc(n,
sizeof(
size_t));
185 size_t *inv_ordering =
gv_calloc(n,
sizeof(
size_t));
187 for (
size_t i = 0; i < n; i++) {
190 gv_sort(ordering, n,
sizeof(ordering[0]),
cmp, place);
191 for (
size_t i = 0; i < n; i++) {
192 inv_ordering[ordering[i]] = i;
199 for (
size_t i = 1; i < n; i++) {
200 left[ordering[i]] = ordering[i - 1];
202 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
203 right[ordering[i]] = ordering[i + 1];
214 size_t left_index = inv_ordering[
pair.left];
215 size_t right_index = inv_ordering[
pair.right];
216 if (left_index > 0) {
217 size_t neighbor = ordering[left_index - 1];
221 new_pair.right =
pair.right;
228 if (right_index < n - 1) {
229 size_t neighbor = ordering[right_index + 1];
232 new_pair.left =
pair.left;
250 for (
size_t i = 0; i <
graph[u].nedges; i++) {
251 if (
graph[u].edges[i] == v) {
271 int *degrees =
gv_calloc(n,
sizeof(
int));
272 size_t top = pairs_size(edges_stack);
273 size_t new_nedges = 2 *
top + n;
275 int *edges =
gv_calloc(new_nedges,
sizeof(
int));
276 float *weights =
gv_calloc(new_nedges,
sizeof(
float));
278 for (
size_t i = 0; i < n; i++) {
281 for (
size_t i = 0; i <
top; i++) {
283 degrees[
pair.left]++;
284 degrees[
pair.right]++;
288 for (
size_t i = 0; i < new_nedges; i++) {
293 for (
size_t i = 0; i < n; i++) {
295 new_graph[i].
ewgts = weights;
296 new_graph[i].
edges = edges;
297 assert(i <= INT_MAX);
300 weights += degrees[i];
307 while (
pop(edges_stack, &
pair)) {
308 assert(
pair.left <= INT_MAX);
309 assert(
pair.right <= INT_MAX);
318 pairs_t pairs_stack = {0};
322 pairs_free(&pairs_stack);
Agobj_t * copy(Agraph_t *g, Agobj_t *obj)
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)
static void * gv_alloc(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 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)
#define exchange(h, i, j)
static void construct_graph(size_t n, pairs_t *edges_stack, vtx_data **New_graph)
static void push(pairs_t *s, Pair x)
static void insert(PairHeap *h, Pair edge)
static int cmp(const void *a, const void *b, void *context)
Agraph_t * graph(char *name)
static Agedge_t * top(edge_stack_t *sp)
#define DEFINE_LIST(name, type)
#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