void Topsort( Graph G, Table HT, int N ) { /* 拓扑排序得到解并输出 */ MinHeap Q = (MinHeap)malloc( sizeof( struct HeapStruct ) ); HeapNode Tmp = (HeapNode)malloc( sizeof( struct HeapRecord ) ); int i, j, InDegree[MAXN]; int flag = 0; /* 初始化最小堆 */ Q->Elements = (HeapNode)malloc((G->NumVert+1)*sizeof(struct HeapRecord)); Q->HeapSize = 0; Q->Elements[0].Num = -1; /* 计算初始入度,建立0入度结点的最小堆 */ for ( i=0; i<G->NumVert; i++ ) { InDegree[i] = 0; if ( !(HT->T[i]<0) ) { /* 只对每个非空单元的元素计算入度 */ for ( j=0; j<G->NumVert; j++ ) InDegree[i] += G->M[j][i]; if ( !InDegree[i] ){ /* 入度为0者存入最小堆 */ Tmp->Index = i; Tmp->Num = HT->T[i]; InsertHeap( Tmp, Q ); } } } /* 拓扑排序 */ while ( Q->HeapSize ) { Tmp = DeleteMin( Q ); /* 输出当前数值最小的入度为0的元 */ if ( flag ) printf(" %d", Tmp->Num); /* 输出其它元素,元素前有空格*/ else { printf("%d", Tmp->Num); /* 输出第1个元素,元素前没有空格*/ flag = 1; } /* 将该结点从图中删去 */ i = Tmp->Index; for (j=0; j<G->NumVert; j++ ) { if ( G->M[i][j] ) { InDegree[j]--; if ( !InDegree[j] ) { /* 更新后入度为0者存入最小堆 */ Tmp->Index = j; Tmp->Num = HT->T[j]; InsertHeap( Tmp, Q ); } } } } printf("\n"); }
int* GetSortedArray(int arr[][n],int k){ int size=n*k; int* output=(int*)malloc(sizeof(int)*size); HNode* heapRoot=CreateHeap(k); //printf("\nCapacity : %d",heapRoot->capacity); int i; for(i=0;i<k;i++){ InsertHeap(heapRoot,arr[i][0],i,0); } /* struct HeapNode* tmpNode=ExtractMin(heapRoot); printf("\nData : %d arrayIndex : %d elm Index : %d",tmpNode->data,tmpNode->arrayIndex,tmpNode->elmIndex); tmpNode=ExtractMin(heapRoot); printf("\nData : %d arrayIndex : %d elm Index : %d",tmpNode->data,tmpNode->arrayIndex,tmpNode->elmIndex); InsertHeap(heapRoot,arr[0][1],0,1); tmpNode=ExtractMin(heapRoot); printf("\nData : %d arrayIndex : %d elm Index : %d",tmpNode->data,tmpNode->arrayIndex,tmpNode->elmIndex); */ int index=0; struct HeapNode* tmpNode; int arrayIndex; int elmIndex; while(heapRoot->count>0){ tmpNode=ExtractMin(heapRoot); //printf("\n%d ",tmpNode->data); output[index++]=tmpNode->data; arrayIndex=tmpNode->arrayIndex; elmIndex=tmpNode->elmIndex; if(elmIndex<n-1){ InsertHeap(heapRoot,arr[arrayIndex][elmIndex+1],arrayIndex,elmIndex+1); } } /* while(heapRoot->count){ output[index++]=ExtractMin(heapRoot)->data; }*/ return output; }
void LargestKNumber(const std::vector<int> &vec, int k, std::vector<int> &heap) { heap.insert(heap.end(), vec.begin(), vec.begin() + k); BuildHeap(heap); for (int i = k; i < vec.size(); i++) { if (vec[i] > heap[0]) { heap[0] = heap.back(); heap.pop_back(); Heapify(heap, 0); InsertHeap(heap, vec[i]); } } }
int main() { ElemType arr[] = {1, 7, 5, 3, 8, 6, 15, 13, 14}; int i, n = sizeof(arr)/sizeof(arr[0]); pHeapHeader pHH = (pHeapHeader)malloc(sizeof(struct HeapHeader)); initHeap(pHH, n); createHeap(pHH, arr, n); InsertHeap(pHH, 10); for(i=0; i<pHH->currentSize; i++) { printf("%d\t", (pHH->point)[i]); } printf("\nMaxHeap value: %d\n", RemoveMax(pHH)); for(i=0; i<pHH->currentSize; i++) { printf("%d\t", (pHH->point)[i]); } return 0; }
int main(int argc, char *argv[]) { int into[100]; tvertice outof[100]; tpeso key[] = {9.5, 2, 13.1, 21.22, 29.12, 2.32, 6.12, 5.22, 22.1, 8.4, 2.4}; int nvertices, szheap; int i, j; tpeso menorelem; szheap=0; nvertices = 11; for (i=0; i<nvertices; i++) { InsertHeap(i, key, into, outof, &szheap); ImprimeRamoHeap(0, key, into, outof, szheap); printf("\n\n"); } menorelem = RetiraMenorElemHeap(key, into, outof, &szheap); menorelem = RetiraMenorElemHeap(key, into, outof, &szheap); menorelem = RetiraMenorElemHeap(key, into, outof, &szheap); ImprimeRamoHeap(0, key, into, outof, szheap); printf("\n\n"); AlteraValorHeap(3, 1.5, key, into, outof, szheap); ImprimeRamoHeap(0, key, into, outof, szheap); printf("\n\n"); AlteraValorHeap(9, 2.23, key, into, outof, szheap); ImprimeRamoHeap(0, key, into, outof, szheap); printf("\n\n"); AlteraValorHeap(9, 17, key, into, outof, szheap); ImprimeRamoHeap(0, key, into, outof, szheap); printf("\n"); return(1); }
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]; }
//--------------------------------------------------------------------------- void __fastcall TfKnapsack::btBranchAndBoundClick(TObject *Sender) { //如果已存在 ndHeapArray 先清除 if (ndHeapArray) { delete[] ndHeapArray; ndHeapArray = NULL; } //讀入背包限制 iBagCapacity = StrToInt(edBagCapacity->Text); //產生 Heap 陣列 iHeapCount = 0; ndHeapArray = new Node[iTotalNum +1]; //產生 Heap 的第一個節點 Node u, v; u.iLevel = -1; u.iNowProfit = 0; u.iNowWeight = 0; u.iUpperBound = UpperBound(u); u.iLowerBound = LowerBound(u); InsertHeap(u); Item *itm; int iNowUpper = INT_MAX; while (iHeapCount > 0) { u = DeleteHeap(); if (u.iLevel == iTotalNum-1) continue; v.iLevel = u.iLevel +1; itm = wrItems[v.iLevel].itm; //現在的重量加下一個 Item 的重量沒超過限重 //才去計算 UpperBound 與 LowerBound if (u.iNowWeight + itm->iWeight <= iBagCapacity) { //拿這個東西 v.iNowProfit = u.iNowProfit + itm->iProfit; v.iNowWeight = u.iNowWeight + itm->iWeight; v.iUpperBound = UpperBound(v); v.iLowerBound = LowerBound(v); if (v.iUpperBound > v.iLowerBound && v.iLowerBound < iNowUpper) InsertHeap(v); if (v.iUpperBound < iNowUpper) iNowUpper = v.iUpperBound; } //不拿這個東西 v.iNowProfit = u.iNowProfit; v.iNowWeight = u.iNowWeight; v.iUpperBound = UpperBound(v); v.iLowerBound = LowerBound(v); if (v.iUpperBound > v.iLowerBound && v.iLowerBound < iNowUpper) InsertHeap(v); if (v.iUpperBound < iNowUpper) iNowUpper = v.iUpperBound; } memSolution->Lines->Add("----------------------------------------------"); memSolution->Lines->Add("Maximum possible profit:"); memSolution->Lines->Add(-iNowUpper); }
size_t WeightedMatching(RowStarts *rowptr,ColIndices *colind,ValueType *C, ValueType *C1,ValueType *dist,ValueType *u,ValueType *v,Indices *p, Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){ size_t i,j,i1,jend,k,m_inv_prev; size_t match_size=0; ValueType curr_shortest_path = (ValueType)0; ValueType curr_aug_path = GetMaxTypeValue<ValueType>(); ValueType dist1; Indices itrace; BitArray_t *col_marker = CreateBitArray(n); BitArray_t *heap_marker = CreateBitArray(n); C--;m--;C1--;dist--;u--;v--;p--;m_inv--; rowptr--;colind--; #if BINARY_HEAP Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID); ValueType *dist_ptr = NULL; #endif assert(C1 && dist && u && v && p); ComputeInitialExtremeMatch<ValueType,Indices>(u,v,C1,C,m,m_inv,colind,rowptr,n,dist); match_size=0; for(i=1;i<=n;i++){ if(m_inv[i]){ match_size++; continue; } /* *Aim is to find a value for jend such that the path *from i-->jend is the shortest */ i1 = i; p[i1] = 0; jend=0; itrace=i; ResetAllBits(col_marker); ResetAllBits(heap_marker); #if BINARY_HEAP bin_heap->n = 0; dist_base = (unsigned long)&(dist[1]); #endif curr_shortest_path=(ValueType)0; curr_aug_path=GetMaxTypeValue<ValueType>(); while(1){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; if(CheckBit(col_marker,j)){ continue; } dist1 = curr_shortest_path + C1[k]; /*Prune any dist1's > curr_aug_path, since *all the costs>0 */ if(*((long long int *)&dist1) < *((long long int *)&curr_aug_path)){ if(!m[j]){ /*we need itrace because, the last i1 which *we explore may not actually give the shortest *augmenting path.*/ jend = j; itrace = i1; curr_aug_path = dist1; }else if(*((long long int *)&dist1) < *((long long int *)&(dist[j]))){ /*Update the dist*/ dist[j] = dist1; p[m[j]] = i1; #if SIMPLE_HEAP SetBit(heap_marker,j); #elif BINARY_HEAP if(CheckBit(heap_marker,j)){ DecreaseKey(bin_heap,j); }else{ InsertHeap(bin_heap,&(dist[j])); SetBit(heap_marker,j); } #endif } } } if(*((long long int *)&curr_aug_path) <= *((long long int *)&curr_shortest_path)){ break; } /*We now have a heap of matched cols, so pick the min*/ #ifdef SIMPLE_HEAP j = SimplePickMin(heap_marker,dist,n); if(j){ curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #elif BINARY_HEAP dist_ptr = (ValueType *) HeapDelete(bin_heap); if(dist_ptr){ assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]); j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(double))+1; assert(j>=1 && j<=n); curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #endif SetBit(col_marker,j); i1 = m[j]; }else{ break; } } if(jend){ /*We found a shortest augmenting path*/ j=jend; node_t itrace_prev; //printf("Shortest augmenting Path {"); while(itrace){ m_inv_prev = m_inv[itrace]; m[j] = itrace; m_inv[itrace]=j; //printf("(%u,%u)",itrace,j); j=m_inv_prev; itrace_prev = itrace; itrace = p[itrace]; if(itrace){ // printf("(%u,%u)",itrace_prev,m_inv_prev); } } match_size++; //printf("}\n"); /*Update the cost with new match m*/ for(j=1;j<=n;j++){ if(CheckBit(col_marker,j)){ u[j] = (u[j]+dist[j])-curr_aug_path; /*Reset the dist values*/ } } for(i1=1;i1<=n;i1++){ if(!m_inv[i1]) continue; j = m_inv[i1]; for(k=rowptr[i1];k<rowptr[i1+1];k++){ if(colind[k] == j){ v[i1] = C[k] - u[j]; } } } /*Update the cost*/ for(i1=1;i1<=n;i1++){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; C1[k] = C[k]-(u[j]+v[i1]); } /*The index should be j rather than i1 but just *avoiding another loop*/ dist[i1] = GetMaxTypeValue<double>(); } } } FreeBitArray(col_marker); FreeBitArray(heap_marker); #ifdef BINARY_HEAP FreeHeap(bin_heap); #endif return match_size; } /*O(n) time picking the maximum from the heap_marker */ node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){ node_t min_j=0;node_t j; double curr_min = MAX_DOUBLE_VALUE; for(j=1;j<=n;j++){ if(CheckBit(bit_heap,j) && dist[j] < curr_min){ min_j = j; curr_min = dist[j]; } } return min_j; }
/*-Jesse-************************************************************************** set_index_and_time() takes the voxel passed to it, (ax,ay,az), and if its seedIndex has not previously been set then we set its seedIndex and tdata to the corresponding values passed to the function and insert the point into the heap. We then take advantage of the capsid's icosahedron properties and compute the other 59 symmetrical points. For each of these points if its seedIndex has not been set then we set its seedIndex and tdata to the corresponding values passed to the function, and insert into the heap.*/ void set_index_and_time(int ax, int ay,int az, unsigned char index, float t) { int i,j,k; int m,n; double cx,cy,cz; double mx,my,mz; double sx,sy,sz; double theta,phi; VECTOR sv; /*-Jesse-*************************************************************** (cx,cy,cz) is set to be a point on the first symmetry axis in FiveFold[]. We whift the point so that the axis goes through the origin.*/ cx = FiveFold[0].x-XDIM/2; cy = FiveFold[0].y-YDIM/2; cz = FiveFold[0].z-ZDIM/2; i = ax; j = ay; k = az; /*-Jesse-******************************************************************* If the seed_index has not previously been set, then set seed_index and tdata to the appropriate values passed to the algorithm. Then insert into the heap.*/ if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } /*-Jesse-*********************************************************************** theta and phi are the spherical angles corresponding (cx,cy,cz) being treated as a voxel instead of an axis of rotation.*/ theta = atan2(cy,cx); phi = atan2(cz, sqrt(cx*cx+cy*cy)); /*-Jesse-********************************************************************** (i,j,k) is set to be the initial point passed to the function rotated about the 5-fold axis stored in (cx,cy,cz).*/ for (n = 1; n < 5; n++) { sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,n*2.0f*PIE/5.0f, XDIM, YDIM, ZDIM); i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); /*-Jesse-********************************************************************** It is possible for the rotation to return a point outside our data set. If the rotation gives us a valid point and if the seed_index has not been previously set then we set seed_index, tdata, and insert into the heap.*/ if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } /*-Jesse-************************************************************************* We now make use of the icosahedral symmetry to find the 59 points symmetric to the point passed to set_index_and_time(). We have already found 4 of these points by rotating about (cx,cy,cz) above. We now wish to translate our point to the other axes of rotation and then rotate about each axis. In detail, suppose we have a voxel V1 that we have just rotated about axis A1 and we now wish to rotate about another axis A2. We first find the cross product of A1XA2 and the angle between A1 and A2. We rotate the voxel V1 about A1XA2 by the angle and we get a corresponding voxel V2 in relation to A2. We can then rotate V2 about A2. We then test if the resulting voxels are above tlow, if they are then we set their densities to be negative.*/ for (m = 1; m < 11; m++) { /*-Jesse-*************************************************** (mx,my,mz) is the m'th 5-fold axis centered at the origin.*/ mx = FiveFold[m].x-XDIM/2; my = FiveFold[m].y-YDIM/2; mz = FiveFold[m].z-ZDIM/2; /*-Jesse-*************************** (sx,sy,sz) = (cx,cy,cz)X(mx,my,mz)*/ sx = mz*cy-my*cz; sy = mx*cz-mz*cx; sz = my*cx-mx*cy; theta = atan2(sy,sx); phi = atan2(sz,sqrt(sx*sx+sy*sy)); if (m < 6) sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,ANGL1,XDIM,YDIM,ZDIM); else sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,ANGL2,XDIM,YDIM,ZDIM); /*-Jesse-************************************************************** (sx,sy,sz) = (ax,ay,az) rotated about (cx,cy,cz)X(mx,my,mz) by angle.*/ sx = sv.x; sy = sv.y; sz = sv.z; theta = atan2(my,mx); phi = atan2(mz, sqrt(mx*mx+my*my)); for (n = 0; n < 5; n++) { sv = Rotate(sx,sy,sz,theta,phi,n*2.0f*PIE/5.0f+PIE/5.0f,XDIM,YDIM,ZDIM); /*-Jesse-***************************************************************** (i,j,k) = (ax,ay,az) rotated about (cx,xy,xz)X(mx,my,mz) by angle and then rotated about (mx,my,mz)*/ i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } } /*-Jesse-************************ (mx,my,mz) = second 5-fold axis*/ mx = FiveFold[1].x-XDIM/2; my = FiveFold[1].y-YDIM/2; mz = FiveFold[1].z-ZDIM/2; /*-Jesse-*************************** (sx,sy,sz) = (cx,cy,cz)X(mx,my,mz)*/ sx = mz*cy-my*cz; sy = mx*cz-mz*cx; sz = my*cx-mx*cy; theta = atan2(sy,sx); phi = atan2(sz,sqrt(sx*sx+sy*sy)); sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,PIE,XDIM,YDIM,ZDIM); sx = sv.x; sy = sv.y; sz = sv.z; /*-Jesse-**************************************************************** (i,j,k) = (ax,ay,az) rotated about (cx,cy,cz)X(mx,my,mz) by 180 degrees*/ i = (int)(sx+0.5); j = (int)(sy+0.5); k = (int)(sz+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } /*-Jesse-********************** (mx,my,mz) = last 5-fold axis*/ mx = FiveFold[11].x-XDIM/2; my = FiveFold[11].y-YDIM/2; mz = FiveFold[11].z-ZDIM/2; theta = atan2(my,mx); phi = atan2(mz, sqrt(mx*mx+my*my)); for (n = 1; n < 5; n++) { sv = Rotate(sx,sy,sz,theta,phi,n*2.0f*PIE/5.0f,XDIM,YDIM,ZDIM); /*-Jesse-********************************************************************************** (i,j,k) = (cx,cy,cz)X[(cx,cy,cz)X(second 5-fold axis)] rotated about the last 5-fold axis*/ i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } }
void ExtractSES(MinHeapS *mheap, SEEDS *all_seeds, int *heappointer, int xd, int yd, int zd, int *atom_index, int atom_num, ATOM *atomlist, float thresh) { int i,j,k; int m,n,l, num, c; int index,index1; float dist; FLTVECT seed; char visited; xdim1 = xd; ydim1 = yd; zdim1 = zd; atom_list = atomlist; min_heap = mheap; AllSeeds = all_seeds; heap_pointer = heappointer; threshold = thresh; /* Initialize */ index = 0; min_heap->size = 0; for (k=0; k<zdim1; k++) for (j=0; j<ydim1; j++) for (i=0; i<xdim1; i++) { if (atom_index[IndexVect1(i,j,k)] < 0) { for (num = 0; num < MaxAtom; num++) AllSeeds[index].atom[num] = -1; num = 0; for (l=k-1; l<=k+1; l++) for (n=j-1; n<=j+1; n++) for (m=i-1; m<=i+1; m++) { if (m==i||n==j||l==k) { index1 = atom_index[IndexVect1(m,n,l)]; if (index1 < 0) { index1 = -index1-1; visited = 0; for (c=0; c<num; c++) { if (index1 == AllSeeds[index].atom[c]) visited = 1; } if (visited == 0) { AllSeeds[index].atom[num] = index1; num++; if (num == MaxAtom) num--; } } } } seed = FindSeed(i,j,k,index); AllSeeds[index].seedx = seed.x; AllSeeds[index].seedy = seed.y; AllSeeds[index].seedz = seed.z; dist = (seed.x-i)*(seed.x-i) + (seed.y-j)*(seed.y-j) + (seed.z-k)*(seed.z-k); min_seed = index; InsertHeap(i,j,k, dist); index++; } else if (atom_index[IndexVect1(i,j,k)] > 0) { heap_pointer[IndexVect1(i,j,k)] = MaxVal; } else { heap_pointer[IndexVect1(i,j,k)] = -11; } } /* Fast Marching Method */ while (1){ GetMinimum(); if (min_dist >= MaxDist-0.001) break; Marching(); } }
void Marching(void) { int tempt_x, tempt_y, tempt_z; float dt,dist; int neighbor,seed; char boundary; float min_seedx, min_seedy, min_seedz; float seedx, seedy, seedz; min_seedx = AllSeeds[min_seed].seedx; min_seedy = AllSeeds[min_seed].seedy; min_seedz = AllSeeds[min_seed].seedz; boundary = 0; /* ============================ */ tempt_x=max(min_x-1,0); tempt_y=min_y; tempt_z=min_z; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } //else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -11) { /* ============================ */ tempt_x=min(min_x+1,xdim1-1); tempt_y=min_y; tempt_z=min_z; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } /* ============================ */ tempt_y=max(min_y-1,0); tempt_x=min_x; tempt_z=min_z; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } /* ============================ */ tempt_y=min(min_y+1,ydim1-1); tempt_x=min_x; tempt_z=min_z; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } /* ============================ */ tempt_z=max(min_z-1,0); tempt_x=min_x; tempt_y=min_y; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } /* ============================ */ tempt_z=min(min_z+1,zdim1-1); tempt_x=min_x; tempt_y=min_y; if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] == MaxVal) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx)+(tempt_y-min_seedy)*(tempt_y-min_seedy)+(tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist <= threshold) InsertHeap(tempt_x, tempt_y, tempt_z, dist); else boundary = 1; } else if (heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)] > -1) { neighbor = heap_pointer[IndexVect1(tempt_x,tempt_y,tempt_z)]; dt = min_heap->dist[neighbor]; if (dt < MaxDist) { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); if (dist < dt) UpdateHeap(tempt_x, tempt_y, tempt_z, dist); } else { dist = (tempt_x-min_seedx)*(tempt_x-min_seedx) + (tempt_y-min_seedy)*(tempt_y-min_seedy) + (tempt_z-min_seedz)*(tempt_z-min_seedz); seed = min_heap->seed[neighbor]; seedx = AllSeeds[seed].seedx; seedy = AllSeeds[seed].seedy; seedz = AllSeeds[seed].seedz; if (dist < (tempt_x-seedx)*(tempt_x-seedx)+(tempt_y-seedy)*(tempt_y-seedy)+(tempt_z-seedz)*(tempt_z-seedz)) UpdateHeap(tempt_x, tempt_y, tempt_z, MaxDist); } } if (boundary) InsertHeap(min_x,min_y,min_z, MaxDist); }
size_t WeightedMatching(RowStarts rowptr,ColIndices colind,ValueTypePtr C, ValueTypePtr dist,ValueTypePtr u,ValueTypePtr v,Indices *p, Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){ typedef typename std::iterator_traits<ValueTypePtr>::value_type ValueType; Indices i,j,i1,jend,k,m_inv_prev; Indices match_size=0; Indices k0,j0; ValueType curr_shortest_path = (ValueType)0; ValueType curr_aug_path = GetMaxTypeValue<ValueType>(curr_aug_path); ValueType dist1; Indices itrace; /*Cost of the edges in the match if *$(i,j) \in M$ then $clabel[i] = C[i][j]$*/ Indices *clabel = new Indices[n]; Indices *aug_label = new Indices[n]; Indices *update_stack = new Indices[n]; Indices update_stack_index; /*Save The Operations on the Heap.*/ Indices save_heap_index; Indices *save_heap_op = new Indices[n]; #ifdef TURN_ON_SAVE_HEAP double close_factor = (double)1.0 + (double)1.0e-16; #endif /*Force the write back to memory to avoid floating point issues*/ ValueType force_mem_write[3]; #ifndef NO_LOCAL_PROFILING CreateProfilingClocks(); #endif /*Core Profiling Clock*/ Clock *core_clk = CreateClock(); #ifdef USE_BIT_ARRAY BitArray_t *col_marker = CreateBitArray(n); BitArray_t *heap_marker = CreateBitArray(n); #else Indices *col_marker = new Indices[n]; unsigned int *heap_marker = NULL; col_marker--; for(i=1;i<=n;i++){ /*Do we need Initialization?*/ col_marker[i] = (Indices)0; } #endif #if BINARY_HEAP Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID); ValueType *dist_ptr = NULL; heap_marker = bin_heap->keyMap; #endif /*Algorithm Uses 1-Indexing to be consistent*/ C--;m--;dist--;u--;v--;p--;m_inv--; rowptr--;colind--;clabel--;save_heap_op--; update_stack--;aug_label--; assert(dist && u && v && p); ComputeInitialExtremeMatch<ValueType,Indices>(u,v,clabel,C,m,m_inv,colind, rowptr,n,dist); match_size=0; StartClock(core_clk); for(i=1;i<=n;i++){ if(m_inv[i]){ match_size++; continue; } /* *Aim is to find a value for jend such that the path *from i-->jend is the shortest */ i1 = i; p[i1] = 0; jend=0; itrace=i; #ifdef USE_BIT_ARRAY ResetAllBits(col_marker); ResetAllBits(heap_marker); #endif #if BINARY_HEAP bin_heap->n = 0; dist_base = (unsigned long)&(dist[1]); #endif curr_shortest_path=(ValueType)0; curr_aug_path=GetMaxTypeValue<ValueType>(curr_aug_path); save_heap_index = (Indices)0; update_stack_index = (Indices)0; while(1){ for(k=rowptr[i1]+1;k<(rowptr[i1+1]+1);k++){ j = colind[k]+1; #ifdef USE_BIT_ARRAY if(CheckBit(col_marker,j)){ #else if(col_marker[j]==i){ #endif continue; } force_mem_write[k%3] = C[k]-(v[i1]+u[j]); dist1 = curr_shortest_path + force_mem_write[k%3]; /*Prune any dist1's > curr_aug_path, since *all the costs>0 */ if(dist1 < curr_aug_path){ if(!m[j]){ /*we need itrace because, the last i1 which *we explore may not actually give the shortest *augmenting path.*/ jend = j; itrace = i1; curr_aug_path = dist1; aug_label[j] = k; }else if(dist1 < dist[j]){ /*Update the dist*/ dist[j] = dist1; p[m[j]] = i1; aug_label[j] = k; #if SIMPLE_HEAP #ifdef USE_BIT_ARRAY SetBit(heap_marker,j); #else heap_marker[j] = i; #endif #elif BINARY_HEAP /*SIMPLE_HEAP*/ #ifdef USE_BIT_ARRAY if(CheckBit(heap_marker,j)){ #else if(heap_marker[j]){ #endif #ifndef NO_LOCAL_PROFILING StartClock(hupdate_clk); #endif /*Call the decrease Key Operation*/ DecreaseKey(bin_heap,j); #ifndef NO_LOCAL_PROFILING StopClock(hupdate_clk); hupdate_ticks += GetClockTicks(hupdate_clk); #endif } #ifdef TURN_ON_SAVE_HEAP else if(curr_shortest_path && dist[j] <= (curr_shortest_path)*(close_factor)){ /*If dist[j] is close to root push it in *save_heap_op*/ assert(save_heap_index < n); save_heap_op[++save_heap_index] = j; } #endif else{ #ifndef NO_LOCAL_PROFILING StartClock(hins_clk); #endif InsertHeap(bin_heap,&(dist[j])); #ifndef NO_LOCAL_PROFILING StopClock(hins_clk); hins_ticks += GetClockTicks(hins_clk); #endif #ifdef USE_BIT_ARRAY SetBit(heap_marker,j); #endif } #endif /*SIMPLE_HEAP*/ } } } if(curr_aug_path <= curr_shortest_path){ break; } /*We now have a heap of matched cols, so pick the min*/ #ifdef SIMPLE_HEAP j = SimplePickMin(heap_marker,dist,n); if(j){ curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #elif BINARY_HEAP #ifndef NO_LOCAL_PROFILING StartClock(hdel_clk); #endif if(save_heap_index){ j = save_heap_op[save_heap_index]; save_heap_index--; curr_shortest_path = dist[j]; #ifdef USE_BIT_ARRAY SetBit(col_marker,j); #else col_marker[j] = (Indices)i; update_stack[++update_stack_index]=j; #endif /*#ifdef USE_BIT_ARRAY*/ i1 = m[j]; }else if(dist_ptr = (ValueType *) HeapDelete(bin_heap)) { #ifndef NO_LOCAL_PROFILING StopClock(hdel_clk); hdel_ticks += GetClockTicks(hdel_clk); #endif assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]); j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; assert(j>=1 && j<=n); curr_shortest_path = dist[j]; heap_marker[j] = 0; /*Setting the keyMap in Heap to 0*/ #endif /*#ifdef SIMPLE_HEAP */ #ifdef USE_BIT_ARRAY SetBit(col_marker,j); update_stack[++update_stack_index]=j; #else col_marker[j] = (Indices)i; update_stack[++update_stack_index]=j; #endif /*#ifdef USE_BIT_ARRAY*/ i1 = m[j]; }else{ break; } } /*We found a shortest augmenting path*/ if(jend){ unsigned long **harray = bin_heap->heapArray; #ifndef NO_LOCAL_PROFILING StartClock(dual_clk); #endif /*NOTE1: We need a very fast way to update *the dual variables and also reset the dist[] *we avoid linear scan where ever we can to update *these dual variables*/ while(update_stack_index){ /*Update u[j]: while*/ j=update_stack[update_stack_index--]; u[j] = (u[j]+dist[j])-curr_aug_path; if(m[j]){ /*See NOTE1*/ i1 = m[j]; v[i1] = C[clabel[i1]] - u[j]; } dist[j] = MAX_DOUBLE_VALUE; if(bin_heap->n){ dist_ptr = (double *)harray[bin_heap->n]; j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; heap_marker[j] = 0; *((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE; bin_heap->n -= 1 ; } } /*Update u[j]: while*/ /*Uncomment if you need to print augmenting path*/ /*node_t itrace_prev;*/ /*printf("Shortest augmenting Path {");*/ j=jend; while(itrace){ m_inv_prev = m_inv[itrace]; m[j] = itrace; m_inv[itrace]=j; /*See NOTE1(above)*/ clabel[itrace] = aug_label[j]; v[itrace] = C[clabel[itrace]] - u[j]; /*printf("(%u,%u)",itrace,j);*/ j=m_inv_prev; /*itrace_prev = itrace;*/ itrace = p[itrace]; /* if(itrace){ printf("(%u,%u)",itrace_prev,m_inv_prev); }*/ } /*printf("}\n");*/ /*There may some dist[] still in the heap*/ while(bin_heap->n){ dist_ptr = (double *)harray[bin_heap->n]; j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(ValueType))+1; heap_marker[j] = 0; *((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE; bin_heap->n -= 1; } match_size++; /*End Dual Update*/ #ifndef NO_LOCAL_PROFILING StopClock(dual_clk); dual_ticks += GetClockTicks(dual_clk); #endif } /*if(jend) : Found Augmeting Path*/ } /*for(i=1;i<=n;i++): Main Outer Loop*/ StopClock(core_clk); WeightedMatchTicks = GetClockTicks(core_clk); #ifndef NO_LOCAL_PROFILING printf("Profile Summary\n"); printf("HINS=(%d) HDEL=(%d) HUPDATE=(%d)\n",(int)hins_ticks,(int)hdel_ticks, (int)hupdate_ticks); printf("DUAL=(%d) \n",(int)dual_ticks); #endif #ifdef USE_BIT_ARRAY FreeBitArray(col_marker); FreeBitArray(heap_marker); #else col_marker++; delete col_marker; #endif #ifdef SIMPLE_HEAP heap_marker++; delete heap_marker; #endif aug_label++; delete aug_label; save_heap_op++; delete save_heap_op; clabel++; delete clabel; #ifdef BINARY_HEAP FreeHeap(bin_heap); #endif return match_size; } /*O(n) time picking the maximum from the heap_marker */ node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){ node_t min_j=0;node_t j; double curr_min = HUGE_VAL; for(j=1;j<=n;j++){ if(CheckBit(bit_heap,j) && dist[j] < curr_min){ min_j = j; curr_min = dist[j]; } } return min_j; } #ifdef BINARY_HEAP inline keyid_t GetDistKeyID(void *dist_ptr){ assert((unsigned long)dist_ptr >= dist_base); return (((((unsigned long)dist_ptr-dist_base))/sizeof(double))+1); } #endif BitArray_t* CreateBitArray(unsigned int size){ div_t d = div(size,SIZE_OF_BYTE_IN_BITS); BitArray_t *bits = (BitArray_t *)malloc(sizeof(BitArray_t)*1); assert(bits); bits->size = (d.rem > 0)?(d.quot+1):d.quot; bits->ba = (char *)malloc(sizeof(char)*(bits->size)); assert(bits->ba); memset(bits->ba,'\0',bits->size); return bits; }