📄 dijkstra-omp.c
字号:
// Dijkstra.c// OpenMP example program: Dijkstra shortest-path finder in a// bidirectional graph; finds the shortest path from vertex 0 to all// others// 编 译: icl /Qopenmp Dijkstra-omp.c(Intel 编译)// // usage: dijkstra nv print (例如: Dijkstra-omp.exe 22000 0)// where nv is the size of the graph, and print is 1 if graph and min// distances are to be printed out, 0 otherwise#include <omp.h>#include <time.h>// global variables, shared by all threads by defaultint nv, // number of vertices *notdone, // vertices not checked yet nth, // number of threads chunk, // number of vertices handled by each thread md, // current min over all threads mv, // vertex which achieves that min largeint = -1; // max possible unsigned intunsigned *ohd, // 1-hop distances between vertices; "ohd[i][j]" is // ohd[i*nv+j] *mind; // min distances found so farvoid init(int ac, char **av){ int i,j,tmp; nv = atoi(av[1]); ohd = malloc(nv*nv*sizeof(int)); mind = malloc(nv*sizeof(int)); notdone = malloc(nv*sizeof(int)); // random graph for (i = 0; i < nv; i++) for (j = i; j < nv; j++) { if (j == i) ohd[i*nv+i] = 0; else { ohd[nv*i+j] = rand() % 20; ohd[nv*j+i] = ohd[nv*i+j]; } } for (i = 1; i < nv; i++) { notdone[i] = 1; mind[i] = ohd[i]; }}// finds closest to 0 among notdone, among s through evoid findmymin(int s, int e, unsigned *d, int *v){ int i; *d = largeint; for (i = s; i <= e; i++) if (notdone[i] && mind[i] < *d) { *d = ohd[i]; *v = i; }}// for each i in [s,e], ask whether a shorter path to i exists, through// mvvoid updatemind(int s, int e){ int i; for (i = s; i <= e; i++) if (mind[mv] + ohd[mv*nv+i] < mind[i]) mind[i] = mind[mv] + ohd[mv*nv+i];}void dowork(){ #pragma omp parallel { int startv,endv, // start, end vertices for my thread step, // whole procedure goes nv steps mymv, // vertex which attains the min value in my chunk me = omp_get_thread_num(); unsigned mymd; // min value found by this thread #pragma omp single { nth = omp_get_num_threads(); if (nv % nth != 0) { printf("nv must be divisible by nth\n"); exit(1); } chunk = nv/nth; printf("there are %d threads\n",nth); } startv = me * chunk; endv = startv + chunk - 1; for (step = 0; step < nv; step++) { // find closest vertex to 0 among notdone; each thread finds // closest in its group, then we find overall closest #pragma omp single { md = largeint; mv = 0; } findmymin(startv,endv,&mymd,&mymv); // update overall min if mine is smaller #pragma omp critical { if (mymd < md) { md = mymd; mv = mymv; } } #pragma omp barrier // mark new vertex as done #pragma omp single { notdone[mv] = 0; } // now update my section of mind updatemind(startv,endv); #pragma omp barrier } }}int main(int argc, char **argv){ int i,j,print; clock_t start, stop; init(argc,argv); start = clock(); // parallel dowork(); // back to single thread stop = clock(); print = atoi(argv[2]); if (print) { printf("graph weights:\n"); for (i = 0; i < nv; i++) { for (j = 0; j < nv; j++) printf("%u ",ohd[nv*i+j]); printf("\n"); } printf("minimum distances:\n"); for (i = 1; i < nv; i++) printf("%u\n",mind[i]); } printf("use time: %f seconds\n",((double)(stop - start)/1000.0)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -