Ejemplo n.º 1
0
struct priority_queue *pq_new(unsigned int size, unsigned int universe) {
	struct priority_queue *pq;
	make_node_list(size);
  pq = new_pq();
	pq->init_n = size;
  return pq;
}
Ejemplo n.º 2
0
Archivo: graph.c Proyecto: anhvir/c207
// The "standard" version of Dijkstra's,
//   ie the one that is the same as shown in the lecture
//    see page 16 of lec08.pdf
// Comments starting with //* are the lines from pseudocode in page 16
// Print out the shortest paths from the source node to each other node
void dijkstras(graph_t *g, int v0) {
	int v;
	int u, w; double weight;   // generous vars for edge (u->w,weight)

	// To store current min-costs and previous vertices
	int *prev;		// prev[v]=u if v was reached from u 
  	double *dist;	// dist[v]= current best dist from source to v
	bool *inQ;	// a helping array for quick check if v in Q
	assert(prev= malloc( g->n * sizeof(*prev) ) );
	assert(dist= malloc( g->n * sizeof(*dist) ) );
	assert(inQ= malloc( g->n * sizeof(*inQ) ) );

	/* Initialization ------------------------------ */
	for (v = 0; v < g->n; v++) {  //* foreach v in V
		prev[v] = NO_PREV;        //*    prev[v]= nil
		dist[v] = INFINITY;       //*    dist[v]= infinity
	}
	dist[v0] = 0;                 //* dist[v0]=0

	//* Q = InitPriorityQueue(V)
	pq_t *Q = new_pq();
	for (v = 0; v < g->n; v++) {
		pq_enqueue(Q, v, dist[v]);
		inQ[v]= true;			// marks v as being inside the queue
	}
		
	/* Main loop of Dijkstra's ------------------------------ */
	// buddy array of n elements to store the adjacency list of a vertex
	data_t *neighbours; int n;
	assert(neighbours= malloc( g->n * sizeof(*neighbours) ) );

	while (!pq_is_empty(Q)) {  //* while Q is non empty do
		// remove min vertex 
    	u = pq_remove_min(Q);  //*    u= EjectMin(Q)
		inQ[u]= false;         //     marks u as not in Q anymore
		
		// With this vertex u:
		//   first, copies the adjacency list of u to array neighbours
		n= list_2_array(g->vs[u].A, neighbours);
		 
		for (v = 0; v < n; v++) {  //* for each (u,w) in E do
			w = neighbours[v].id;   //   having:edge (u-->w,weight) 
			weight= neighbours[v].weight;

			//* if (w in Q && dist[v]+weight(u,w) <dist[v]
			if ( inQ[w] && dist[w] > dist[u]+weight) {  
				dist[w] = dist[u]+weight;  //* dist[w]= dist[u]+weight(u,v)          
				prev[w] = u;               //* prev[w]= u 
			                               //* Update(Q, w, dist[w])
				pq_update(Q, w, dist[w]);
			
			}
		}
	}

	
	/* Prints out all shortest paths ------------------------------ */
	print_all_path(dist, prev, g, v0);
	
	// free the dynamic data structures
	free(dist);
	free(prev);
	free(neighbours);
	free_pq(Q);	
}
Ejemplo n.º 3
0
Archivo: graph.c Proyecto: anhvir/c207
// NON-standard version of Dijkstra's:
// Print out the shortest paths from the source node to each other node
void dijkstras(graph_t *g, int source) {
	int i;
	int u, v; double weight;   // generous vars for edge (u->v,weight)
	double new_weight;

	// To store current min-costs and previous vertices
	int *prev;		// prev[v]=u if v was reached from u 
  	double *dist;	// dist[v]= current best dist from source to v
	assert(prev= malloc( g->n * sizeof(*prev) ) );
	assert(dist= malloc( g->n * sizeof(*dist) ) );

	/* Initialization ------------------------------ */
	for (i = 0; i < g->n; i++) {
		prev[i] = NO_PREV;
		dist[i] = INFINITY;
	}
	dist[source] = 0;

	// enqueue "source" - the only one that has limitted dist
	pq_t *queue = new_pq();
	pq_enqueue(queue, source, dist[source]);

	/* Main loop of Dijkstra's ------------------------------ */
	// buddy array of n elements to store the adjacency list of a vertex
	data_t *neighbours; int n;
	assert(neighbours= malloc( g->n * sizeof(*neighbours) ) );

	while (!pq_is_empty(queue)) {
		// remove min vertex 
    	u = pq_remove_min(queue);
		
		// With this vertex u:
		// * first, copies the adjacency list of u to array neighbours
		n= list_2_array(g->vs[u].A, neighbours);
		// * then, inspects each of the neighbour 
		for (i = 0; i < n; i++) {
			v = neighbours[i].id;   // looking at edge (u-->v,weight) 
			weight = neighbours[i].weight;
			new_weight = dist[u] + weight;

			// if v was reached before with a better outcome
			//      then we just ignore the edge u-->v
			if ( dist[v] <= new_weight) continue;  

			// updates vertex v in the queue 
			if (dist[v] == INFINITY) { 
				// if v never been reached before, adds it to queue
				pq_enqueue(queue, v, new_weight);
			} else { 
				// otherwise, updates weight of v in the queue
				//   note that the update must be successful 
				if ( !pq_update(queue, v, new_weight) ){
					fprintf(stderr, "Internal error: Something wrong "
					  "in code or in data (such as negative weight)\n");
					exit(EXIT_FAILURE);
				}
			}
			
			// now updaes dist[v] and prev[v]
			dist[v] = new_weight;          
			prev[v] = u;

		}
	}

	
	/* Prints out all shortest paths ------------------------------ */
	print_all_path(dist, prev, g, source);
	
	// free the dynamic data structures
	free(dist);
	free(prev);
	free(neighbours);
	free_pq(queue);	
}