void dijkstra1( long int n, long int s, double *D1, double *P1, double *Gpr, mwIndex *Gir, mwIndex *Gjc) { int finished; long int i, startInd, endInd, whichNeigh, nDone, closest; double closestD, arcLength, INF, SMALL, oldDist; HeapNode *A, *hnMin, hnTmp; FibHeap *heap; INF=mxGetInf(); SMALL=mxGetEps(); // setup heap if ((heap = new FibHeap) == NULL || (A = new HeapNode[n+1]) == NULL ) mexErrMsgTxt( "Memory allocation failed-- ABORTING.\n" ); heap->ClearHeapOwnership(); // initialize for (i=0; i<n; i++) { if (i!=s) A[ i ] = (double) INF; else A[ i ] = (double) SMALL; if (i!=s) D1[ i ] = (double) INF; else D1[ i ] = (double) SMALL; P1[ i ] = -1; heap->Insert( &A[i] ); A[ i ].SetIndexValue( (long int) i ); } // Insert 0 then extract it, which will balance heap heap->Insert(&hnTmp); heap->ExtractMin(); // loop over nonreached nodes finished = nDone = 0; while ((finished==0) && (nDone < n)) { hnMin = (HeapNode *) heap->ExtractMin(); closest = hnMin->GetIndexValue(); closestD = hnMin->GetKeyValue(); if ((closest<0) || (closest>=n)) mexErrMsgTxt( "Minimum Index out of bound..." ); D1[ closest ] = closestD; if (closestD == INF) finished=1; else { // relax all nodes adjacent to closest nDone++; startInd = Gjc[ closest ]; endInd = Gjc[ closest+1 ] - 1; if( startInd!=endInd+1 ) for( i=startInd; i<=endInd; i++ ) { whichNeigh = Gir[ i ]; arcLength = Gpr[ i ]; oldDist = D1[ whichNeigh ]; if ( oldDist > ( closestD + arcLength )) { D1[ whichNeigh ] = closestD + arcLength; // c++ index P1[ whichNeigh ] = closest; hnTmp = A[ whichNeigh ]; hnTmp.SetKeyValue( closestD + arcLength ); heap->DecreaseKey( &A[ whichNeigh ], hnTmp ); } } } } // cleanup delete heap; delete[] A; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *sr,*D,*P,*SS,*Dsmall,*Psmall; int *irs,*jcs; long int M,N,S,MS,NS,i,j,in; HeapNode *A = NULL; FibHeap *theHeap = NULL; if (nrhs != 2) { mexErrMsgTxt( "Only 2 input arguments allowed." ); } else if (nlhs != 1) { mexErrMsgTxt( "Only 1 output argument allowed." ); } M = mxGetM( prhs[0] ); N = mxGetN( prhs[0] ); if (M != N) mexErrMsgTxt( "Input matrix needs to be square." ); SS = mxGetPr(prhs[1]); MS = mxGetM( prhs[1] ); NS = mxGetN( prhs[1] ); if ((MS==0) || (NS==0) || ((MS>1) && (NS>1))) mexErrMsgTxt( "Source nodes are specified in one dimensional matrix only" ); if (NS>MS) MS=NS; plhs[0] = mxCreateDoubleMatrix( MS,M, mxREAL); D = mxGetPr(plhs[0]); Dsmall = (double *) mxCalloc( M , sizeof( double )); if (mxIsSparse( prhs[ 0 ] ) == 1) { /* dealing with sparse array */ sr = mxGetPr(prhs[0]); irs = mxGetIr(prhs[0]); jcs = mxGetJc(prhs[0]); // Setup for the Fibonacci heap for (i=0; i<MS; i++) { if ((theHeap = new FibHeap) == NULL || (A = new HeapNode[M+1]) == NULL ) { mexErrMsgTxt( "Memory allocation failed-- ABORTING.\n" ); } theHeap->ClearHeapOwnership(); S = (long int) *( SS + i ); S--; if ((S < 0) || (S > M-1)) mexErrMsgTxt( "Source node(s) out of bound" ); /* ------------------------------------------------------------------------------------------------- run the dijkstra code ------------------------------------------------------------------------------------------------- */ //mexPrintf( "Working on i=%d\n" , i ); dodijk_sparse( M,N,S,Dsmall,sr,irs,jcs,A,theHeap ); for (j=0; j<M; j++) { *( D + j*MS + i ) = *( Dsmall + j ); //mexPrintf( "Distance i=%d to j=%d =%f\n" , S+1 , j , *( Dsmall + j ) ); } /* ------------------------------------------------------------------------------------------------- end of the dijkstra code ------------------------------------------------------------------------------------------------- */ delete theHeap; delete[] A; } } else mexErrMsgTxt( "Function not implemented for full arrays" ); }