void heap_sort(sortlist_t *list) { sortlist_node_t temp; int i = 0; for (i = list->len / 2; i > 0; i--) heap_build(list, i, list->len); for (i = list->len; i > 1; i--) { temp = list->list[i - 1]; list->list[i - 1] = list->list[0]; list->list[0] = temp; heap_build(list, 1, i - 1); } }
/* ----------------------------------------------------------------------- */ int projectI(double xPtr[], double bPtr[], double tau, int n) /* ----------------------------------------------------------------------- */ { int i, j; double b, /* Current element of vector b */ csb, /* Cumulative sum of b */ alpha = 0, soft = 0; /* Soft thresholding value */ /* The vector xPtr[] is initialized to bPtr[] prior to the function call */ /* Check if tau is essentially zero. Exit with x = 0. */ if (tau < DBL_EPSILON) { for (i = 0; i < n; i++) xPtr[i] = 0; return 0; } /* Check if ||b||_1 <= lambda. Exit with x = b. */ for (csb = 0, i = 0; i < n; i++) csb += bPtr[i]; if (csb <= tau) return 0; /* Set up the heap */ heap_build(n, xPtr); /* Initialise csb with -tau so we don't have to subtract this at every iteration */ csb = -tau; /* Determine threshold value `soft' */ for (i = n, j = 0; j < n; soft = alpha) { b = xPtr[0]; /* Get current maximum heap element */ j ++; /* Give compiler some room for optimization */ csb += b; /* Update the cumulative sum of b */ /* Move heap to next maximum value */ i = heap_del_max(i, xPtr); /* Compute the required step to satisfy the tau constraint */ alpha = csb / j; /* We are done as soon as the constraint can be satisfied */ /* without exceeding the current minimum value in `vector' b */ if (alpha >= b) break; } /* Set the solution by applying soft-thresholding with `soft' */ for (i = 0; i < n; i++) { b = bPtr[i]; if (b <= soft) xPtr[i] = 0; else xPtr[i] = b - soft; } return j; }
int main(){ int a[10] = {5,6,1,2,3,8,7,11,10,20},i=0; struct heap heap; HEAP_INIT(&heap,12); heap_build(&heap,a,10); heap_insert(&heap,4); heap_insert(&heap,0); for(i=0;i<12;i++){ printf("%d ",heap.heap_arr[i]); } }
void heap_sort(int *a, int length) { // 建立堆 大根堆,递增排序 heap_build(a,length); for (int i = length-1; i >0; --i) { //交换 heap_swop(&a[0],&a[i]); //调整 heap_adjust(a,i); } }
static void Select_on (int k, heap_comp hc) { int i, num, mem; WordData **wd; Alloc_keep_discard (); num = Num[0] + Num[1]; wd = Xmalloc (num * sizeof (WordData *)); for (i = 0; i < Num[0]; i++) wd[i] = Words[0] + i; for (i = 0; i < Num[1]; i++) wd[i + Num[0]] = Words[1] + i; heap_build (wd, sizeof (*wd), num, hc); mem = 0; while (k > mem && num) { int idx; WordData *word = wd[0]; #ifdef DEBUG fprintf (stderr, "%4d:%4d:%8d :%8d :%8d : \"%s\"\n", keep[0].num_wds, keep[1].num_wds, mem, word->freq, word->occur_num, word2str (word->word)); #endif mem += sizeof (u_char *) + word->word[0]; heap_deletehead (wd, sizeof (*wd), &num, hc); idx = KIND (word); keep[idx].wd[keep[idx].num_wds++] = word; } for (i = 0; i < num; i++) { WordData *word = wd[i]; int idx = KIND (word); discard[idx].wd[discard[idx].num_wds++] = word; } SortAndCount_DictData (&keep[0]); SortAndCount_DictData (&keep[1]); SortAndCount_DictData (&discard[0]); SortAndCount_DictData (&discard[1]); assert (keep[0].num_wds + discard[0].num_wds == Num[0]); assert (keep[1].num_wds + discard[1].num_wds == Num[1]); }
static inline int k_smallest(const int *v, int vn, int *heap, int hn) { if (vn < hn) { return -1; } /* fill heap */ memcpy(heap, v, sizeof(int) * hn); /* build heap shape */ heap_build(heap, hn); for (int i = hn; i < vn; ++i) { if (v[i] < heap[0]) { heap[0] = v[i]; heaptify(heap, hn, 0); } } return 0; }
struct hcnode * huffman(struct hcnode **nodes, size_t count) { struct heap *heap; struct hcnode *z, *x, *y; struct hcnode *root; int i; heap = heap_build(nodes, count); for(i=0; i<count-1; i++) { z = xmalloc(sizeof(struct hcnode)); x = z->left = heap_extract_min(heap); y = z->right = heap_extract_min(heap); z->frequency = x->frequency + y->frequency; x->parent = y->parent = z; z->parent = NULL; heap_insert(heap, z); } root = heap_extract_min(heap); heap_free(heap); return root; }
void test_heap(void) { struct heap *h; struct hcnode a, b, c, d, e; struct hcnode *nodes[3]; d.frequency = 4; e.frequency = 5; b.frequency = 2; c.frequency = 3; a.frequency = 1; nodes[0] = &a; nodes[1] = &b; nodes[2] = &c; nodes[3] = &d; nodes[4] = &e; h = heap_build(nodes, 5); assert (1 == heap_extract_min(h)->frequency); assert (2 == heap_extract_min(h)->frequency); assert (3 == heap_extract_min(h)->frequency); assert (4 == heap_extract_min(h)->frequency); assert (5 == heap_extract_min(h)->frequency); heap_free(h); }
static void Method3 (int k) { int i, keep_num, discard_num, mem, num_trans, recalc_reqd; int keep_to_discard = 0; int discard_to_keep = 0; int recalcs = 0; double freqs_trans[2], total; u_long escape[2]; WordData **keep_heap, **discard_heap; freqs_trans[0] = freqs_trans[1] = 0; num_trans = 0; discard_num = Num[0] + Num[1]; discard_heap = Xmalloc (discard_num * sizeof (WordData *)); keep_num = 0; keep_heap = Xmalloc (discard_num * sizeof (WordData *)); for (i = 0; i < Num[0]; i++) discard_heap[i] = Words[0] + i; for (i = 0; i < Num[1]; i++) discard_heap[i + Num[0]] = Words[1] + i; heap_build (discard_heap, sizeof (*discard_heap), discard_num, DecFreqIncWL); mem = 0; while (k > mem && discard_num) { WordData *word = discard_heap[0]; mem += sizeof (u_char *) + word->word[0]; heap_deletehead (discard_heap, sizeof (word), &discard_num, DecFreqIncWL); keep_heap[keep_num++] = word; freqs_trans[KIND (word)] += word->freq; num_trans++; } CalcBitCost (discard_heap, discard_num, keep_heap, keep_num, freqs_trans, escape, num_trans); heap_build (discard_heap, sizeof (*discard_heap), discard_num, BigSaving); heap_build (keep_heap, sizeof (*keep_heap), keep_num, SmallSaving); total = 0; recalc_reqd = 0; while (keep_num && discard_num) { if ((keep_num && keep_heap[0]->num_trans < num_trans) || (discard_num && discard_heap[0]->num_trans < num_trans)) { if (keep_num && keep_heap[0]->num_trans < num_trans) { WordData *word = keep_heap[0]; int idx = KIND (word); float wbc; #ifdef DEBUG1 fprintf (stderr, "KEEP \"%s\" %.2f ->", word2str (word->word), word->saving); #endif wbc = -log2 (word->freq / (freqs_trans[idx] + escape[idx])) * word->freq; word->saving = (word->char_bit_cost - wbc) / (sizeof (char *) + word->word[0]); #ifdef DEBUG1 fprintf (stderr, " %.2f\n", word->saving); #endif word->num_trans = num_trans; heap_changedhead (keep_heap, sizeof (word), keep_num, SmallSaving); } if (discard_num && discard_heap[0]->num_trans < num_trans) { WordData *word = discard_heap[0]; int idx = KIND (word); float wbc; #ifdef DEBUG1 fprintf (stderr, "DISCARD \"%s\" %.2f ->", word2str (word->word), word->saving); #endif wbc = -log2 (word->freq / (freqs_trans[idx] + escape[idx])) * word->freq; word->saving = (word->char_bit_cost - wbc) / (sizeof (char *) + word->word[0]); #ifdef DEBUG1 fprintf (stderr, " %.2f\n", word->saving); #endif word->num_trans = num_trans; heap_changedhead (discard_heap, sizeof (word), discard_num, BigSaving); } } else if (keep_heap[0]->saving < discard_heap[0]->saving) { assert (keep_num && discard_num); if (keep_num && mem + sizeof (char *) + discard_heap[0]->word[0] > k) { /* Transfer the word at the top of the keep heap to the discard heap. */ WordData *word = keep_heap[0]; int idx = KIND (word); heap_deletehead (keep_heap, sizeof (word), &keep_num, SmallSaving); discard_heap[discard_num] = word; heap_additem (discard_heap, sizeof (word), &discard_num, BigSaving); freqs_trans[idx] -= word->freq; mem -= sizeof (u_char *) + word->word[0]; num_trans++; total += word->saving; keep_to_discard++; #ifdef DEBUG fprintf (stderr, "KEEP -> DISCARD %8d :%8d :%8.0f :%8.0f : \"%s\"\n", mem, word->freq, word->char_bit_cost, word->saving, word2str (word->word)); #endif } else { /* Transfer the word at the top of the discard heap to the keep heap. */ WordData *word = discard_heap[0]; int idx = KIND (word); heap_deletehead (discard_heap, sizeof (word), &discard_num, BigSaving); keep_heap[keep_num] = word; heap_additem (keep_heap, sizeof (word), &keep_num, SmallSaving); freqs_trans[idx] += word->freq; mem += sizeof (u_char *) + word->word[0]; num_trans++; total += word->saving; discard_to_keep++; #ifdef DEBUG fprintf (stderr, "DISCARD -> KEEP %8d :%8d :%8.0f :%8.0f : \"%s\"\n", mem, word->freq, word->char_bit_cost, word->saving, word2str (word->word)); #endif } recalc_reqd = 1; } else { if (recalc_reqd == 0) break; #ifdef DEBUG1 fprintf (stderr, "--------------\n"); #endif if (recalcs == MAX_RECALCULATIONS) break; CalcBitCost (discard_heap, discard_num, keep_heap, keep_num, freqs_trans, escape, num_trans); heap_build (discard_heap, sizeof (*discard_heap), discard_num, BigSaving); heap_build (keep_heap, sizeof (keep_heap), keep_num, SmallSaving); recalc_reqd = 0; recalcs++; } } Alloc_keep_discard (); for (i = 0; i < discard_num; i++) { WordData *word = discard_heap[i]; int idx = KIND (word); assert (IsWord (word) || IsNonWord (word)); discard[idx].wd[discard[idx].num_wds++] = word; } for (i = 0; i < keep_num; i++) { WordData *word = keep_heap[i]; int idx = KIND (word); assert (IsWord (word) || IsNonWord (word)); keep[idx].wd[keep[idx].num_wds++] = word; } SortAndCount_DictData (&keep[0]); SortAndCount_DictData (&keep[1]); SortAndCount_DictData (&discard[0]); SortAndCount_DictData (&discard[1]); assert (keep[0].num_wds + discard[0].num_wds == Num[0]); assert (keep[1].num_wds + discard[1].num_wds == Num[1]); Message ("Keep -> Discard : %8d", keep_to_discard); Message ("Discard -> Keep : %8d", discard_to_keep); Message ("Huffman Recalculations : %8d", recalcs); if (recalcs == MAX_RECALCULATIONS) Message ("WARNING: The number of recalculations == %d", MAX_RECALCULATIONS); }
void connect_enforce(struct vtx_data **graph, /* data structure for graph */ int nvtxs, /* number of vertices in full graph */ int using_ewgts, /* are edge weights being used? */ int * assignment, /* set number of each vtx (length n) */ double * goal, /* desired sizes for each set */ int nsets_tot, /* total number sets created */ int * total_move, /* total number of vertices moved */ int * max_move /* largest connected component moved */ ) { struct vtx_data **subgraph; /* data structure for domain graph */ int subnvtxs; /* number of vertices in a domain */ int subnedges; /* number of edges in a domain */ struct heap * heap; /* data structure for sorting set sizes */ int * heap_map; /* pointers from sets to heap locations */ int * list_ptrs; /* header of vtx list for each domain */ int * setlists; /* linked list of vtxs for each domain */ int * vtxlist; /* space for breadth first search list */ int * comp_lists; /* list of vtxs in each connected comp */ int * clist_ptrs; /* pointers to heads of comp_lists */ int * subsets; /* list of active domains (all of them) */ int * subsets2; /* list of active domains (all of them) */ double * set_size; /* weighted sizes of different partitions */ double size; /* size of subset being moved to new domain */ int * bndy_list; /* list of domains adjacent to component */ double * bndy_size; /* size of these boundaries */ double * comp_size; /* sizes of different connected components */ double comp_size_max; /* size of largest connected component */ int comp_max_index = 0; /* which component is largest? */ int * glob2loc; /* global to domain renumbering */ int * loc2glob; /* domain to global renumbering */ int * degree; /* number of neighbors of a vertex */ int * comp_flag; /* component number for each vtx */ double ewgt; /* edge weight */ int nbndy; /* number of sets adjecent to component */ int domain; /* which subdomain I'm working on */ int new_domain; /* subdomain to move some vertices to */ double max_bndy; /* max connectivity to other domain */ int ncomps; /* number of connected components */ int change; /* how many vertices change set? */ int max_change; /* largest subset moved together */ int vtx; /* vertex in a connected component */ int set; /* set a neighboring vertex is in */ int i, j, k, l; /* loop counters */ double heap_extract_max(); int make_maps(), find_comps(); void make_setlists(), make_subgraph(), remake_graph(); void heap_build(), heap_update_val(); change = 0; max_change = 0; /* Allocate space & initialize some values. */ set_size = smalloc(nsets_tot * sizeof(double)); bndy_size = smalloc(nsets_tot * sizeof(double)); bndy_list = smalloc(nsets_tot * sizeof(int)); setlists = smalloc((nvtxs + 1) * sizeof(int)); list_ptrs = smalloc(nsets_tot * sizeof(int)); glob2loc = smalloc((nvtxs + 1) * sizeof(int)); loc2glob = smalloc((nvtxs + 1) * sizeof(int)); subsets = smalloc(nsets_tot * sizeof(int)); heap = (struct heap *)smalloc((nsets_tot + 1) * sizeof(struct heap)); heap_map = smalloc(nsets_tot * sizeof(int)); for (i = 0; i < nsets_tot; i++) { set_size[i] = 0; bndy_list[i] = 0; bndy_size[i] = 0; subsets[i] = i; } for (i = 1; i <= nvtxs; i++) { set_size[assignment[i]] += graph[i]->vwgt; } for (i = 0; i < nsets_tot; i++) { heap[i + 1].tag = i; heap[i + 1].val = set_size[i] - goal[i]; } make_setlists(setlists, list_ptrs, nsets_tot, subsets, assignment, NULL, nvtxs, TRUE); heap_build(heap, nsets_tot, heap_map); for (i = 0; i < nsets_tot; i++) { /* Find largest remaining set to work on next */ size = heap_extract_max(heap, nsets_tot - i, &domain, heap_map); /* Construct subdomain graph. */ subnvtxs = make_maps(setlists, list_ptrs, domain, glob2loc, loc2glob); if (subnvtxs > 1) { subgraph = (struct vtx_data **)smalloc((subnvtxs + 1) * sizeof(struct vtx_data *)); degree = smalloc((subnvtxs + 1) * sizeof(int)); make_subgraph(graph, subgraph, subnvtxs, &subnedges, assignment, domain, glob2loc, loc2glob, degree, using_ewgts); /* Find connected components. */ comp_flag = smalloc((subnvtxs + 1) * sizeof(int)); vtxlist = smalloc(subnvtxs * sizeof(int)); ncomps = find_comps(subgraph, subnvtxs, comp_flag, vtxlist); sfree(vtxlist); /* Restore original graph */ remake_graph(subgraph, subnvtxs, loc2glob, degree, using_ewgts); sfree(degree); sfree(subgraph); if (ncomps > 1) { /* Figure out sizes of components */ comp_size = smalloc(ncomps * sizeof(double)); for (j = 0; j < ncomps; j++) { comp_size[j] = 0; } for (j = 1; j <= subnvtxs; j++) { comp_size[comp_flag[j]] += graph[loc2glob[j]]->vwgt; } comp_size_max = 0; for (j = 0; j < ncomps; j++) { if (comp_size[j] > comp_size_max) { comp_size_max = comp_size[j]; comp_max_index = j; } } for (j = 0; j < ncomps; j++) { if (j != comp_max_index) { change += comp_size[j]; if (comp_size[j] > max_change) max_change = comp_size[j]; } } sfree(comp_size); /* Make data structures for traversing components */ comp_lists = smalloc((subnvtxs + 1) * sizeof(int)); clist_ptrs = smalloc(ncomps * sizeof(int)); if (ncomps > nsets_tot) { subsets2 = smalloc(ncomps * sizeof(int)); for (j = 0; j < ncomps; j++) subsets2[j] = j; } else subsets2 = subsets; make_setlists(comp_lists, clist_ptrs, ncomps, subsets2, comp_flag, NULL, subnvtxs, TRUE); if (ncomps > nsets_tot) { sfree(subsets2); } /* Move all but the largest component. */ ewgt = 1; for (j = 0; j < ncomps; j++) if (j != comp_max_index) { /* Figure out to which other domain it is most connected. */ nbndy = 0; k = clist_ptrs[j]; while (k != 0) { vtx = loc2glob[k]; for (l = 1; l <= graph[vtx]->nedges; l++) { set = assignment[graph[vtx]->edges[l]]; if (set != domain) { if (bndy_size[set] == 0) bndy_list[nbndy++] = set; if (using_ewgts) ewgt = graph[vtx]->ewgts[l]; bndy_size[set] += ewgt; } } k = comp_lists[k]; } /* Select a new domain. */ /* Instead of just big boundary, penalize too-large sets. */ /* Could be more aggressive to improve balance. */ max_bndy = 0; new_domain = -1; for (k = 0; k < nbndy; k++) { l = bndy_list[k]; if (bndy_size[l] * goal[l] / (set_size[l] + 1) > max_bndy) { new_domain = bndy_list[k]; max_bndy = bndy_size[l] * goal[l] / (set_size[l] + 1); } } if (new_domain == -1) { printf("Error in connect_enforce: new_domain = -1. Disconnected graph?\n"); new_domain = domain; } /* Clear bndy_size array */ for (k = 0; k < nbndy; k++) bndy_size[bndy_list[k]] = 0; k = clist_ptrs[j]; size = 0; while (k != 0) { vtx = loc2glob[k]; assignment[vtx] = new_domain; size += graph[vtx]->vwgt; /* Finally, update setlists and list_ptrs */ /* Note: current domain setlist now bad, but not used again */ setlists[vtx] = list_ptrs[new_domain]; list_ptrs[new_domain] = vtx; k = comp_lists[k]; } /* printf("Updating set %d (from %d) to size %g\n", new_domain, domain, set_size[new_domain] + size - goal[new_domain]); */ if (heap_map[new_domain] > 0) { set_size[new_domain] += size; heap_update_val(heap, heap_map[new_domain], set_size[new_domain] - goal[new_domain], heap_map); } } sfree(clist_ptrs); sfree(comp_lists); } sfree(comp_flag); } } sfree(heap_map); sfree(heap); sfree(subsets); sfree(loc2glob); sfree(glob2loc); sfree(list_ptrs); sfree(setlists); sfree(bndy_list); sfree(bndy_size); sfree(set_size); *total_move = change; *max_move = max_change; }