00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013
00014
00015 #include "converse.h"
00016 #include "graphdefs.h"
00017
00018 int addEdge(VerticesListType *graph, EdgeListType *l,int fm,int to);
00019 void addspEdge(VerticesListType *graph, EdgeListType *, int, int);
00020 int edgeExists(VerticesListType *graph, int fm, int to);
00021 static Q * makeQueue();
00022 static int isEmpty(Q*);
00023 static int dequeue(Q*);
00024
00025 #define VMAX 2050
00026 int V;
00027 int E;
00028 int C;
00029
00030 VerticesListType * InitVertices();
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static void printOut(VerticesListType *vertices);
00041 static void copyOut(VerticesListType *vertices, int *npe, int *pes);
00042 static void initGraph(VerticesListType *graph);
00043 static void diameter(VerticesListType *graph);
00044 static void AddEdges(VerticesListType *graph, EdgeListType *EdgeList, int V, int n);
00045
00046 void gengraph(int pV, int pC, int pseed, int *pes, int *npe, int tofile)
00047 { int i;
00048 VerticesListType graph;
00049 int seed;
00050 EdgeListType * EdgeList;
00051
00052 extern EdgeListType * InitEdgeList();
00053 char dircmd[20], dirname[10];
00054
00055 V = pV;
00056 C = pC;
00057 seed = pseed;
00058
00059 if (CmiMyPe() == 0)
00060 CmiPrintf("for %d PEs, connectivity %d... \n", V, C);
00061
00062
00063 if (tofile && CmiMyPe() == 0) {
00064 sprintf(dirname, "graph%d", V);
00065 sprintf(dircmd, "mkdir %s", dirname);
00066 system(dircmd);
00067 }
00068
00069
00070 for (i=0; i<seed; i++) CrnRand();
00071 if ((V*C %2) != 0) printf("V*C must be even\n");
00072 E = V*C/2;
00073 initGraph(&graph);
00074 EdgeList = InitEdgeList(E);
00075 AddEdges(&graph, EdgeList, V, E);
00076
00077
00078 if (tofile) {
00079 if (CmiMyPe()==0) printOut(&graph);
00080 }
00081 else copyOut(&graph, npe, pes);
00082
00083 if (CmiMyPe()==0) diameter(&graph);
00084 }
00085
00086 #if 0
00087 static void AddEdges(EdgeListType *EdgeList, int V, int n)
00088
00089 {int i,j,w,x,y;
00090
00091 int c1;
00092 if (C>1) c1 = C-1;
00093
00094 for (i=0; i< V/c1; i++)
00095 for (j=0; j<c1; j++) {
00096 w = c1*i + j +1;
00097
00098 if (w < V) {
00099 addEdge(EdgeList,i,w);
00100
00101 }
00102 else ;
00103 }
00104 n -= (V-1);
00105
00106 for (i=0; i<n; i++)
00107 {
00108 do {
00109 do {
00110 x = CrnRand() % V;
00111 } while (connections(x) >= C);
00112 do {
00113 y = CrnRand() % V;
00114 } while ((y== x) || connections(y) >= C);
00115 } while (edgeExists(x,y));
00116 addEdge(EdgeList, x, y);
00117 }
00118 }
00119 #endif
00120
00121 static void AddEdges(VerticesListType *graph, EdgeListType *EdgeList, int V, int n)
00122
00123 { int i,j,w,x,y,k;
00124 int c1,max,maxi;
00125 int **varr;
00126 int varrlen,count=0;
00127 int flag=0;
00128
00129
00130 varr=(int **)calloc(V, sizeof(int*));
00131 for (i=0;i<V;i++)
00132 varr[i]=calloc(2, sizeof(int));
00133
00134 if (C>1) c1 = C-1;
00135
00136 for (i=0; i<= V/c1; i++)
00137 for (j=0; j<c1; j++) {
00138 w = c1*i + j +1;
00139 if (w < V) {
00140 addEdge(graph, EdgeList,i,w);
00141 count++;
00142 }
00143 }
00144
00145
00146 j=0;
00147 for (i=0;i<V;i++)
00148 if(connections(graph, i)<C)
00149 {
00150 varr[j][0]=i;
00151 varr[j][1]=C-connections(graph,i);
00152 j++;
00153 }
00154 varrlen=j;
00155 CmiAssert(varrlen>0);
00156
00157
00158
00159 n -= count;
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 k=n;
00214 for (j=0;j<k;j++)
00215 {
00216 flag=0;
00217 max=0;
00218 maxi=0;
00219 for (i=0;i<varrlen;i++)
00220 if (varr[i][1]>max) { max=varr[i][1];maxi=i;}
00221 x = maxi;
00222 do {
00223 y = rand() % varrlen;
00224 } while (y == x) ;
00225
00226
00227
00228
00229
00230
00231
00232
00233 if (edgeExists(graph, varr[x][0],varr[y][0])&&(j==k-1))
00234 addspEdge(graph, EdgeList,varr[x][0],varr[y][0]);
00235 else
00236 {
00237 while((y==x)||(edgeExists(graph,varr[x][0],varr[y][0])))
00238 y = rand() % varrlen;
00239 addEdge(graph,EdgeList,varr[x][0],varr[y][0]);
00240 }
00241
00242 varr[x][1]=varr[x][1]-1;
00243 varr[y][1]=varr[y][1]-1;
00244
00245 if (varr[x][1]==0)
00246 {
00247 flag=1;
00248 for (i=x;i<varrlen-1;i++)
00249 {
00250 varr[i][0]=varr[i+1][0];
00251 varr[i][1]=varr[i+1][1];
00252 }
00253 varrlen--;
00254 }
00255 if ((y>x)&&(flag))
00256 {
00257 if (varr[y-1][1]==0)
00258 {
00259 for (i=y-1;i<varrlen-1;i++)
00260 {
00261 varr[i][0]=varr[i+1][0];
00262 varr[i][1]=varr[i+1][1];
00263 }
00264 varrlen--;
00265 }
00266 }
00267 else if (varr[y][1]==0)
00268 {
00269 for (i=y;i<varrlen-1;i++)
00270 {
00271 varr[i][0]=varr[i+1][0];
00272 varr[i][1]=varr[i+1][1];
00273 }
00274 varrlen--;
00275 }
00276 }
00277 for (i=0;i<V;i++) free(varr[i]);
00278 free(varr);
00279 }
00280
00281
00282 void fillAdjArray(Edge *edges, VerticesListType *vlist, int V, int E);
00283 void sortAdjArrays(VerticesListType *vlist);
00284 static void sort(int *adj, int fromIndex, int toIndex);
00285 void countDegrees(Edge *edges, Vertex *vertRecs, int V, int E);
00286
00287 VerticesListType *
00288 InitVertices(EdgeList, V,E)
00289 EdgeListType * EdgeList;
00290 int V;
00291 int E;
00292 {
00293
00294
00295
00296
00297
00298
00299 VerticesListType * vlist;
00300
00301 vlist = (VerticesListType *) malloc(sizeof(VerticesListType));
00302 _MEMCHECK(vlist);
00303 vlist->numVertices = V;
00304 vlist->vertexArray = (Vertex *) malloc(V*sizeof(Vertex));
00305 _MEMCHECK(vlist->vertexArray);
00306 vlist->adjArray = (int *) malloc(2*E*sizeof(int));
00307
00308 _MEMCHECK(vlist->adjArray);
00309 countDegrees(EdgeList->edges, vlist->vertexArray, V, E);
00310 fillAdjArray(EdgeList->edges, vlist, V, E);
00311 sortAdjArrays(vlist);
00312 return(vlist);
00313 }
00314
00315 void countDegrees(Edge *edges, Vertex *vertRecs, int V, int E)
00316 {
00317
00318
00319 int i, count;
00320
00321 for (i=0; i<V; i++)
00322 { vertRecs[i].degree = 0;
00323 vertRecs[i].next = 0;}
00324 for (i=0; i<E; i++)
00325 {vertRecs[ edges[i].node1 ].degree++;
00326 vertRecs[ edges[i].node2 ].degree++;}
00327
00328
00329
00330 count = 0;
00331 for (i=0; i<V; i++)
00332 { vertRecs[i].adjListInd = count;
00333 count += vertRecs[i].degree;
00334 }
00335 }
00336
00337 void fillAdjArray(Edge *edges, VerticesListType *vlist, int V, int E)
00338 {
00339 int i, x,y;
00340 int * adj;
00341 Vertex * vertexRecs;
00342
00343 adj = vlist->adjArray;
00344 vertexRecs = vlist->vertexArray;
00345
00346 for (i=0; i<E; i++)
00347 { x = edges[i].node1; y = edges[i].node2;
00348 adj[ vertexRecs[x].adjListInd + vertexRecs[x].next ] = y;
00349 vertexRecs[x].next++;
00350 adj[ vertexRecs[y].adjListInd + vertexRecs[y].next ] = x;
00351 vertexRecs[y].next++;
00352 }
00353 }
00354
00355 void sortAdjArrays(VerticesListType *vlist)
00356 {
00357 int V, i;
00358 int dupcount;
00359
00360 V = vlist->numVertices;
00361 for (i=0; i<V; i++)
00362 { sort(vlist->adjArray,
00363 vlist->vertexArray[i].adjListInd,
00364 vlist->vertexArray[i].adjListInd + vlist->vertexArray[i].degree -1);
00365 }
00366
00367 dupcount = 0;
00368 for (i=0; i<V; i++)
00369 { int m,n, limit;
00370 int * adj;
00371
00372 m = vlist->vertexArray[i].adjListInd;
00373 n = m+1;
00374 limit = m + vlist->vertexArray[i].degree;
00375
00376 adj = vlist->adjArray;
00377
00378
00379
00380 while ((adj[m] != adj[n]) && (n < limit)) {m++; n++;}
00381
00382 while (n<limit) {
00383 while ((adj[m] == adj[n]) && (n<limit))
00384 { n++; dupcount++; vlist->vertexArray[i].degree--;}
00385 adj[m+1] = adj[n];
00386 m++; n++;
00387 }
00388 }
00389
00390
00391 if ((dupcount % 2) != 0) {printf("error. duplicates not even.\n"); }
00392 E -= dupcount/2;
00393 }
00394
00395 static void sort(int *adj, int fromIndex, int toIndex)
00396 { int i,j, tmp;
00397 short changed;
00398 changed = 1;
00399 for (i=toIndex; ((i>fromIndex) && changed); i--)
00400 { changed = 0;
00401 for (j=fromIndex; j<i; j++)
00402 { if (adj[j] > adj[j+1])
00403 {
00404 changed = 1;
00405 tmp = adj[j];
00406 adj[j] = adj[j+1];
00407 adj[j+1] = tmp;
00408 }
00409 }
00410 }
00411 }
00412
00413 static void copyOut(VerticesListType *vertices, int *npe, int *pes)
00414 {
00415 int i;
00416 int * adj;
00417 Vertex * vertexRecs;
00418
00419 adj = vertices->adjArray;
00420 vertexRecs = vertices->vertexArray;
00421
00422 #if CMK_NODE_QUEUE_AVAILABLE
00423 *npe = vertexRecs[CmiMyNode()].degree;
00424 for (i=0; i<vertexRecs[CmiMyNode()].degree; i++)
00425 pes[i] = adj[ vertexRecs[CmiMyNode()].adjListInd + i ];
00426 #else
00427 *npe = vertexRecs[CmiMyPe()].degree;
00428 for (i=0; i<vertexRecs[CmiMyPe()].degree; i++)
00429 pes[i] = adj[ vertexRecs[CmiMyPe()].adjListInd + i ];
00430 #endif
00431 }
00432
00433 static void printOut(VerticesListType *vertices)
00434 {int i,j;
00435 int * adj;
00436 Vertex * vertexRecs;
00437 FILE *fp;
00438 char filename[20];
00439
00440 adj = vertices->adjArray;
00441 vertexRecs = vertices->vertexArray;
00442
00443 for (i=0; i<vertices->numVertices; i++)
00444 {
00445
00446 sprintf(filename, "graph%d/graph%d", vertices->numVertices, i);
00447 fp = fopen(filename, "w");
00448 fprintf(fp, "%d ", vertexRecs[i].degree);
00449 for (j=0; j<vertexRecs[i].degree; j++)
00450 fprintf(fp, "%d ", adj[ vertexRecs[i].adjListInd + j ]);
00451 fprintf(fp, "\n");
00452 fclose(fp);
00453 }
00454 }
00455
00456 static void initGraph(VerticesListType *graph)
00457 { int i;
00458 graph->numVertices = V;
00459 graph->vertexArray = (Vertex *) malloc(V*sizeof(Vertex));
00460 _MEMCHECK(graph->vertexArray);
00461 graph->adjArray = (int *) malloc(2*E*sizeof(int));
00462 _MEMCHECK(graph->adjArray);
00463
00464 for (i=0; i< V; i++) {
00465 graph->vertexArray[i].degree = 0;
00466 graph->vertexArray[i].next = i*C;
00467 graph->vertexArray[i].adjListInd = i*C;
00468 }
00469 }
00470
00471 static void enqueue(Q *q, int i);
00472
00473 static void diameter(VerticesListType *graph)
00474 {
00475 Q * makeQueue();
00476 int i,j, k, v, w, start;
00477 int *distance;
00478 int *histogram;
00479 Q * q;
00480 int dia;
00481 float average;
00482
00483 distance = (int *)calloc(V, sizeof(int));
00484 histogram = (int *)calloc(V, sizeof(int));
00485
00486 for (i=0; i<V; i++) {
00487 histogram[i] = 0;
00488 }
00489
00490 dia = 0;
00491 average = 0.0;
00492 q = makeQueue();
00493 for (i=0; i<V; i++) {
00494
00495 for (j=0; j<V; j++) distance[j] = -1;
00496 distance[i] = 0;
00497 enqueue(q, i);
00498 while (! (isEmpty(q))) {
00499 v = dequeue(q);
00500
00501 start=graph->vertexArray[v].adjListInd;
00502 for (k=0; k< graph->vertexArray[i].degree; k++) {
00503 w = graph->adjArray[k+start];
00504 if (distance[w] == -1) {
00505 distance[w] = distance[v] + 1;
00506 enqueue(q, w);
00507 }
00508 }
00509 }
00510 for (j=0; j<V; j++) {
00511 if (distance[j] > dia) dia = distance[j];
00512 average += distance[j];
00513 histogram[ distance[j]]++;
00514 }
00515 }
00516 average = average / (V*V);
00517 printf("the diameter is: %d, average internode distance = %f\n",
00518 dia, average);
00519
00520 }
00521
00522
00523
00524
00525 static Q * makeQueue()
00526 {
00527 Q *q = (Q *) malloc(sizeof(Q));
00528 _MEMCHECK(q);
00529 q->size = VMAX;
00530 q->numElements = 0;
00531 q->head = 1;
00532 q->tail = 0;
00533 q->buf = (int *) malloc(VMAX*sizeof(int));
00534 _MEMCHECK(q->buf);
00535 return q;
00536 }
00537
00538 static void enqueue(Q * q, int i) {
00539 q->tail++;
00540 if (q->tail == q->size) q->tail = 0;
00541 q->buf[q->tail] = i;
00542 q->numElements++;
00543 }
00544
00545 static int dequeue(Q *q) {
00546 int r;
00547 r = q->buf[q->head++];
00548 if (q->head == q->size) q->head = 0;
00549 q->numElements--;
00550 return r;
00551 }
00552
00553 static int isEmpty(Q * q) {
00554 return (q->numElements == 0) ;
00555 }