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;
}
Example #2
0
void test_sequential_random_Insert_DeleteMin(){
	
	FibHeap fib;
	priority_queue<int> ref_q;
	int NUM_NODES = 100000;
	
	for (int i = 0; i < NUM_NODES; i++){
		int curr = 	rand();
		fib.insertNode(curr);
		ref_q.push(-curr);			
		}

	for (int i = 0; i < NUM_NODES; i++){
		int val= fib.deleteMin();
		int ref = -ref_q.top();
		ref_q.pop();
	
		if (val != ref){
			cout << "\n Our value: " << val << " Ref Value: " << ref;
			return;
		}
	}
	cout << "\n Sequential Insert then Delete Succeeded";

	for (int i = 0; i < NUM_NODES; i++){
		int curr = 	rand();
		fib.insertNode(curr);
		ref_q.push(-curr);			
		if (i%50 == 0){
		int num_deletes = rand() % fib.getSize()+1;
			for (int j = 0; j < num_deletes; j++){
				int val= fib.deleteMin();
				int ref = -ref_q.top();
				ref_q.pop();
			
				if (val != ref){
					cout << "\n Random : Our value: " << val << " Ref Value: " << ref;
					return;
				}
			}
		}
	}
	cout << "\n Random Insert and Delete Succeeded";

}
Example #3
0
/* 	 
 * Adaptive Randomized Sampling Algorithm for Weighted graphs. The cut-off on the number of samples is n/20. 
*/ 
void Adaptive_Sampling_Weighted(f64 ACB[], NETWORK *network, f64 c_thr, f64 sup, f64 &time_dif) { 
	
	ui64 i, j, u, v, numSample, randvx;
	ui64 nvertices = (ui64) network->nvertices;	// The number of vertices in the network
	ui64 count = 0; 
	f64 u_distance, v_distance, edgeWeight;		// Variables to store distance estimates or edge weights
	
	time_t start, end;							// Time variables
	
	vector<ui64> sigma;							// sigma is the number of shortest paths
	vector<f64> delta;							// A vector storing dependency of the source vertex on all other vertices
	vector< vector <ui64> > PredList;			// A list of predecessors of all vertices 
	
	vector<ui64> SampleVertex; 
	vector<ui64>::iterator it;					// An iterator of vector elements
	vector<bool> Flag; 
	
	stack <ui64> S;								// A stack containing vertices in the order found by Dijkstra's Algorithm
	
	FibHeap PQueue;								// A priority queue storing vertices
	FibHeapNode nodeTemp;						// A particular node stored in the priority queue
	FibHeapNode *nodePtr;						// Pointer to a vertex element stored in the priority queue
	vector<FibHeapNode *> nodeVector;			// A vector of all priority queue elements 
	
	// Set the start time of Randomized Brandes' Algorithm
	time(&start); 

	nodeVector.assign ( nvertices, NULL );
	for (i=0; i < nvertices; i++) {
		nodeVector[i] = new FibHeapNode(); 
		nodeVector[i]->Set_vertexPosition(i); 
		//Set all Nodes distance to unsigned long max ULONG_MAX that is assumed to be infinity
		nodeVector[i]->Set_key(ULONG_MAX); 
	}
	
	// Generate random seed 
	srand((unsigned)time(NULL)); 
	
	numSample = (ui64) (nvertices/sup); 
	
	if (numSample < 1) 
		numSample = nvertices; 
	
	SampleVertex.resize(numSample); 
	Flag.assign(nvertices, false); 
	
	for (i=0; i < numSample; i++) {
		
		// Generate a random vertex
		randvx = (ui64) ((((f64) rand())/((f64) RAND_MAX + 1.0))*nvertices); 
		
		// Insert the randomly sampled vertex
		SampleVertex.push_back(randvx); 
	}
	
	// Compute Randomized Betweenness Centrality using sampled vertices
	for (it= SampleVertex.begin(); it < SampleVertex.end(); it++) {
		
		count += 1;
		i = *it; 
		
		/* Initialize */ 
		PredList.assign(nvertices, vector <ui64> (0, 0)); 
		sigma.assign(nvertices, 0); 
		sigma[i] = 1; 
		delta.assign(nvertices, 0); 
		
		nodeVector[i]->Set_key(0); 
		PQueue.Insert(nodeVector[i]); 
		
		// While the priority queue is nonempty 
		while (PQueue.GetNumNodes() != 0) {
			// Get the element in the priority queue with the minimum key 
			nodePtr = PQueue.ExtractMin(); 
			// Get the vertex corresponding to the queue element with the minimum key
			u = nodePtr->Get_vertexPosition(); 
			// Push u onto the stack S. Needed later for betweenness computation
			S.push(u); 
			// Shortest path distance from source i to vertex u
			u_distance = nodeVector[u]->Get_key(); 
			// Iterate over all the neighbors of u 
			for (j=0; j < (ui64) network->vertex[u].degree; j++) { 
				// Get the neighbor v of vertex u
				v = (ui64) network->vertex[u].edge[j].target; 
				// Get the weight of the edge (u,v) 
				edgeWeight = (f64) network->vertex[u].edge[j].weight; 
				// If v's shortest path distance estimate has not been set yet, then 
				// set the distance estimate of v and store v in the priority queue
				if (nodeVector[v]->Get_key() == ULONG_MAX) {
					nodeVector[v]->Set_key(u_distance + edgeWeight); 
					PQueue.Insert(nodeVector[v]); 
				}
				// Get the current shortest path distance estimate of v
				v_distance = nodeVector[v]->Get_key(); 
				
				/* Relax and Count */ 
				if (v_distance == u_distance + edgeWeight) { 
					sigma[v] += sigma[u]; 
					PredList[v].push_back(u); 
				}
				if (v_distance > u_distance + edgeWeight) {
					sigma[v] = sigma[u]; 
					PredList[v].clear(); 
					PredList[v].push_back(u); 
					nodeTemp.Set_vertexPosition(v); 
					nodeTemp.Set_key(u_distance + edgeWeight); 
					if (PQueue.DecreaseKey(nodeVector[v], nodeTemp) != 0) 
						cout << "Error decreasing the node key" << endl; 
				}
				
			} // End For 
			
		} // End While
		
		
		/* Accumulation */ 
		while (!S.empty()) { 
			u = S.top(); 
			S.pop(); 
			for (j=0; j < PredList[u].size(); j++) {
				delta[PredList[u][j]] += ((f64) sigma[PredList[u][j]]/sigma[u]) * (1+delta[u]); 
			}
			
			if ((u != i) && (!Flag[u])) {
				ACB[u] += delta[u]; 
				if (ACB[u] > c_thr * nvertices) {
					ACB[u] = nvertices * (ACB[u]/count);
					Flag[u] = true;
				}
			} // End If 
			
		} // End While
		
		// Clear data for the next run
		PredList.clear(); 
		sigma.clear(); 
		delta.clear(); 
		for (j=0; j < nvertices; j++) 
			nodeVector[j]->Set_key(ULONG_MAX); 
		
	} // End For 
	
	for (i=0; i < nvertices; i++) {
		if (!Flag[i]) {
			ACB[i] = nvertices * (ACB[i]/numSample); 
		}
	}
	
	// End time after Brandes' algorithm and the time difference
	time(&end); 
	time_dif = difftime(end, start); 
	cout << "It took " << time_dif << " seconds to calculate Adaptive Sampling Based Approximate Centrality Values in a weighted graph" << endl;
	
	// Deallocate memory 
	for (i=0; i < nvertices; i++) 
		delete nodeVector[i]; 
	return; 
	
} // End of Adaptive_Sampling_Weighted 
Example #4
0
/* 
 * Brandes Algorithm for weighted graphs
 */ 
