예제 #1
0
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;
}
예제 #2
0
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" );

}