/* multiq_insert() */ static inline int multiq_insert(jl_task_t *task, int16_t priority) { jl_ptls_t ptls = jl_get_ptls_states(); uint64_t rn; task->prio = priority; do { rn = cong(heap_p, cong_unbias, &ptls->rngseed); } while (!jl_mutex_trylock_nogc(&heaps[rn].lock)); if (heaps[rn].ntasks >= tasks_per_heap) { jl_mutex_unlock_nogc(&heaps[rn].lock); jl_error("multiq insertion failed, increase #tasks per heap"); return -1; } heaps[rn].tasks[heaps[rn].ntasks++] = task; sift_up(&heaps[rn], heaps[rn].ntasks-1); jl_mutex_unlock_nogc(&heaps[rn].lock); int16_t prio = jl_atomic_load(&heaps[rn].prio); if (task->prio < prio) jl_atomic_compare_exchange(&heaps[rn].prio, prio, task->prio); return 0; }
/* * Given a heap and an index, sift_up checks to see if the value * at that index needs to be "sifted upward" in the heap, to * preserve the heap properties. Specifically, a value needs to * be moved up in the heap if it is less than its parent value. * (This is just the "order" property; the "shape" property is * not affected by sifting a value up.) */ void sift_up(float_heap *pHeap, int index) { int parent_index = PARENT(index); /* If the index to sift up is the root, we are done. */ if (index == 0) return; assert(parent_index >= 0); assert(parent_index != index); /* Parent of index 0 = 0... that's bad. */ /* If the specified value is smaller than its parent value then * we have to swap the value and its parent. */ if (pHeap->values[index] < pHeap->values[parent_index]) { /* Swap the value with its parent value. */ swap_values(pHeap, index, parent_index); /* If we haven't gotten to the root, we might have to * sift up again. */ if (parent_index != 0) sift_up(pHeap, parent_index); } }
int main() { char command; int b; while( scanf("%c", &command)) { if(command == 'Q') break; if(command == 'A') { scanf("%d", &b); sift_up(b); } if(command == 'R') { if(n == 0) printf("Not available\n"); else {printf("%d\n", sift_down());} } if(command == 'L') { if(n == 0) printf("Not available"); else {printf("%d\n", h[0]);} } } return 0; }
void heap_add(binary_heap *heap, void *new_element) { if(heap->len == heap->mem) { heap->heap = realloc(heap->heap, heap->mem * 2); heap->mem *= 2; } heap->heap[heap->len++] = new_element; sift_up(heap, heap->len-1); }
/** * gts_heap_insert: * @heap: a #GtsHeap. * @p: a pointer to add to the heap. * * Inserts a new element @p in the heap. */ void gts_heap_insert (GtsHeap * heap, gpointer p) { g_return_if_fail (heap != NULL); g_ptr_array_add (heap->elts, p); if (!heap->frozen) sift_up (heap, heap->elts->len); }
/* * binaryheap_add * * Adds the given datum to the heap in O(log n) time, while preserving * the heap property. */ void binaryheap_add(binaryheap *heap, Datum d) { if (heap->bh_size >= heap->bh_space) elog(ERROR, "out of binary heap slots"); heap->bh_nodes[heap->bh_size] = d; heap->bh_size++; sift_up(heap, heap->bh_size - 1); }
/**Function******************************************************************** Synopsis [Builds a DD from a given order.] Description [Builds a DD from a given order. This procedure also sifts the final order and inserts into the array the size in nodes of the result. Returns 1 if successful; 0 otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ static int build_dd( DdManager * table, int num /* the index of the individual to be built */, int lower, int upper) { int i,j; /* loop vars */ int position; int index; int limit; /* how large the DD for this order can grow */ int size; /* Check the computed table. If the order already exists, it ** suffices to copy the size from the existing entry. */ if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { STOREDD(num,numvars) = STOREDD(index,numvars); #ifdef DD_STATS (void) fprintf(table->out,"\nCache hit for index %d", index); #endif return(1); } /* Stop if the DD grows 20 times larges than the reference size. */ limit = 20 * STOREDD(0,numvars); /* Sift up the variables so as to build the desired permutation. ** First the variable that has to be on top is sifted to the top. ** Then the variable that has to occupy the secon position is sifted ** up to the second position, and so on. */ for (j = 0; j < numvars; j++) { i = STOREDD(num,j); position = table->perm[i]; result = sift_up(table,position,j+lower); if (!result) return(0); size = table->keys - table->isolated; if (size > limit) break; } /* Sift the DD just built. */ #ifdef DD_STATS (void) fprintf(table->out,"\n"); #endif result = cuddSifting(table,lower,upper); if (!result) return(0); /* Copy order and size to table. */ for (j = 0; j < numvars; j++) { STOREDD(num,j) = table->invperm[lower+j]; } STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ return(1); } /* end of build_dd */
void sift_up(int* arr, int i) { if(i == 0) return; // at the root // if the current node is larger than its parent, swap them if(cmp(arr[i], arr[(i-1)/2]) > 0) { swap(&arr[i], &arr[(i-1)/2]); // sift up to repair the heap sift_up(arr, (i-1)/2); } }
bool heap_add(struct heap *h, void *v) { if( h->n >= h->size ) { return false; } size_t i = h->n++; h->cpy(pitem(h,i), v); sift_up(h, i); return true; }
/* sift_up() */ static inline void sift_up(taskheap_t *heap, int16_t idx) { if (idx > 0) { int16_t parent = (idx-1)/heap_d; if (heap->tasks[idx]->prio < heap->tasks[parent]->prio) { jl_task_t *t = heap->tasks[parent]; heap->tasks[parent] = heap->tasks[idx]; heap->tasks[idx] = t; sift_up(heap, parent); } } }
static void heap_sort(int *a, int n) { int i; for (i = 1; i < n; ++i) { sift_up(a-1, i+1); } --i; while (i > 0) { swap(a, 0, i); sift_down(a-1, i--); } }
/** * gts_eheap_insert: * @heap: a #GtsEHeap. * @p: a pointer to add to the heap. * * Inserts a new element @p in the heap. * * Returns: a #GtsEHeapPair describing the position of the element in the heap. * This pointer is necessary for gts_eheap_remove() and * gts_eheap_decrease_key(). */ GtsEHeapPair * gts_eheap_insert (GtsEHeap * heap, gpointer p) { GtsEHeapPair * pair; GPtrArray * elts; g_return_val_if_fail (heap != NULL, NULL); g_return_val_if_fail (heap->func != NULL, NULL); elts = heap->elts; pair = g_malloc (sizeof (GtsEHeapPair)); g_ptr_array_add (elts, pair); pair->data = p; pair->pos = elts->len; pair->key = (*heap->func) (p, heap->data); if (!heap->frozen) sift_up (heap, elts->len); return pair; }
void heap_replace(heap_node_t *old, heap_node_t *node) { heap_t *heap = old->heap; size_t pos = old->index; heap_node_t **storage = heap->allocation.memory; /* disassociate old node from heap */ old->heap = NULL; old->index = 0; /* place new node in heap */ node->heap = heap; node->index = pos; storage[pos] = node; /* restore heap invariant */ sift_up(heap, pos, heap->count); sift_down(heap, 0, pos); }
/** * gts_eheap_decrease_key: * @heap: a #GtsEHeap. * @p: a #GtsEHeapPair. * @new_key: the new value of the key for this element. Must be smaller than * the current key. * * Decreases the value of the key of the element at position @p. */ void gts_eheap_decrease_key (GtsEHeap * heap, GtsEHeapPair * p, gdouble new_key) { guint i; g_return_if_fail (heap != NULL); g_return_if_fail (p != NULL); i = p->pos; g_return_if_fail (i > 0 && i <= heap->elts->len); g_return_if_fail (p == heap->elts->pdata[i - 1]); g_return_if_fail (new_key <= p->key); p->key = new_key; if (!heap->frozen) sift_up (heap, i); }
/* * add item to heap * returns heap_size */ GW_LARGE_INT heap_add(int r, int c, CELL ele) { HEAP_PNT heap_p; /* add point to next free position */ heap_size++; heap_p.added = nxt_avail_pt; heap_p.ele = ele; heap_p.pnt.r = r; heap_p.pnt.c = c; nxt_avail_pt++; /* sift up: move new point towards top of heap */ sift_up(heap_size, heap_p); return heap_size; }
/* Adds another value to the heap, in the proper place. */ void add_value(float_heap *pHeap, float newval) { int index; assert(pHeap != NULL); assert(pHeap->num_values >= 0); /* There needs to be room for one more element in the heap... */ assert(pHeap->num_values < MAX_HEAP_ELEMS); /* Add the new value to the end of the heap, then sift up. */ index = pHeap->num_values; pHeap->values[index] = newval; pHeap->num_values++; /* If the new value isn't at the root, sift up. */ if (index != 0) sift_up(pHeap, index); }
void *heap_insert(heap *h, void *data) { int insert_index; /* make sure that we actually have a tree */ if(h == NULL) { /* we didnt get a tree? */ return NULL; } /* check to make sure there is space in the tree */ if(heap_isfull(h)) { /* the heap is already full, return NULL */ return NULL; } /* check to see if we are using a dup function, and if we are, then make a copy of data, and add the copy of the item to the heap. If we are not, then just add data to the heap */ if(h->dupitem_fn != NULL) { data = h->dupitem_fn(data); if(data == NULL) { /* could not duplicate item */ return NULL; } } insert_index = h->next_free_idx; /* the heap is not full, so go ahead and add the item to the next available spot in the tree, update next_free_idx */ h->heap_items[insert_index] = data; h->next_free_idx++; /* call sift up to move the item to its proper location */ sift_up(h, insert_index); /* return pointer to the data */ return data; }
static void sift_up(heap *h, int insert_index) { int parent_index; int swap_tmp; void *parent_item; void *insert_item; if(h == NULL) { /* no heap */ return; } /* check to make sure they dont want to sift the root up */ if(insert_index == 1) { /* they did, and since its not really possible, just return */ return; } /* calculate the parent index */ parent_index = insert_index >> 1; /* grab pointers to the location of the parent, and the item being inserted */ parent_item = h->heap_items[parent_index]; insert_item = h->heap_items[insert_index]; if(h->orderitem_fn(insert_item, parent_item)) { /* swap the item and its parent */ swap_tmp = insert_index; h->heap_items[parent_index] = insert_item; h->heap_items[insert_index] = parent_item; insert_index = parent_index; parent_index = swap_tmp; /* we did some work, so sift_up again */ sift_up(h, insert_index); } }
void heap_remove(heap_node_t *node) { heap_t *heap = node->heap; size_t pos = node->index; if (heap->count) { /* shrink heap */ heap->count--; if (pos != heap->count) { /* exchange previous last element for removed element */ swap(heap->allocation.memory, pos, heap->count); /* shrink storage */ (void) allocation_realloc_array(&(heap->allocation), heap->count, sizeof(heap_node_t *)); /* restore heap invariant */ sift_up(heap, pos, heap->count); } } /* disassociate node from heap */ node->heap = NULL; node->index = 0; }
void bottom_up_build_max_heap(int* arr, int len) { int i; for(i = 0; i < len; i++) { sift_up(arr, i); } }
// Performs 1OPT move on location w in O(m log n) time void solution_flip(instance_t *inst, solution_t *s, int w) { int i, j, w2, i2; // Update costs s->total_cost -= s->flip_gain[w]; s->flip_gain[w] *= -1.0; // Deal with special case where the solution was 'all locations closed' if (s->heap_size == 0) { s->x[w] = 1; for (j = 0; j < inst->m; j++) { // the cheapest location in each heap is the only open location s->heap[j][0] = w; s->heap_inv[j][w] = 0; s->besti1[j] = w; } for (i = 0; i < inst->n; i++) if (i != w) { // recompute cost differences for all remaining closed locations s->flip_gain[i] = -inst->f[i]; for (j = 0; j < inst->m; j++) { if (inst->c[i][j] < inst->c[w][j]) s->flip_gain[i] += inst->c[w][j] - inst->c[i][j]; } } s->heap_size = 1; return; } // Deal with the special case where we close the only remaining open solution if (s->heap_size == 1 && s->x[w]) { s->x[w] = 0; for (j = 0; j < inst->m; j++) s->besti1[j] = s->heap_inv[j][w] = s->heap[j][0] = -1; //remove w from the heap for (i = 0; i < inst->n; i++) if (i != w) { // compute fictional cost differences s->flip_gain[i] = inst->ub - inst->f[i]; for (j = 0; j < inst->m; j++) s->flip_gain[i] -= inst->c[i][j]; } s->heap_size = 0; return; } // Deal with the general cases if (s->x[w]) { // case where we close location w s->x[w] = 0; --s->heap_size; for (j = 0; j < inst->m; j++) { // carefully remove it from each heap i = s->heap_inv[j][w]; assert(i != -1); assert(s->heap[j][i] == w); w2 = s->heap[j][s->heap_size]; assert(s->heap_inv[j][w2] == s->heap_size); s->heap_inv[j][w] = -1; if (w != w2) { s->heap_inv[j][w2] = i; s->heap[j][i] = w2; sift_up(inst->c, j, s->heap[j], s->heap_inv[j], i); sift_down(inst->c, j, s->heap[j], s->heap_inv[j], s->heap_inv[j][w2], s->heap_size); } } } else { // case where we open location w s->x[w] = 1; for (j = 0; j < inst->m; j++) { // add it to each heap s->heap[j][s->heap_size] = w; s->heap_inv[j][w] = s->heap_size; sift_up(inst->c, j, s->heap[j], s->heap_inv[j], s->heap_size); } ++s->heap_size; } // Update move costs of all closed locations for (j = 0; j < inst->m; j++) { if (inst->c[s->heap[j][0]][j] <= inst->c[s->besti1[j]][j]) { // the client j can use a cheaper location than previously for (i = 0; i < inst->n; i++) if (i != w && !s->x[i]) { if (inst->c[i][j] < inst->c[s->heap[j][0]][j]) s->flip_gain[i] -= inst->c[s->besti1[j]][j] - inst->c[s->heap[j][0]][j]; else if (inst->c[i][j] < inst->c[s->besti1[j]][j]) s->flip_gain[i] -= inst->c[s->besti1[j]][j] - inst->c[i][j]; } } else { for (i = 0; i < inst->n; i++) if (i != w && !s->x[i]) { if (inst->c[i][j] < inst->c[s->besti1[j]][j]) s->flip_gain[i] += inst->c[s->heap[j][0]][j] - inst->c[s->besti1[j]][j] ; else if (inst->c[i][j] < inst->c[s->heap[j][0]][j]) s->flip_gain[i] += inst->c[s->heap[j][0]][j] - inst->c[i][j]; } } } if (s->heap_size == 1) { // Special case where one location is open // This special case only occurs when we close one of two open locations // Recompute all move costs and two cheapest locations from scratch i = s->heap[0][0]; assert(s->x[i]); s->flip_gain[i] = -inst->ub + inst->f[i]; for (j = 0; j < inst->m; j++) { s->flip_gain[i] += inst->c[i][j]; s->besti2[j] = -1; s->besti1[j] = s->heap[j][0]; } } else if (s->heap_size == 2 && s->x[w]) { // Special case where two locations are open // This special case only occurs when only one location was open an we open another // Recompute all move costs and two cheapest locations from scratch i = (s->heap[0][0] == w) ? s->heap[0][1] : s->heap[0][0]; assert(s->x[i]); assert(i != w); s->flip_gain[i] = inst->f[i]; for (j = 0; j < inst->m; j++) { assert(s->besti2[j] == -1); if (s->heap[j][0] == i) s->flip_gain[i] += inst->c[i][j] - inst->c[s->heap[j][1]][j]; s->besti2[j] = s->heap[j][1]; s->besti1[j] = s->heap[j][0]; } } else { // Update all move costs and the two cheapest locations for (j = 0; j < inst->m; j++) { i2 = (s->heap_size == 2 || inst->c[s->heap[j][1]][j] <= inst->c[s->heap[j][2]][j]) ? 1 : 2; if (s->heap[j][0] != s->besti1[j] || inst->c[s->heap[j][i2]][j] != inst->c[s->besti2[j]][j]) { i = s->besti1[j]; if (i != w && s->x[i]) s->flip_gain[i] += inst->c[s->besti2[j]][j] - inst->c[i][j]; i = s->heap[j][0]; if (i != w && s->x[i]) s->flip_gain[i] -= inst->c[s->heap[j][i2]][j] - inst->c[i][j]; } s->besti2[j] = s->heap[j][i2]; s->besti1[j] = s->heap[j][0]; } } }