void heap_sort(int *c,int start,int end) { int tmp,i; for(i=0;i<end;i++) { max_heap(c,start,end-i); tmp=*c; *c=*(c+end-i); *(c+end-i)=tmp; } }
int FindMedian(std::vector<int> &vec) { std::vector<int> min_heap(1, INT_MAX), max_heap(1, INT_MIN); for (int i = 0; i < vec.size(); i++) { if (vec[i] < max_heap[0]) { if (max_heap.size() > min_heap.size()) { int root = PopHeapRoot(max_heap, true); InsertHeap(min_heap, root, false); } InsertHeap(max_heap, vec[i], true); } else if (vec[i] > min_heap[0]) { if (min_heap.size() >= max_heap.size()) { int root = PopHeapRoot(min_heap, false); InsertHeap(max_heap, root, true); } InsertHeap(min_heap, vec[i], false); } else { if (min_heap.size() >= max_heap.size()) InsertHeap(max_heap, vec[i], true); else InsertHeap(min_heap, vec[i], false); } } return max_heap[0]; }
std::unordered_map<int, std::unordered_map<int, int>> base_balance_algo_for_all( std::unordered_map<int, int>& num_objs) { int average = (int) std::accumulate( num_objs.begin(), num_objs.end(), 0.0, [&](double a, std::pair<int, int> pair) -> double { return a + (double) pair.second / num_objs.size(); }); auto greater = [](const std::pair<int, int>& left, const std::pair<int, int>& right) { return left.second < right.second; }; auto less = [](const std::pair<int, int>& left, const std::pair<int, int>& right) { return left.second > right.second; }; std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, decltype(greater)> max_heap(greater); std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, decltype(less)> min_heap(less); // the minimum number of objects a thread should have int at_least = average; // the maximum number of objects a thread should have int at_most = average + 1; for (auto& v : num_objs) { if (v.second > at_least) { max_heap.push(v); } if (v.second < at_most) { min_heap.push(v); } } // the migration plan // key: source global_tid // value: destination global_tid and number of objects transfered std::unordered_map<int, std::unordered_map<int, int>> res; while (!min_heap.empty() && !max_heap.empty()) { std::pair<int, int> min_pair = min_heap.top(); min_heap.pop(); const int dst_tid = min_pair.first; const int min_obj_num = min_pair.second; int already_moved = 0; while (!max_heap.empty() && min_obj_num + already_moved < at_least) { int num_to_be_moved = 0; std::pair<int, int> max_pair = max_heap.top(); max_heap.pop(); const int src_tid = max_pair.first; const int max_obj_num = max_pair.second; const int at_most_can_move = max_obj_num - at_least; const int need = at_least - (min_obj_num + already_moved); // check whether this thread has enough objects to be moved // if not if (need >= at_most_can_move) { already_moved += at_most_can_move; num_to_be_moved = at_most_can_move; } else { already_moved += need; num_to_be_moved = need; // if it still has excess objects can be moved // push back to the heap if ((max_obj_num - num_to_be_moved) >= at_most) { max_heap.push(std::make_pair(src_tid, max_obj_num - num_to_be_moved)); } } assert(num_to_be_moved >= 0); if (res.find(src_tid) == res.end()) { res[src_tid] = std::unordered_map<int, int>(); } res[src_tid][dst_tid] = num_to_be_moved; } } return res; }