eval.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* $Id: eval.c,v 1.1 1996/10/04 13:33:28 ewz Exp $
  2.  * 
  3.  * eval.c -- evaluation routines.
  4.  *
  5.  */
  6. #include <stdio.h>
  7. #include <malloc.h>
  8. #include "gb_graph.h"
  9. #include "gb_dijk.h"
  10. #include "eval.h"
  11. #include <assert.h>
  12. int finddegdist(Graph *g, int** degdist)
  13. {
  14.     Vertex *v;
  15.     Arc *a;
  16.     int max = 0, *deg, idx, i;
  17.     deg = (int *)malloc((g->n)*sizeof(int));
  18.     for (v = g->vertices,i=0; i<g->n; i++,v++) {
  19. deg[i] = 0;
  20. for (a = v->arcs; a; a = a->next)
  21. deg[i]++;
  22. if (deg[i] > max) max = deg[i];
  23.     }
  24.     *degdist = (int *)calloc(max+1,sizeof(int));
  25.     for (v = g->vertices,i=0; i < g->n; i++, v++) {
  26. (*degdist)[deg[i]]++;
  27.     }
  28.     return max;
  29. }
  30. #define first(g)  g->vertices
  31. #define BIGINT 0x7fffffff
  32. #define MAXBINS 100
  33. #define BINCONST  10 /* number of bins in pathlen dist = n*BINCONST */
  34. static int *depth;
  35. static int min, max;
  36. static float avg;
  37. void
  38. dopaths(Graph *g, enum Field f0, enum Field f1, int *rmin, int *rmax, float *ravg)
  39. {
  40.     Vertex *u, *v;
  41.     Arc *a;
  42.     int idx, i,j, sum;
  43.     depth = (int *)calloc(g->n,sizeof(int)); 
  44.     /* note that bins really should be calculated using scale  */
  45.     /*  e.g., bins = c*scale, where c is some constant */
  46.     /* scale can be extracted from g->id, but I don't want  */
  47.     /*  to bother with that right now */
  48.     /*
  49.      *    bins = BINCONST*g->n;
  50.      *    pathlendist = (int *)calloc(bins+1,sizeof(int)); 
  51.      *    maxpathlen = 0;
  52.      */
  53.     max = 0;
  54.     min = BIGINT;
  55.     sum = 0;
  56.     for (v = first(g),i=0; i< g->n; i++,v++) {
  57.         twofield_sptree(g,v,f0,f1); /* sets mdist for each node */
  58.         depth[i] = 0; /* paranoia */
  59.         for (u = first(g),j=0; j<g->n; j++,u++) { 
  60.     if (u->mdist > depth[i]) depth[i] = u->mdist;
  61.     /* if (u->dist > maxpathlen) maxpathlen = u->dist; */
  62.     /* pathlendist[bins] counts all lengths >= bins */
  63.     /* if (u->dist > bins) pathlendist[bins]++; */
  64.     /* else pathlendist[u->dist]++; */
  65. sum += depth[i];
  66. if (depth[i] < min) min = depth[i];
  67.         if (depth[i] > max) max = depth[i];
  68.     }
  69.     avg = (float)sum/g->n;
  70.     *rmax = max;
  71.     *rmin = min;
  72.     *ravg = avg;
  73. }
  74. /* convert depth data into a distribution */
  75. /* assumes dopaths has already been called, and that min, max, depth */
  76. /*     have valid data */
  77. void
  78. dodepthdist(Graph *g, int** ddist)
  79. {
  80. int num, i;
  81.   num = max - min + 1;
  82.   *ddist = (int *)calloc(num,sizeof(int));
  83.   for (i = 0; i < g->n; i++) 
  84.     (*ddist)[depth[i] - min]++;
  85. }
  86. #define rank z.I
  87. #define parent y.V
  88. #define untagged x.A
  89. #define link w.V
  90. #define min v.V
  91. #define idx(g,v) v-g->vertices
  92. /* count bicomponents. */
  93. /* verbose=0 means no printouts, just return the number. */
  94. int bicomp(Graph *g,int verbose)
  95. {
  96.     register Vertex *v;
  97.     long            nn;
  98.     Vertex          dummy;
  99.     Vertex         *active_stack;
  100.     Vertex         *vv;
  101.     Vertex         *artic_pt = NULL;
  102.     int count = 0;
  103.     for (v = g->vertices; v < g->vertices + g->n; v++) {
  104. v->rank = 0;
  105. v->untagged = v->arcs;
  106.         v->link = NULL;
  107.     }
  108.     nn = 0;
  109.     active_stack = NULL;
  110.     dummy.rank = 0;
  111.     for (vv = g->vertices; vv < g->vertices + g->n; vv++)
  112. if (vv->rank == 0) {
  113.     v = vv;
  114.     v->parent = &dummy;
  115.     v->rank = ++nn;
  116.     v->link = active_stack;
  117.     active_stack = v;
  118.     v->min = v->parent;
  119.     do {
  120. register Vertex *u;
  121. register Arc   *a = v->untagged;
  122. if (a) {
  123.     u = a->tip;
  124.     v->untagged = a->next;
  125.     if (u->rank) {
  126. if (u->rank < v->min->rank)
  127.     v->min = u;
  128.     } else {
  129. u->parent = v;
  130. v = u;
  131. v->rank = ++nn;
  132. v->link = active_stack;
  133. active_stack = v;
  134. v->min = v->parent;
  135.     }
  136. } else {
  137.     u = v->parent;
  138.     if (v->min == u) /* 19: */
  139. if (u == &dummy) {
  140.     if (verbose) {
  141.     if (artic_pt)
  142. printf(" and %d (this ends a connected component of the graph)n", idx(g, artic_pt));
  143.     else
  144. printf("Isolated vertex %dn", idx(g, v));
  145.     }
  146.     active_stack = artic_pt = NULL;
  147. } else {
  148.     register Vertex *t;
  149.     if (artic_pt && verbose)
  150. printf(" and articulation point %dn", 
  151. idx(g, artic_pt));
  152.     t = active_stack;
  153.     active_stack = v->link;
  154.     if (verbose) printf("Bicomponent %d", idx(g,v));
  155.     count++;
  156.     if (verbose) {
  157.     if (t == v)
  158. putchar('n');
  159.     else {
  160. printf(" also includes:n");
  161. while (t != v) {
  162.     printf(" %d (from %d; ..to %d)n",
  163.        idx(g,t),idx(g,t->parent),idx(g,t->min));
  164.     t = t->link;
  165. }
  166.     }
  167.     }
  168.     artic_pt = u;
  169. }
  170.     else if (v->min->rank < u->min->rank)
  171. u->min = v->min;
  172.     v = u;
  173. }
  174.     }
  175.     while (v != &dummy);
  176. }
  177.     return count;
  178. }
  179. void twofield_sptree(g,u,f0,f1)
  180. Graph*g;
  181. Vertex*u;
  182. enum Field f0,f1;
  183. {
  184. Vertex *v, *t;
  185. Arc *r;
  186.    int newdist;
  187. for (t = g->vertices; t < g->vertices + g->n; t++) {
  188. t->backlink = NULL;
  189. t->dist = BIGINT;
  190. t->mdist = 0;
  191. }
  192. u->backlink = u;
  193. u->dist = 0;
  194. u->mdist = 0;
  195. t = u;
  196. (*init_queue)(0L); /* queue contains only unknown v's */
  197. while (t != NULL) {
  198. /* invariant: u is known => u->mdist and u->dist are correct */
  199.     for (r = t->arcs; r; r=r->next) {
  200. v = r->tip;
  201. /* newdist = t->dist + r->len; */
  202. switch (f0) {
  203. case Len: newdist = t->dist + r->len; break;
  204. case A: newdist = t->dist + r->a.I; break;
  205. case B: newdist = t->dist + r->b.I; break;
  206. case Hops: newdist = t->dist + 1;
  207. }
  208. if (v->backlink) { /* v was seen but not known */
  209.     if (newdist < v->dist) {
  210. v->backlink = t;
  211. /* v->hops = t->hops + 1; */
  212. switch (f1) {
  213. case Len: v->mdist = t->mdist + r->len; break;
  214. case A: v->mdist = t->mdist + r->a.I; break;
  215. case B: v->mdist = t->mdist + r->b.I; break;
  216. case Hops: v->mdist = t->mdist + 1;
  217. }
  218. (*requeue)(v,newdist);
  219.     }
  220.     }
  221. else { /* newly seen */
  222.     v->backlink = t;
  223.     /* v->hops = t->hops + 1; */
  224.     switch (f1) {
  225. case Len: v->mdist = t->mdist + r->len; break;
  226. case A: v->mdist = t->mdist + r->a.I; break;
  227. case B: v->mdist = t->mdist + r->b.I; break;
  228. case Hops: v->mdist = t->mdist + 1;
  229. }
  230.     (*enqueue)(v,newdist);
  231. }
  232.     }
  233.     t = (*del_min)();
  234.         }
  235. }