bool BinaryHeap :: updateKey(Location nodeAddress, Priority newKey) { BinaryNode * node; if(nodeAddress == NULL) return false; node = (BinaryNode *) nodeAddress; if (newKey < node->key) return decreaseKey(nodeAddress,newKey); else if (newKey > node->key) return increaseKey(nodeAddress,newKey); else return true; }
// increase the key of given node by the given value bool BinaryHeap :: increaseKey(Location nodeAddress, Priority newKey) { Priority data=newKey; BinaryNode *x,*y=(BinaryNode*)nodeAddress; x=y; if(y==NULL || (newKey <= y->key)) //check for a invalid input return -1; else{ //update the given node by that key y->key=newKey; setLocation(y,y->key); //check which key has to be change right or left ?? if(y->leftChild!=NULL && y->leftChild->key < newKey){ data=y->leftChild->key; x=y->leftChild; } if(y->rightChild!=NULL && (y->rightChild->key < newKey)){ if(data >y->rightChild->key) { data=y->rightChild->key; x=y->rightChild; } } //modify the heap according to respective changes if(y->leftChild==x){ y->key=y->leftChild->key ; setLocation(y,y->key); increaseKey(y->leftChild,newKey); } else if(y->rightChild==x){ y->key=y->rightChild->key ; setLocation(y,y->key); increaseKey(y->rightChild,newKey); } } return 0; }
// delete the given node from the heap bool BinaryHeap :: deleteKey(Location nodeAddress) { BinaryNode *x,*z,*y=(BinaryNode*)nodeAddress; Priority datakey =lastElement->key; x=lastElement; //updation of pointers if(root==NULL || y==NULL ) return false; else if(y==root && y->leftChild==NULL && y->rightChild==NULL) root=lastElement=NULL; else if(x->parent->rightChild==x){ x->parent->rightChild=NULL; lastElement=x->parent->leftChild; x->leftSibling->rightSibling=NULL; } else if(x->parent->leftChild==x) { x->parent->leftChild=NULL; if(x->parent==root) lastElement=root; else { if(x->parent->leftSibling==NULL) { z=x->parent; while(z->rightSibling!=NULL) { z=z->rightSibling; } lastElement=z; } else{ lastElement=x->parent->leftSibling->rightChild; x->parent->leftSibling->rightChild->rightSibling=NULL; } } } keyToAddress.erase(x->key); delete x; //delete the node // heapify the given heap if(y->key < datakey) increaseKey(y,datakey); else if(y->key > datakey) decreaseKey(y,datakey); return true; }
void TopoCentLB :: increaseKey(HeapNode *heap,int i,double wt){ if(wt != -1.00){ #ifdef MAX_EDGE if(wt>heap[i].key) heap[i].key = wt; #else heap[i].key += wt; #endif } int parent = (i-1)/2; if(heap[parent].key >= heap[i].key) return; else { HeapNode tmp = heap[parent]; heap[parent] = heap[i]; heap[i] = tmp; heapMapping[heap[parent].node]=parent; heapMapping[heap[i].node]=i; increaseKey(heap,parent,-1.00); } }
orderedQueue insert(int key, T value){ A.push_back(std::pair<int, T>(-(1<<17),value)); increaseKey(A.size(), key); }
/*The algorithm uses an idea similar to the standard MST algorithm*/ void TopoCentLB :: calculateMST(PartGraph *partgraph,LBTopology *topo,int *proc_mapping,int max_comm_part) { int *inHeap; double *keys; int count = partgraph->n_nodes; int i=0,j=0; //Arrays needed for keeping information inHeap = new int[partgraph->n_nodes]; keys = new double[partgraph->n_nodes]; int *assigned_procs = new int[count]; hopCount = new double*[count]; for(i=0;i<count;i++){ proc_mapping[i]=-1; assigned_procs[i]=0; hopCount[i] = new double[count]; for(j=0;j<count;j++) hopCount[i][j] = 0; } //Call a topology routine to fill up hopCount topo->get_pairwise_hop_count(hopCount); int max_neighbors = topo->max_neighbors(); HeapNode *heap = new HeapNode[partgraph->n_nodes]; heapMapping = new int[partgraph->n_nodes]; int heapSize = 0; for(i=0;i<partgraph->n_nodes;i++){ heap[i].key = 0.00; heap[i].node = i; keys[i] = 0.00; inHeap[i] = 1; heapMapping[i]=i; } //Assign the max comm partition first heap[max_comm_part].key = 1.00; heapSize = partgraph->n_nodes; BuildHeap(heap,heapSize); int k=0,comm_cnt=0,m=0; int *commParts = new int[partgraph->n_nodes]; //srand(count); while(heapSize > 0){ /****Phase1: Extracting appropriate partition from heap****/ HeapNode max = extractMax(heap,&heapSize); inHeap[max.node] = 0; for(i=0;i<partgraph->n_nodes;i++){ commParts[i]=-1; PartGraph::Edge wt = partgraph->edges[max.node][i]; if(wt == 0) continue; if(inHeap[i]){ #ifdef MAX_EDGE if(wt>keys[i]) keys[i]=wt; #else keys[i] += wt; #endif /*This part has been COMMENTED out for optimizing the code: we handle the updation using heapMapping*/ /*array instead of searching for node in the heap everytime*/ //Update in the heap too //First, find where this node is..in the heap /*for(j=0;j<heapSize;j++) if(heap[j].node == i) break; if(j==heapSize) CmiAbort("Some error in heap...\n");*/ increaseKey(heap,heapMapping[i],wt); } } /*Phase2: ASSIGNING partition to processor*/ //Special case if(heapSize == partgraph->n_nodes-1){ //Assign max comm partition to 0th proc in the topology proc_mapping[max.node]=0; assigned_procs[0]=1; continue; } m=0; comm_cnt=0; double min_cost=-1; int min_cost_index=-1; double cost=0; int p=0; //int q=0; for(k=0;k<partgraph->n_nodes;k++){ if(!inHeap[k] && partgraph->edges[k][max.node]){ commParts[comm_cnt]=k; comm_cnt++; } } //Optimized the loop by commenting out the get_hop_count code and getting all the hop counts initially for(m=0;m<count;m++){ if(!assigned_procs[m]){ cost=0; for(p=0;p<comm_cnt;p++){ //if(!hopCount[proc_mapping[commParts[p]]][m]) //hopCount[proc_mapping[commParts[p]]][m]=topo->get_hop_count(proc_mapping[commParts[p]],m); cost += hopCount[proc_mapping[commParts[p]]][m]*partgraph->edges[commParts[p]][max.node]; } if(min_cost==-1 || cost<min_cost){ min_cost=cost; min_cost_index=m; } } } proc_mapping[max.node]=min_cost_index; assigned_procs[min_cost_index]=1; } //clear up memory delete[] inHeap; delete[] keys; delete[] assigned_procs; delete[] heap; delete[] commParts; }
int main() { ElementType data[] = {85, 80, 40, 30, 10, 70, 110}; // P141 ElementType buildHeapData[] = {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130}; BinaryHeap bh; int size; int i; int capacity; printf("\n\t=== test for inserting the binary heap with {85, 80, 40, 30, 10, 70, 110} in turn ===\n"); capacity = 14; bh = initBinaryHeap(capacity); size = 7; for(i = 0; i < size; i++) insert(data[i], bh); printBinaryHeap(bh); printf("\n\t=== test for inserting the binary heap with {100, 20, 90} in turn ===\n"); insert(100, bh); insert(20, bh); insert(90, bh); printBinaryHeap(bh); printf("\n\t=== test for inserting the binary heap with 5 ===\n"); insert(5, bh); printBinaryHeap(bh); printf("\n\t=== test for 3 deletings towards the minimum in binary heap ===\n"); deleteMin(bh); printBinaryHeap(bh); deleteMin(bh); printBinaryHeap(bh); deleteMin(bh); printBinaryHeap(bh); // other operations in bianry heap printf("\n\t====== test for other operations in bianry heap as follows ======\n"); printf("\n\t=== test for increaseKey(4, 120, bh) ===\n"); increaseKey(4, 120, bh); printBinaryHeap(bh); printf("\n\t=== test for increaseKey(2, 120, bh) ===\n"); increaseKey(2, 120, bh); printBinaryHeap(bh); printf("\n\t=== test for decreaseKey(9, 195, bh) ===\n"); decreaseKey(9, 195, bh); printBinaryHeap(bh); printf("\n\t=== test for decreaseKey(4, 90, bh) ===\n"); decreaseKey(4, 90, bh); printBinaryHeap(bh); printf("\n\t=== test for decreaseKey(7, 50, bh) ===\n"); decreaseKey(7, 50, bh); printBinaryHeap(bh); printf("\n\t=== test for decreaseKey(5, 155, bh) ===\n"); decreaseKey(5, 155, bh); printBinaryHeap(bh); printf("\n\t=== test for deleteElement(4, bh) ===\n"); deleteElement(4, bh); printBinaryHeap(bh); printf("\n\t=== test for deleteElement(1, bh) ===\n"); deleteElement(1, bh); printBinaryHeap(bh); printf("\n\t=== test for deleteElement(3, bh) ===\n"); deleteElement(3, bh); printBinaryHeap(bh); // test over , Bingo! // as you know, the build heap operation is identical with other operations printf("\n\t=== test for building heap with {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130} ===\n"); capacity = 16; bh = initBinaryHeap(capacity); bh->size = 15; bh->elements = buildHeapData; buildHeap(bh); printBinaryHeapFromZero(bh); return 0; }