void BrandesAlgorithm_Weighted(f64 CB[], NETWORK *network, f64 &time_dif) { 
	
	ui64 i, j, u, v;
	ui64 nvertices = (ui64) network->nvertices;	// The number of vertices in the network
	f64 u_distance, v_distance, edgeWeight;		// Variables to store distance estimates or edge weights
	
	time_t start, end;							// Time variables
	
	vector<ui64> sigma;							// sigma is the number of shortest paths
	vector<f64> delta;							// A vector storing dependency of the source vertex on all other vertices
	vector< vector <ui64> > PredList;			// A list of predecessors of all vertices 
	
	stack <ui64> S;								// A stack containing vertices in the order found by Dijkstra's Algorithm
	
	FibHeap PQueue;								// A priority queue storing vertices
	FibHeapNode nodeTemp;						// A particular node stored in the priority queue
	FibHeapNode *nodePtr;						// Pointer to a vertex element stored in the priority queue
	vector<FibHeapNode *> nodeVector;			// A vector of all priority queue elements 
	
	// Set the start time of Brandes' Algorithm
	time(&start); 

	nodeVector.assign ( nvertices, NULL );
	for (i=0; i < nvertices; i++) {
		nodeVector[i] = new FibHeapNode(); 
		nodeVector[i]->Set_vertexPosition(i); 
		//Set all Nodes distance to unsigned long max ULONG_MAX that is assumed to be infinity
		nodeVector[i]->Set_key(ULONG_MAX); 
	}
	
	// Compute Betweenness Centrality for every vertex i
	for (i=0; i < nvertices; i++) {
		
		/* Initialize */ 
		PredList.assign(nvertices, vector <ui64> (0, 0)); 
		sigma.assign(nvertices, 0); 
		sigma[i] = 1; 
		delta.assign(nvertices, 0); 
		
		nodeVector[i]->Set_key(0); 
		PQueue.Insert(nodeVector[i]); 
		
		// While the priority queue is nonempty 
		while (PQueue.GetNumNodes() != 0) {
			// Get the element in the priority queue with the minimum key 
			nodePtr = PQueue.ExtractMin(); 
			// Get the vertex corresponding to the queue element with the minimum key
			u = nodePtr->Get_vertexPosition(); 
			// Push u onto the stack S. Needed later for betweenness computation
			S.push(u); 
			// Shortest path distance from source i to vertex u
			u_distance = nodeVector[u]->Get_key(); 
			// Iterate over all the neighbors of u 
			for (j=0; j < (ui64) network->vertex[u].degree; j++) { 
				// Get the neighbor v of vertex u
				v = (ui64) network->vertex[u].edge[j].target; 
				// Get the weight of the edge (u,v) 
				edgeWeight = (f64) network->vertex[u].edge[j].weight; 
				// If v's shortest path distance estimate has not been set yet, then 
				// set the distance estimate of v and store v in the priority queue
				if (nodeVector[v]->Get_key() == ULONG_MAX) {
					nodeVector[v]->Set_key(u_distance + edgeWeight); 
					PQueue.Insert(nodeVector[v]); 
				}
				// Get the current shortest path distance estimate of v
				v_distance = nodeVector[v]->Get_key(); 
				
				/* Relax and Count */ 
				if (v_distance == u_distance + edgeWeight) { 
					sigma[v] += sigma[u]; 
					PredList[v].push_back(u); 
				}
				if (v_distance > u_distance + edgeWeight) {
					sigma[v] = sigma[u]; 
					PredList[v].clear(); 
					PredList[v].push_back(u); 
					nodeTemp.Set_vertexPosition(v); 
					nodeTemp.Set_key(u_distance + edgeWeight); 
					if (PQueue.DecreaseKey(nodeVector[v], nodeTemp) != 0) 
						cout << "Error decreasing the node key" << endl; 
				}
				
			} // End For 
			
		} // End While
					

		/* Accumulation */ 
		while (!S.empty()) { 
			u = S.top(); 
			S.pop(); 
			for (j=0; j < PredList[u].size(); j++) {
				delta[PredList[u][j]] += ((f64) sigma[PredList[u][j]]/sigma[u]) * (1+delta[u]); 
			}
			if (u != i) 
				CB[u] += delta[u]; 
		}
		
		// Clear data for the next run
		PredList.clear(); 
		sigma.clear(); 
		delta.clear(); 
		for (j=0; j < nvertices; j++) 
			nodeVector[j]->Set_key(ULONG_MAX); 
		
	} // End For 
	
	// End time after Brandes' algorithm and the time difference
	time(&end); 
	time_dif = difftime(end, start); 
	cout << "It took " << time_dif << " seconds to calculate Betweenness Centrality in an weighted graph" << endl; 
	
	// Deallocate memory 
	for (i=0; i < nvertices; i++) 
		delete nodeVector[i]; 
	return; 
	
} // End of BrandesAlgorithm_Weighted 
Example #5
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" );

}
Example #6
0
//============================================================================================
// Dijkstra::_run
//
// Input:
//  fromId:     The id of the starting city.
//  toId:       The id of the ending city
//  cities:     A vector of City objectrs representing all the cities in the graph.
//  forward:    A boolean value indicating whether or not the algorithm should be run by following
//              edges leading to a Node or edges leading away from that Node.
//
// Output:
//  A DijkstraResult object.
//
// Run Dijkstra's Algorithm from the City identified by the fromId parameter to the city identified by the
// toId parameter.
//============================================================================================
DijkstraResult *Dijkstra::_run(unsigned long fromId, unsigned long toId, std::map<unsigned long, City *> cities, bool forward){
    std::map<unsigned long, City*> previous;
    std::map<unsigned long, Node*> cityNodes;
    std::map<unsigned long, unsigned long> distances;

    FibHeap* heap = new FibHeap();
    Node *temp;
    
    for(auto it = cities.begin(); it != cities.end(); it++){
        it->second->visited = false;
        
        if (it->second->key == fromId) {
            it->second->distance = 0;
        }
        else{
            it->second->distance = ULONG_MAX;
        }
        
        temp = new Node(it->second);
        FibHeap::insert(temp, heap);
        cityNodes[it->second->key] = temp;
    }
    
    City *minCity, *neighbor;
    Road *road;
    std::vector<Road *> roads;
    
    while(heap->min != nullptr)
    {
        minCity = heap->deleteMin(heap);
        
        if(forward){
            roads = minCity->fromRoads;
        }
        else{
            roads = minCity->toRoads;
        }

        for (auto it = roads.begin(); it != roads.end(); it++)
        {
            road = *it;
            
            if(forward){
                neighbor = cities[road->to];
            }else{
                neighbor = cities[road->from];
            }
            
            if (neighbor->visited == false)
            {
                unsigned long altDistance = minCity->distance + road->length;
                
                if (altDistance < neighbor->distance)
                {
                    if(minCity->distance != ULONG_MAX){
                        unsigned long sub = neighbor->distance - altDistance;
                        
                        previous[neighbor->key] = minCity;
                        distances[neighbor->key] = altDistance;
                        FibHeap::decreaseKey(sub, cityNodes[neighbor->key], heap);
                    }
                }
            }
        }
        
        minCity->visited = true;
    }
    
    distances[toId] = cities[toId]->distance;
    
    return new DijkstraResult(previous, distances);
    
}
Example #7
0
void test_decrease_key(){
	FibHeap fib;
	int NUM_NODES = 100;
	
	boost_heap pq;	
	map<int, boost_heap::handle_type> index;
	vector<int> keys;
	set<int> keyset;  // Used for getting logarithmic random generation and duplicate detection
	
	for (int i = 0; i < NUM_NODES; i++){
		unsigned int curr = 	rand();
		if (present(keyset, curr)) continue;
		
		fib.insertNode(curr);
		index[curr]=pq.push(curr);			
		keys.push_back(curr);
		keyset.insert(curr);
		
		if (i % 25 == 0){
			//Do some random decrease keys
			for (int j = 0; j < 20; j++){
				//Pick a key to change
				unsigned int to_change_index = rand() % keys.size(); 
				unsigned int to_change_val = keys[to_change_index];
				
				if (to_change_val == 0) continue;

				//Find a smaller value to change to which doesnt already exist
				// Or try for a bit
				unsigned int new_val = rand() % to_change_val;
				
				for (int k = 0; k < 100; k++){
				 if (present(keyset, new_val))
				  new_val = rand() % to_change_val;
				 else break;
				}
				if (present(keyset,new_val)) continue;
				
				//replace the old value with new one
				keys[to_change_index] = new_val;
				keyset.erase(to_change_val);
				keyset.insert(new_val);
				
				//perform operation on heaps
				pq.decrease(index[to_change_val],new_val);
				index[new_val] = index[to_change_val];
				index.erase(to_change_val);
				
				fib.decreaseKey(to_change_val, new_val);
				
			}
		}
		
		if (i%50 == 0){
			int num_deletes = rand() % fib.getSize()+1;
			for (int j = 0; j < num_deletes; j++){
				unsigned int val= fib.deleteMin();
				unsigned int ref = pq.top();
				pq.pop();
			
				if (val != ref){
					cout << "\n Random : Our value: " << val << " Ref Value: " << ref;
					return;
				}
				
				keyset.erase(val);
				
				std::vector<int>::iterator position = std::find(keys.begin(), keys.end(), val);
				if (position != keys.end()) // == vector.end() means the element was not found
    				keys.erase(position);
				else cout << "Should never get here, keys messed up";
				
				index.erase(val);
			}
		}
			
	}
	
	
cout <<"Test completed";
	
}