void dijkstra(MGraph *G, int s) { int i, *set, u, v; MinQueue queue; initialize_single_source(G, s); set = malloc(sizeof(int)*G->numVertexes); queue.size = G->numVertexes; queue.heap = malloc(sizeof(int)*(G->numVertexes+1)); //初始化集合S为空 for(i=0;i<G->numVertexes;i++) { set[i] = 0; } set[s] = 1; //初始化队列为空 for(i=0;i<G->numVertexes;i++) { queue.heap[i+1] = i; } //逐步添加最小权值边 while(queue.size>0) { build_min_heap(&queue); u = extract_min(&queue); set[u] = 1; for(i=0;i<G->numVertexes;i++) { if(G->edges[u][i] != INFINITY) { relax(u,i, G->edges[u][i]); } } } }
void dijkstra_normal(MGraph *G, int s) { printf("This is dijkstra O(n2)\n"); int i ,j, u, *set, min; initialize_single_source(G, s); set = malloc(sizeof(int)*G->numVertexes); for(i=0;i<G->numVertexes;i++) { set[i] = 0; } for(i=0;i<G->numVertexes;i++) { min = INFINITY; for(j=0;j<G->numVertexes;j++) { if((set[j]==0) && d[j] < min) { u = j; min = d[j]; } } set[u] = 1; for(j=0;j<G->numVertexes;j++) { if(G->edges[u][j] != INFINITY) { if(d[j] > d[u] +G->edges[u][j]) { d[j] = d[u] + G->edges[u][j]; p[j] = u; } } } } }
// 将d[]拷贝到优先队列中,在优先队列中对d进行修改(decreace_key) // 处理完成后,再拷贝出来 // 假定graph,d[],parent[]均已分配内存 void dijkstra(AdjList* graph, int numVertices, int s, int d[], int parent[]) { int i; AdjListNodePtr v; FibHeap h = make_fib_heap(); FibHeapNodePtr fpnArray[numVertices]; initialize_single_source(graph, numVertices, s, d, parent); construct_queue(graph, numVertices, d, h, fpnArray); fib_heap_root_print(h->min); while(h->min != NIL) { FibHeapNodePtr u = fib_heap_extract_min(h); printf("extract_min: %d\n", u->ref); // 指示顶点u已不再优先队列中 u->inq = FALSE; v = graph[u->ref]; // 对以u->ref为顶点的每条边进行松弛 while(v) { // 有无代码依赖于parent[]的修改? // 循环的下一次迭代依赖于优先队列中关键字域的修改 dijkstra_relax(u->ref, v->vertex, v->weight, parent, fpnArray, h); v = v->next; } } // 将队列中关键字的值拷贝回d中,利用fpnArray[] for (i = 0; i < numVertices; i++) { d[i] = fpnArray[i]->key; } // 释放优先队列中的内存... }
/* Run the Bellman-Ford algorithm from vertex s. Fills in arrays d and pi. */ int bellman_ford(int first[], int node[], int next[], double w[], double d[], int pi[], int s, int n) { int u, v, i, j; initialize_single_source(d, pi, s, n); for (i = 1; i <= n-1; ++i) { for (u = 1; u <= n; ++u) { j = first[u];// pour chaque sommet while (j > 0) { v = node[j]; relax(u, v, w[j], d, pi); j = next[j]; } } } for (u = 1; u <= n; ++u) { j = first[u]; while (j > 0) { v = node[j]; if (d[v] > d[u] + w[j]) return 0; j = next[j]; } } return 1; }
/** * @brief Dijkstra's shortest path algorithm * * @param[in] g The graph to operate on * @param[in] s The starting vertex * @param[in] cb The function to call when a shortest spath vertex is determined. */ void sp_dijkstra (GRAPH_T* g, unsigned long s, SP_DJ_FP_T cb) { HEAP_T* h; VTX_D_T* u = NULL; VTX_D_T* v; unsigned long key, no; char* ctx = NULL; EDGE_T* e; void* p; initialize_single_source (g, s); h = heap_create (DS_HEAP_MIN, GRAPH_NO_VERTICES(g)); while (NULL != (u = graph_vertex_next_get (g, u))) { heap_min_insert (h, D_SP_AUX_SPEST(u), u, &D_SP_AUX_I(u)); } while (HEAP_SIZE(h)) { heap_extract_min (h, &p, &key); u = (VTX_D_T*)p; ctx = NULL; no = ((VTX_D_T*)u)->no; while (no) { e = graph_vertex_next_edge_get (g, u, &ctx); if (e->v1 == u) v = e->v2; else v = e->v1; if (v->id.iid == s) { no--; continue; } DEBUG_PRINT ("Relaxing v=%lu (OLD weight: %lu; NEW weight: u=%lu w=%lu)\n", v->id.iid, D_SP_AUX_SPEST(v), u->id.iid, e->weight); relax (g, u, v, e->weight); heap_decrease_key (h, D_SP_AUX_I(v), D_SP_AUX_SPEST(v)); no--; } } if (cb) { v = NULL; while (NULL != (v = graph_vertex_next_get (g, v))) { cb (v); //fprintf (stderr, "vid = %lu sp=%lu\n", v->id.iid, D_SP_AUX_SPEST(v)); } } }
/*Caminhos mínimos por Bellman-Ford: */ void BellmanFord (Graph *G, int source) { int i, u; int pai[G->V]; /*Árvore de caminhos mínimos.*/ int dist[G->V]; /*Distâncias mínimas.*/ Queue *Q = criar_queue (G->V); initialize_single_source (source, pai, dist, Q, G->V); /*****************************/ /*FAZER: termine o algoritmo!*/ /*****************************/ Node *v; /*Variável para percorrer a lista de adjacência do vértice {u}*/ for(i = 0; i< G->V - 1; i++) { int u; for(u = 0; u < G->V; u++) { for(v = G->listadj[u]; v != NULL; v = v->proximo) { relax (u, v->id, G, pai, dist); } } } for(u = 0; u < G->V; u++) { for(v = G->listadj[u]; v != NULL; v = v->proximo) { if(dist[v->id] > dist[u] + v->id) { printf("Falso\n"); printf("Tem solução\n"); exit(0); } printf("Verdadeiro"); exit(1); } } }
/*Caminhos mínimos por Dijkstra: */ void Dijkstra (Graph *G, int source) { int pai[G->V]; /*Árvore de caminhos mínimos.*/ int dist[G->V]; /*Distâncias mínimas.*/ Queue *Q = criar_queue (G->V); initialize_single_source (source, pai, dist, Q, G->V); while (!vazio_queue(Q)) { int u = extract_min (Q, dist, G->V); Node *v; /*Variável para percorrer a lista de adjacência do vértice {u}*/ for (v = G->listadj[u]; v != NULL; v = v->proximo) { relax (u, v->id, G, pai, dist); } printf("Nó = %d (predecessor = %d), caminho mínimo do nó %d até o nó %d = %d\n", u, pai[u], source, u, dist[u]); } }
/* Run Dijkstra's algorithm from vertex s. Fills in arrays d and pi. */ void dijkstra(int first[], int node[], int next[], double w[], double d[], int pi[], int s, int n, int handle[], int heap_index[]) { int size = n; int u, v, i; initialize_single_source(d, handle, heap_index, pi, s, n); while (size > 0) { u = handle[1]; extract_min(d, handle, heap_index, size); --size; i = first[u]; while (i > 0) { v = node[i]; relax(u, v, w[i], d, handle, heap_index, size, pi); i = next[i]; } } }
void dag_shortest_path(AdjList* graph, int length, int s, int d[], int parent[]) { AdjListNodePtr adjNode; List list = NULL, x = NULL; // toplogically sort the vertices of G toplogical_sort(graph, length, &list); initialize_single_source(graph, length, s, d, parent); x = list; while(x->value != s){ x = x->next; } while(x) { adjNode = graph[x->value]; while(adjNode) { relax(x->value, adjNode->vertex, adjNode->weight ,d, parent); adjNode = adjNode->next; } x = x->next; } free_list(list); }