Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

calcdest.cc

Go to the documentation of this file.
00001 extern "C" {
00002 #include <assert.h>
00003 #include <fcntl.h>
00004 #include <math.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <sys/time.h>
00009 #include <sys/types.h>
00010 #include <sys/uio.h>
00011 #include <unistd.h>
00012 /* #include <err.h>*/
00013 };
00014 #include "../../../tools/rng.h"
00015 #include "setdest.h"
00016 
00017 //#define               DEBUG
00018 #define         SANITY_CHECKS
00019 //#define               SHOW_SYMMETRIC_PAIRS
00020 
00021 
00022 #define GOD_FORMAT      "$ns_ at %.12f \"$god_ set-dist %d %d %d\"\n"
00023 #define GOD_FORMAT2     "$god_ set-dist %d %d %d\n"
00024 #define NODE_FORMAT     "$ns_ at %.12f \"$node_(%d) setdest %.12f %.12f %.12f\"\n"
00025 #define NODE_FORMAT2    "$node_(%d) setdest %.12f %.12f %.12f\n"
00026 #define NODE_FORMAT3    "$node_(%d) set %c_ %.12f\n"
00027 
00028 #undef          INFINITY
00029 #define         INFINITY        0x00ffffff
00030 #define         min(x,y)        ((x) < (y) ? (x) : (y))
00031 #define         max(x,y)        ((x) > (y) ? (x) : (y))
00032 #define         ROUND_ERROR     1e-9
00033 
00034 static int count = 0;
00035 
00036 /* ======================================================================
00037    Function Prototypes
00038    ====================================================================== */
00039 void            usage(char**);
00040 void            init(void);
00041 double          uniform(void);
00042 
00043 void            dumpall(void);
00044 void            ComputeW(void);
00045 void            floyd_warshall(void);
00046 
00047 void            show_diffs(void);
00048 void            show_routes(void);
00049 void            show_counters(void);
00050 
00051 
00052 /* ======================================================================
00053    Global Variables
00054    ====================================================================== */
00055 double          RANGE = 250.0;          // transmitter range in meters
00056 double          TIME = 0.0;             // my clock;
00057 double          MAXTIME = 0.0;          // duration of simulation
00058 
00059 double          MAXX = 0.0;
00060 double          MAXY = 0.0;
00061 double          MAXSPEED = 0.0;
00062 double          PAUSE = 0.0;
00063 u_int32_t       NODES = 0;
00064 u_int32_t       RouteChangeCount = 0;
00065 u_int32_t       LinkChangeCount = 0;
00066 u_int32_t       DestUnreachableCount = 0;
00067 
00068 Node            *NodeList = 0;
00069 u_int32_t       *D1 = 0;
00070 u_int32_t       *D2 = 0;
00071 
00072 FILE            *in_file;
00073 FILE            *out_file;
00074 
00075 
00076 /* ======================================================================
00077    Random Number Generation
00078    ====================================================================== */
00079 #define M               2147483647L
00080 #define INVERSE_M       ((double)4.656612875e-10)
00081 
00082 char random_state[32];
00083 RNG *rng;
00084 
00085 double
00086 uniform()
00087 {
00088         count++;
00089         return rng->uniform_double();
00090 }
00091 
00092 
00093 /* ======================================================================
00094    Misc Functions...
00095    ====================================================================== */
00096 void
00097 usage(char **argv)
00098 {
00099         fprintf(stderr,
00100                 "\nusage: %s\t[-n <nodes>] \n",
00101                 argv[0]);
00102         fprintf(stderr,
00103                 "\t\t[-t <simulation time>]\n");
00104         fprintf(stderr,
00105                 "\t\t-i <input_file> -o <output file>\n");
00106         fprintf(stderr,
00107 "\t\t #nodes, max time, and range read from scenario file if possible\n\n");
00108         
00109 }
00110 
00111 void
00112 init()
00113 {
00114         /*
00115          * Initialized the Random Number Generation
00116          */
00117 
00118         /*
00119          * Allocate memory for globals
00120          */
00121         NodeList = new Node[NODES];
00122         if(NodeList == 0) {
00123                 perror("new");
00124                 exit(1);
00125         }
00126 
00127         D1 = new u_int32_t[NODES * NODES];
00128         if(D1 == 0) {
00129                 perror("new");
00130                 exit(1);
00131         }
00132         memset(D1, '\xff', sizeof(u_int32_t) * NODES * NODES);
00133 
00134         D2 = new u_int32_t[NODES * NODES];
00135         if(D2 == 0) {
00136                 perror("new");
00137                 exit(1);
00138         }
00139         memset(D2, '\xff', sizeof(u_int32_t) * NODES * NODES);
00140 }
00141 
00142 void
00143 OpenAndReadHeader(char *in_filename, char *out_filename)
00144   /* assumes all initialization comments are at top of file with no
00145      no lines that start with other than '#' */
00146 {
00147   char buf[256];
00148   
00149   in_file = fopen(in_filename,"r");
00150   out_file = fopen(out_filename,"w");
00151   
00152   if (NULL == in_file) 
00153         fprintf(stderr, "*** can't open inputfile %s",in_filename);
00154   if (NULL == out_file) 
00155         fprintf(stderr,"can't open outputfile %s",out_filename);
00156   
00157   while (!feof(in_file)) {
00158 
00159     *buf = fgetc(in_file);
00160     ungetc(*buf,in_file);
00161     if (*buf != '#') break;
00162 
00163     fgets(buf, sizeof(buf), in_file);
00164 
00165     /* check to see if we need data from the line */
00166     sscanf(buf, "# nodes: %d, max time: %lf", &NODES, &MAXTIME);
00167     sscanf(buf, "# nominal range: %lf", &RANGE);
00168     
00169     fprintf(out_file, "%s", buf);
00170   }
00171   NODES += 1;                   // correct for 1-based indexs
00172   fflush(out_file);
00173 }
00174 
00175 void
00176 ReadInMovementPattern()
00177 {
00178   char buf[256];
00179   u_int n;
00180   double x,y,z,t,s;
00181   struct setdest *setdest;
00182 
00183   while (!feof(in_file)) {
00184 
00185     fgets(buf, sizeof(buf), in_file);
00186     fprintf(out_file, "%s", buf);
00187     if (*buf == '#') continue;
00188     if (*buf == '\n') continue;
00189 
00190     /* check to see if we need data from the line */
00191     if (2 == sscanf(buf,"$node_(%d) set Z_ %lf", &n, &z)) 
00192       {
00193         assert(n < NODES);
00194         NodeList[n].position.Z = z;
00195       }
00196     else if (2 == sscanf(buf,"$node_(%d) set X_ %lf", &n, &x)) 
00197       {
00198         assert(n < NODES);
00199         NodeList[n].position.X = x;
00200       }
00201     else if (2 == sscanf(buf,"$node_(%d) set Y_ %lf", &n, &y)) 
00202       {
00203         assert(n < NODES);
00204         NodeList[n].position.Y = y;
00205       }
00206     else if (5 == sscanf(buf,"$ns_ at %lf \"$node_(%d) setdest %lf %lf %lf\"", 
00207                         &t, &n, &x, &y, &s)) 
00208       {
00209         assert(n < NODES);
00210         assert(t <= MAXTIME);
00211         setdest = (struct setdest *)malloc(sizeof(*setdest));
00212         assert(setdest);
00213         setdest->X = x; setdest->Y = y; setdest->Z = 0;
00214         setdest->time = t;
00215         setdest->speed = s;
00216         if (NodeList[n].traj.lh_first 
00217             && t > NodeList[n].traj.lh_first->time)
00218           {
00219             printf("setdest's must be in anti-chronological order in input file!\n");
00220             printf("failed on node %d\n",n);
00221             exit(-1);
00222           }
00223         LIST_INSERT_HEAD(&NodeList[n].traj,setdest,traj);
00224       }
00225     else 
00226       {
00227         printf("unparsable line: '%s'", buf);
00228         continue;
00229       }
00230   }  
00231   fflush(out_file);  
00232 }
00233 
00234 extern "C" char *optarg;
00235 int
00236 main(int argc, char **argv)
00237 {
00238         char ch;
00239         char *in_filename = NULL;
00240         char *out_filename = NULL;
00241 
00242         while ((ch = getopt(argc, argv, "n:t:i:o:")) != EOF) {       
00243 
00244                 switch (ch) { 
00245 
00246                 case 'n':
00247                         NODES = atoi(optarg) + 1;
00248                         break;
00249 
00250                 case 't':
00251                         MAXTIME = atof(optarg);
00252                         break;
00253         
00254                 case 'i':
00255                         in_filename = optarg;
00256                         break;
00257 
00258                 case 'o':
00259                         out_filename = optarg;
00260                         break;
00261 
00262                 default:
00263                         usage(argv);
00264                         exit(1);
00265                 }
00266         }
00267 
00268         if (NULL == in_filename || NULL == out_filename) {
00269                 usage(argv);
00270                 exit(1);
00271         }
00272 
00273         OpenAndReadHeader(in_filename, out_filename);
00274 
00275         if(NODES == 0 || MAXTIME == 0.0) {
00276                 usage(argv);
00277                 exit(1);
00278         }
00279         // A more portable solution for random number generation
00280         rng = new RNG;
00281         rng->set_seed(RNG::HEURISTIC_SEED_SOURCE); 
00282         init();
00283 
00284         ReadInMovementPattern();
00285 
00286         while(TIME <= MAXTIME) {
00287                 double nexttime = 0.0;
00288                 u_int32_t i;
00289 
00290                 for(i = 1; i < NODES; i++) {
00291                         NodeList[i].Update();
00292                 }
00293 
00294                 for(i = 1; i < NODES; i++) {
00295                         NodeList[i].UpdateNeighbors();
00296                 }
00297 
00298                 for(i = 1; i < NODES; i++) {
00299                         Node *n = &NodeList[i];
00300         
00301                         if(n->time_transition > 0.0) {
00302                                 if(nexttime == 0.0)
00303                                         nexttime = n->time_transition;
00304                                 else
00305                                         nexttime = min(nexttime, n->time_transition);
00306                         }
00307 
00308                         if(n->time_arrival > 0.0) {
00309                                 if(nexttime == 0.0)
00310                                         nexttime = n->time_arrival;
00311                                 else
00312                                         nexttime = min(nexttime, n->time_arrival);
00313                         }
00314                 }
00315 
00316                 floyd_warshall();
00317 
00318 #ifdef DEBUG
00319                 show_routes();
00320 #endif
00321 
00322                 show_diffs();
00323 
00324 #ifdef DEBUG
00325                 dumpall();
00326 #endif
00327 
00328                 if (nexttime <= TIME + ROUND_ERROR) 
00329                   TIME = MAXTIME + 1;   /* we're done */
00330                 else 
00331                   TIME = nexttime;
00332 #ifdef OLD
00333                 assert(nexttime > TIME + ROUND_ERROR);
00334                 TIME = nexttime;
00335 #endif
00336 
00337         }
00338 
00339         show_counters();
00340 
00341         int of;
00342         if ((of = open(".rand_state",O_WRONLY | O_TRUNC | O_CREAT, 0777)) < 0)
00343           fprintf(stderr,"open rand state");
00344         for (unsigned int i = 0; i < sizeof(random_state); i++)
00345           random_state[i] = 0xff & (int) (uniform() * 256);
00346         if (write(of,random_state, sizeof(random_state)) < 0)
00347           fprintf(stderr,"writing rand state");
00348         close(of);
00349 }
00350 
00351 
00352 /* ======================================================================
00353    Node Class Functions
00354    ====================================================================== */
00355 u_int32_t Node::NodeIndex = 0;
00356 
00357 Node::Node()
00358 {
00359         u_int32_t i;
00360 
00361         index = NodeIndex++;
00362 
00363         if(index == 0)
00364                 return;
00365 
00366         route_changes = 0;
00367         link_changes = 0;
00368 
00369         /*
00370          * For the first PAUSE seconds of the simulation, all nodes
00371          * are stationary.
00372          */
00373         time_arrival = TIME;
00374         time_update = TIME;
00375         time_transition = 0.0;
00376 
00377         position.X = position.Y = position.Z = 0.0;
00378         destination.X = destination.Y = destination.Z = 0.0;
00379         direction.X = direction.Y = direction.Z = 0.0;
00380         speed = 0.0;
00381 
00382         neighbor = new Neighbor[NODES];
00383         if(neighbor == 0) {
00384                 perror("new");
00385                 exit(1);
00386         }
00387 
00388         LIST_INIT(&traj);
00389 
00390         for(i = 1; i < NODES; i++) {
00391                 neighbor[i].index = i;
00392                 neighbor[i].reachable = (index == i) ? 1 : 0;
00393                 neighbor[i].time_transition = 0.0;
00394         }
00395 }
00396 
00397 
00398 
00399 void
00400 Node::RandomPosition()
00401 {
00402         position.X = uniform() * MAXX;
00403         position.Y = uniform() * MAXY;
00404         position.Z = 0.0;
00405 }
00406 
00407 
00408 void
00409 Node::RandomDestination()
00410 {
00411         destination.X = uniform() * MAXX;
00412         destination.Y = uniform() * MAXY;
00413         destination.Z = 0.0;
00414         assert(destination != position);
00415 }
00416 
00417 void
00418 Node::RandomSpeed()
00419 {
00420         speed = uniform() * MAXSPEED;
00421 
00422         assert(speed != 0.0);
00423 }
00424 
00425 
00426 void
00427 Node::Update()
00428 {
00429         struct setdest *setdest = traj.lh_first;
00430 
00431         position += (speed * (TIME - time_update)) * direction;
00432 
00433         if(TIME == time_arrival) {
00434 
00435           if (NULL == setdest) 
00436             {
00437               destination = position;
00438               direction.X = direction.Y = direction.Z = 0.0;
00439               speed = 0.0;
00440               time_arrival = MAXTIME + 1;
00441             } 
00442           else 
00443             {
00444               vector v;
00445               destination.X = setdest->X;
00446               destination.Y = setdest->Y;
00447               speed = setdest->speed;
00448               if (0.0 == speed)
00449                 { // it's a pause at the current location
00450                   if (LIST_NEXT(setdest,traj))
00451                     time_arrival = LIST_NEXT(setdest,traj)->time;
00452                   else
00453                     time_arrival = MAXTIME + 1;
00454                 }
00455               else 
00456                 { // we're moving somewhere, when do we get there?
00457                   v = destination - position;
00458                   direction = v / v.length();
00459                   time_arrival = TIME + v.length() / speed;
00460                 }
00461               LIST_REMOVE(setdest,traj);
00462               free(setdest);
00463             }
00464         }
00465 
00466         time_update = TIME;
00467         time_transition = 0.0;
00468 }
00469 
00470 
00471 void
00472 Node::UpdateNeighbors()
00473 {
00474         static Node *n2;
00475         static Neighbor *m1, *m2;
00476         static vector D, B, v1, v2;
00477         static double a, b, c, t1, t2, Q;
00478         static u_int32_t i, reachable;
00479 
00480         v1 = speed * direction;
00481 
00482         /*
00483          *  Only need to go from INDEX --> N for each one since links
00484          *  are symmetric.
00485          */
00486         for(i = index+1; i < NODES; i++) {
00487 
00488                 m1 = &neighbor[i];
00489                 n2 = &NodeList[i];
00490                 m2 = &n2->neighbor[index];
00491 
00492                 assert(i == m1->index);
00493                 assert(m1->index == n2->index);
00494                 assert(index == m2->index);
00495                 assert(m1->reachable == m2->reachable);
00496 
00497                 reachable = m1->reachable;
00498 
00499                 /* ==================================================
00500                    Determine Reachability
00501                    ================================================== */
00502                 {       vector d = position - n2->position;
00503 
00504                         if(d.length() < RANGE) {
00505 #ifdef SANITY_CHECKS
00506                                 if(TIME > 0.0 && m1->reachable == 0)
00507                                         assert(RANGE - d.length() < ROUND_ERROR);
00508 #endif
00509                                 m1->reachable = m2->reachable = 1;
00510                         }
00511                         // Boundary condition handled below.
00512                         else {
00513 #ifdef SANITY_CHECKS
00514                                 if(TIME > 0.0 && m1->reachable == 1)
00515                                         assert(d.length() - RANGE < ROUND_ERROR);
00516 #endif
00517                                 m1->reachable = m2->reachable = 0;
00518                         }
00519 #ifdef DEBUG
00520                         fprintf(stdout, "# %.6f (%d, %d) %.2fm\n",
00521                                 TIME, index, m1->index, d.length());
00522 #endif
00523                 }
00524 
00525                 /* ==================================================
00526                    Determine Next Event Time
00527                    ================================================== */
00528                 v2 = n2->speed * n2->direction;
00529 
00530                 D = v2 - v1;
00531                 B = n2->position - position;
00532 
00533                 a = (D.X * D.X) + (D.Y * D.Y) + (D.Z * D.Z);
00534                 b = 2 * ((D.X * B.X) + (D.Y * B.Y) + (D.Z * B.Z));
00535                 c = (B.X * B.X) + (B.Y * B.Y) + (B.Z * B.Z) - (RANGE * RANGE);
00536 
00537                 if(a == 0.0) {
00538                         /*
00539                          *  No Finite Solution
00540                          */
00541                         m1->time_transition= 0.0;
00542                         m2->time_transition= 0.0;
00543                         goto  next;
00544                 }
00545 
00546                 Q = b * b - 4 * a * c;
00547                 if(Q < 0.0) {
00548                         /*
00549                          *  No real roots.
00550                          */
00551                         m1->time_transition = 0.0;
00552                         m2->time_transition = 0.0;
00553                         goto next;
00554                 }
00555                 Q = sqrt(Q);
00556 
00557                 t1 = (-b + Q) / (2 * a);
00558                 t2 = (-b - Q) / (2 * a);
00559 
00560                 // Stupid Rounding/Boundary Cases
00561                 if(t1 > 0.0 && t1 < ROUND_ERROR) t1 = 0.0;
00562                 if(t1 < 0.0 && -t1 < ROUND_ERROR) t1 = 0.0;
00563                 if(t2 > 0.0 && t2 < ROUND_ERROR) t2 = 0.0;
00564                 if(t2 < 0.0 && -t2 < ROUND_ERROR) t2 = 0.0;
00565 
00566                 if(t1 < 0.0 && t2 < 0.0) {
00567                         /*
00568                          *  No "future" time solution.
00569                          */
00570                         m1->time_transition = 0.0;
00571                         m2->time_transition = 0.0;
00572                         goto next;
00573                 }
00574 
00575                 /*
00576                  * Boundary conditions.
00577                  */
00578                 if((t1 == 0.0 && t2 > 0.0) || (t2 == 0.0 && t1 > 0.0)) {
00579                         m1->reachable = m2->reachable = 1;
00580                         m1->time_transition = m2->time_transition = TIME + max(t1, t2);
00581                 }
00582                 else if((t1 == 0.0 && t2 < 0.0) || (t2 == 0.0 && t1 < 0.0)) {
00583                         m1->reachable = m2->reachable = 0;
00584                         m1->time_transition = m2->time_transition = 0.0;
00585                 }
00586 
00587                 /*
00588                  * Non-boundary conditions.
00589                  */
00590                 else if(t1 > 0.0 && t2 > 0.0) {
00591                         m1->time_transition = TIME + min(t1, t2);
00592                         m2->time_transition = TIME + min(t1, t2);
00593                 }
00594                 else if(t1 > 0.0) {
00595                         m1->time_transition = TIME + t1;
00596                         m2->time_transition = TIME + t1;
00597                 }
00598                 else {
00599                         m1->time_transition = TIME + t2;
00600                         m2->time_transition = TIME + t2;
00601                 }
00602 
00603                 /* ==================================================
00604                    Update the transition times for both NODEs.
00605                    ================================================== */
00606                 if(time_transition == 0.0 || (m1->time_transition &&
00607                    time_transition > m1->time_transition)) {
00608                         time_transition = m1->time_transition;
00609                 }
00610                 if(n2->time_transition == 0.0 || (m2->time_transition &&
00611                    n2->time_transition > m2->time_transition)) {
00612                         n2->time_transition = m2->time_transition;
00613                 }
00614         next:
00615                 if(reachable != m1->reachable && TIME > 0.0) {
00616                         LinkChangeCount++;
00617                         link_changes++;
00618                         n2->link_changes++;
00619                 }
00620         }
00621 }
00622 
00623 void
00624 Node::Dump()
00625 {
00626         Neighbor *m;
00627         u_int32_t i;
00628 
00629         fprintf(stdout,
00630                 "Node: %d\tpos: (%.2f, %.2f, %.2f) dst: (%.2f, %.2f, %.2f)\n",
00631                 index, position.X, position.Y, position.Z,
00632                 destination.X, destination.Y, destination.Z);
00633         fprintf(stdout, "\tdir: (%.2f, %.2f, %.2f) speed: %.2f\n",
00634                 direction.X, direction.Y, direction.Z, speed);
00635         fprintf(stdout, "\tArrival: %.2f, Update: %.2f, Transition: %.2f\n",
00636                 time_arrival, time_update, time_transition);
00637 
00638         for(i = 1; i < NODES; i++) {
00639                 m = &neighbor[i];
00640                 fprintf(stdout, "\tNeighbor: %d (%x), Reachable: %d, Transition Time: %.2f\n",
00641                         m->index, (int) m, m->reachable, m->time_transition);
00642         }
00643 }
00644 
00645 
00646 /* ======================================================================
00647    Dijkstra's Shortest Path Algoritm
00648    ====================================================================== */
00649 void dumpall()
00650 {
00651         u_int32_t i;
00652 
00653         fprintf(stdout, "\nTime: %.2f\n", TIME);
00654 
00655         for(i = 1; i < NODES; i++) {
00656                 NodeList[i].Dump();
00657         }
00658 }
00659 
00660 void
00661 ComputeW()
00662 {
00663         u_int32_t i, j;
00664         u_int32_t *W = D2;
00665 
00666         memset(W, '\xff', sizeof(int) * NODES * NODES);
00667 
00668         for(i = 1; i < NODES; i++) {
00669                 for(j = i; j < NODES; j++) {
00670                         Neighbor *m = &NodeList[i].neighbor[j];
00671                         if(i == j)
00672                                 W[i*NODES + j] = W[j*NODES + i] = 0;
00673                         else
00674                                 W[i*NODES + j] = W[j*NODES + i] = m->reachable ? 1 : INFINITY;  
00675                 }
00676         }
00677 }
00678 
00679 void
00680 floyd_warshall()
00681 {
00682         u_int32_t i, j, k;
00683 
00684         ComputeW();     // the connectivity matrix
00685 
00686         for(i = 1; i < NODES; i++) {
00687                 for(j = 1; j < NODES; j++) {
00688                         for(k = 1; k < NODES; k++) {
00689                                 D2[j*NODES + k] = min(D2[j*NODES + k], D2[j*NODES + i] + D2[i*NODES + k]);
00690                         }
00691                 }
00692         }
00693 
00694 #ifdef SANITY_CHECKS
00695         for(i = 1; i < NODES; i++)
00696                 for(j = 1; j < NODES; j++) {
00697                         assert(D2[i*NODES + j] == D2[j*NODES + i]);
00698                         assert(D2[i*NODES + j] <= INFINITY);
00699                 }
00700 #endif
00701 }
00702 
00703 
00704 /*
00705  *  Write the actual GOD entries to a TCL script.
00706  */
00707 void
00708 show_diffs()
00709 {
00710         u_int32_t i, j;
00711 
00712         for(i = 1; i < NODES; i++) {
00713                 for(j = i + 1; j < NODES; j++) {
00714                         if(D1[i*NODES + j] != D2[i*NODES + j]) {
00715 
00716                                 if(D2[i*NODES + j] == INFINITY)
00717                                         DestUnreachableCount++;
00718 
00719                                 if(TIME > 0.0) {
00720                                         RouteChangeCount++;
00721                                         NodeList[i].route_changes++;
00722                                         NodeList[j].route_changes++;
00723                                 }
00724 
00725                                 if(TIME == 0.0) {
00726                                         fprintf(out_file, GOD_FORMAT2,
00727                                                 i, j, D2[i*NODES + j]);
00728 #ifdef SHOW_SYMMETRIC_PAIRS
00729                                         fprintf(out_file, GOD_FORMAT2,
00730                                                 j, i, D2[j*NODES + i]);
00731 #endif
00732                                 }
00733                                 else {
00734                                         fprintf(out_file, GOD_FORMAT, 
00735                                                 TIME, i, j, D2[i*NODES + j]);
00736 #ifdef SHOW_SYMMETRIC_PAIRS
00737                                         fprintf(out_file, GOD_FORMAT, 
00738                                                 TIME, j, i, D2[j*NODES + i]);
00739 #endif
00740                                 }
00741                         }
00742                 }
00743         }
00744 
00745         memcpy(D1, D2, sizeof(int) * NODES * NODES);
00746 }
00747 
00748 
00749 void
00750 show_routes()
00751 {
00752         u_int32_t i, j;
00753 
00754         fprintf(stdout, "#\n# TIME: %.12f\n#\n", TIME);
00755         for(i = 1; i < NODES; i++) {
00756                 fprintf(stdout, "# %2d) ", i);
00757                 for(j = 1; j < NODES; j++)
00758                         fprintf(stdout, "%3d ", D2[i*NODES + j] & 0xff);
00759                 fprintf(stdout, "\n");
00760         }
00761         fprintf(stdout, "#\n");
00762 }
00763 
00764 void
00765 show_counters()
00766 {
00767         u_int32_t i;
00768 
00769         fprintf(out_file, "#\n# Destination Unreachables: %d\n#\n",
00770                 DestUnreachableCount);
00771         fprintf(out_file, "# Route Changes: %d\n#\n", RouteChangeCount);
00772         fprintf(out_file, "# Link Changes: %d\n#\n", LinkChangeCount);
00773         fprintf(out_file, "# Node | Route Changes | Link Changes\n");
00774         for(i = 1; i < NODES; i++)
00775                 fprintf(out_file, "# %4d |          %4d |         %4d\n",
00776                         i, NodeList[i].route_changes,
00777                         NodeList[i].link_changes);
00778         fprintf(out_file, "#\n");
00779 }
00780 

Generated on Tue Apr 20 12:14:11 2004 for NS2.26SourcesOriginal by doxygen 1.3.3