00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 extern "C" {
00041 #include <assert.h>
00042 #include <fcntl.h>
00043 #include <math.h>
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <sys/time.h>
00048 #include <sys/types.h>
00049 #include <sys/uio.h>
00050 #include <unistd.h>
00051 #if !defined(sun)
00052 #include <err.h>
00053 #endif
00054 };
00055 #include "../../../tools/rng.h"
00056
00057 #include "setdest.h"
00058
00059
00060
00061 #define SANITY_CHECKS
00062
00063
00064
00065 #define GOD_FORMAT "$ns_ at %.12f \"$god_ set-dist %d %d %d\"\n"
00066 #define GOD_FORMAT2 "$god_ set-dist %d %d %d\n"
00067 #define NODE_FORMAT "$ns_ at %.12f \"$node_(%d) setdest %.12f %.12f %.12f\"\n"
00068 #define NODE_FORMAT2 "$node_(%d) setdest %.12f %.12f %.12f\n"
00069 #define NODE_FORMAT3 "$node_(%d) set %c_ %.12f\n"
00070
00071 #define RTG_INFINITY 0x00ffffff
00072 #ifndef min
00073 #define min(x,y) ((x) < (y) ? (x) : (y))
00074 #define max(x,y) ((x) > (y) ? (x) : (y))
00075 #endif
00076 #define ROUND_ERROR 1e-9
00077 #ifndef PI
00078 #define PI 3.1415926
00079 #endif
00080
00081
00082 static int count = 0;
00083
00084
00085
00086
00087 void usage(char**);
00088 void init(void);
00089 double uniform(void);
00090
00091 void dumpall(void);
00092 void ComputeW(void);
00093 void floyd_warshall(void);
00094
00095 void show_diffs(void);
00096 void show_routes(void);
00097 void show_counters(void);
00098
00099
00100
00101
00102
00103 const double RANGE = 250.0;
00104 double TIME = 0.0;
00105 double MAXTIME = 0.0;
00106
00107 double MAXX = 0.0;
00108 double MAXY = 0.0;
00109 double PAUSE = 0.0;
00110 double MAXSPEED = 0.0;
00111 double MINSPEED = 0.0;
00112 double SS_AVGSPEED = 0.0;
00113 double KAPPA = 0.0;
00114 double MEAN = 0.0;
00115 double SIGMA = 0.0;
00116 double EXP_1_V = 0.0;
00117 double EXP_R = 0.0;
00118 double PDFMAX = 0.0;
00119 u_int32_t SPEEDTYPE = 1;
00120 u_int32_t PAUSETYPE = 1;
00121 u_int32_t VERSION = 1;
00122 u_int32_t NODES = 0;
00123 u_int32_t RouteChangeCount = 0;
00124 u_int32_t LinkChangeCount = 0;
00125 u_int32_t DestUnreachableCount = 0;
00126
00127
00128 Node *NodeList = 0;
00129 u_int32_t *D1 = 0;
00130 u_int32_t *D2 = 0;
00131
00132
00133
00134
00135
00136 #define M 2147483647L
00137 #define INVERSE_M ((double)4.656612875e-10)
00138
00139 char random_state[32];
00140 RNG *rng;
00141
00142 double
00143 uniform()
00144 {
00145 count++;
00146 return rng->uniform_double() ;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 void
00157 compute_EXP_R()
00158 {
00159 #define csc(x) (1.0/sin(x)) // csc function
00160 #define sec(x) (1.0/cos(x)) // sec function
00161 #define sin2(x) (sin(x)*sin(x)) // sin^2
00162 #define sin3(x) (sin2(x)*sin(x)) // sin^3
00163 #define cos2(x) (cos(x)*cos(x)) // cos^2
00164 #define cos3(x) (cos2(x)*cos(x)) // cos^3
00165
00166 double x = MAXX, y = MAXY;
00167 double x2 = x*x, x3 = x*x*x;
00168 double y2 = y*y, y3 = y*y*y;
00169
00170 double term1 = sin(atan2(y,x)) / 2.0 / cos2(atan2(y,x));
00171 double term2 = 0.5 * log( sec(atan2(y,x)) + y/x );
00172 double term3 = -1.0 * x3 / y2 / 60.0 / cos3(atan2(y,x)) + 1.0/60.0 * x3 / y2;
00173 double term4 = (term1 + term2) * x2 / 12.0 / y + term3;
00174
00175 double term5 = -1.0 * cos(atan2(y,x)) / 2.0 / sin2(atan2(y,x));
00176 double term6 = 0.5 * log( csc(atan2(y,x)) - x/y );
00177 double term7 = -1.0 * y3 / x2 / 60.0 / sin3(atan2(y,x)) + 1.0/60.0 * y3 / x2;
00178 double term8 = -1.0 * (term5 + term6) * y2 / 12.0 / x + term7;
00179
00180 EXP_R = (4 * (term4 + term8));
00181 }
00182
00183 void
00184 usage(char **argv)
00185 {
00186 fprintf(stderr, "\nusage:\n");
00187 fprintf(stderr,
00188 "\n<original 1999 CMU version (version 1)>\n %s\t-v <1> -n <nodes> -p <pause time> -M <max speed>\n",
00189 argv[0]);
00190 fprintf(stderr,
00191 "\t\t-t <simulation time> -x <max X> -y <max Y>\n");
00192 fprintf(stderr,
00193 "\nOR\n<modified 2003 U.Michigan version (version 2)>\n %s\t-v <2> -n <nodes> -s <speed type> -m <min speed> -M <max speed>\n",
00194 argv[0]);
00195 fprintf(stderr,
00196 "\t\t-t <simulation time> -P <pause type> -p <pause time> -x <max X> -y <max Y>\n");
00197 fprintf(stderr,
00198 "\t\t(Refer to the script files make-scen.csh and make-scen-steadystate.csh for detail.) \n\n");
00199 }
00200
00201 void
00202 init()
00203 {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 NodeList = new Node[NODES];
00250 if(NodeList == 0) {
00251 perror("new");
00252 exit(1);
00253 }
00254
00255 D1 = new u_int32_t[NODES * NODES];
00256 if(D1 == 0) {
00257 perror("new");
00258 exit(1);
00259 }
00260 memset(D1, '\xff', sizeof(u_int32_t) * NODES * NODES);
00261
00262 D2 = new u_int32_t[NODES * NODES];
00263 if(D2 == 0) {
00264 perror("new");
00265 exit(1);
00266 }
00267 memset(D2, '\xff', sizeof(u_int32_t) * NODES * NODES);
00268 }
00269
00270 extern "C" char *optarg;
00271
00272 int
00273 main(int argc, char **argv)
00274 {
00275 char ch;
00276
00277 while ((ch = getopt(argc, argv, "v:n:s:m:M:t:P:p:x:y:i:o:")) != EOF) {
00278
00279 switch (ch) {
00280
00281 case 'v':
00282 VERSION = atoi(optarg);
00283 break;
00284
00285 case 'n':
00286 NODES = atoi(optarg);
00287 break;
00288
00289 case 's':
00290 SPEEDTYPE = atoi(optarg);
00291 break;
00292
00293 case 'm':
00294 MINSPEED = atof(optarg);
00295 break;
00296
00297 case 'M':
00298 MAXSPEED = atof(optarg);
00299 break;
00300
00301 case 't':
00302 MAXTIME = atof(optarg);
00303 break;
00304
00305 case 'P':
00306 PAUSETYPE = atoi(optarg);
00307 break;
00308
00309 case 'p':
00310 PAUSE = atof(optarg);
00311 break;
00312
00313 case 'x':
00314 MAXX = atof(optarg);
00315 break;
00316
00317 case 'y':
00318 MAXY = atof(optarg);
00319 break;
00320
00321 default:
00322 usage(argv);
00323 exit(1);
00324 }
00325 }
00326
00327 if(MAXX == 0.0 || MAXY == 0.0 || NODES == 0 || MAXTIME == 0.0) {
00328 usage(argv);
00329 exit(1);
00330 }
00331
00332
00333 if (VERSION != 1 && VERSION != 2) {
00334 printf("Please specify the setdest version you want to use. For original 1999 CMU version use 1; For modified 2003 U.Michigan version use 2\n");
00335 exit(1);
00336 }
00337
00338 if (VERSION == 2 && MINSPEED <= 0) {
00339 usage(argv);
00340 exit(1);
00341 } else if (VERSION == 1 && MINSPEED > 0) {
00342 usage(argv);
00343 exit(1);
00344 }
00345
00346
00347
00348 rng = new RNG;
00349 rng->set_seed(RNG::HEURISTIC_SEED_SOURCE);
00350
00351
00352
00353
00354
00355
00356
00357
00358 if (VERSION == 1) {
00359 fprintf(stdout, "#\n# nodes: %d, pause: %.2f, max speed: %.2f, max x: %.2f, max y: %.2f\n#\n",
00360 NODES, PAUSE, MAXSPEED, MAXX, MAXY);
00361 }
00362
00363
00364 else if (VERSION == 2) {
00365
00366 compute_EXP_R();
00367
00368
00369 if (SPEEDTYPE == 1) {
00370 EXP_1_V = log(MAXSPEED/MINSPEED) / (MAXSPEED - MINSPEED);
00371 SS_AVGSPEED = EXP_R / (EXP_1_V*EXP_R + PAUSE);
00372 PDFMAX = 1/MINSPEED*EXP_R / (EXP_1_V*EXP_R + PAUSE) / (MAXSPEED-MINSPEED);
00373 }
00374
00375
00376 else if (SPEEDTYPE == 2) {
00377 int bin_no = 10000;
00378 double delta = (MAXSPEED - MINSPEED)/bin_no;
00379 int i;
00380 double acc_k, acc_e, square, temp_v;
00381
00382 MEAN = (MAXSPEED + MINSPEED)/2.0;
00383 SIGMA = (MAXSPEED - MINSPEED)/4.0;
00384
00385 KAPPA = 0.0;
00386 EXP_1_V = 0.0;
00387 PDFMAX = 0.0;
00388
00389
00390 for (i=0; i<bin_no; ++i) {
00391 temp_v = MINSPEED + i*delta;
00392 square = (temp_v - MEAN)*(temp_v - MEAN)/SIGMA/SIGMA;
00393
00394 acc_k = 1.0/sqrt(2.0*PI*SIGMA*SIGMA)*exp(-0.5*square);
00395 KAPPA += (acc_k*delta);
00396
00397 acc_e = 1.0/temp_v/sqrt(2.0*PI*SIGMA*SIGMA)*exp(-0.5*square);
00398 EXP_1_V += (acc_e*delta);
00399
00400
00401 if (PDFMAX < acc_e) PDFMAX = acc_e;
00402 }
00403 EXP_1_V /= KAPPA;
00404 SS_AVGSPEED = EXP_R / (EXP_1_V*EXP_R + PAUSE);
00405 PDFMAX = EXP_R*PDFMAX/KAPPA / (EXP_1_V*EXP_R + PAUSE);
00406 }
00407
00408 else
00409 ;
00410
00411 fprintf(stdout, "#\n# nodes: %d, speed type: %d, min speed: %.2f, max speed: %.2f\n# avg speed: %.2f, pause type: %d, pause: %.2f, max x: %.2f, max y: %.2f\n#\n",
00412 NODES , SPEEDTYPE, MINSPEED, MAXSPEED, SS_AVGSPEED, PAUSETYPE, PAUSE, MAXX, MAXY);
00413 }
00414
00415
00416 init();
00417
00418 while(TIME <= MAXTIME) {
00419 double nexttime = 0.0;
00420 u_int32_t i;
00421
00422 for(i = 0; i < NODES; i++) {
00423 NodeList[i].Update();
00424 }
00425
00426 for(i = 0; i < NODES; i++) {
00427 NodeList[i].UpdateNeighbors();
00428 }
00429
00430 for(i = 0; i < NODES; i++) {
00431 Node *n = &NodeList[i];
00432
00433 if(n->time_transition > 0.0) {
00434 if(nexttime == 0.0)
00435 nexttime = n->time_transition;
00436 else
00437 nexttime = min(nexttime, n->time_transition);
00438 }
00439
00440 if(n->time_arrival > 0.0) {
00441 if(nexttime == 0.0)
00442 nexttime = n->time_arrival;
00443 else
00444 nexttime = min(nexttime, n->time_arrival);
00445 }
00446
00447 }
00448
00449 floyd_warshall();
00450
00451 #ifdef DEBUG
00452 show_routes();
00453 #endif
00454
00455 show_diffs();
00456
00457 #ifdef DEBUG
00458 dumpall();
00459 #endif
00460
00461 assert(nexttime > TIME + ROUND_ERROR);
00462 TIME = nexttime;
00463 }
00464
00465 show_counters();
00466
00467 int of;
00468 if ((of = open(".rand_state",O_WRONLY | O_TRUNC | O_CREAT, 0777)) < 0) {
00469 fprintf(stderr, "open rand state\n");
00470 exit(-1);
00471 }
00472 for (unsigned int i = 0; i < sizeof(random_state); i++)
00473 random_state[i] = 0xff & (int) (uniform() * 256);
00474 if (write(of,random_state, sizeof(random_state)) < 0) {
00475 fprintf(stderr, "writing rand state\n");
00476 exit(-1);
00477 }
00478 close(of);
00479
00480
00481 }
00482
00483
00484
00485
00486
00487 u_int32_t Node::NodeIndex = 0;
00488
00489 Node::Node()
00490 {
00491 u_int32_t i;
00492
00493 index = NodeIndex++;
00494
00495
00496
00497
00498 route_changes = 0;
00499 link_changes = 0;
00500
00501
00502
00503
00504
00505
00506
00507
00508 if (VERSION == 1) {
00509 time_arrival = TIME + PAUSE;
00510 }
00511
00512
00513 else if (VERSION == 2) {
00514
00515 double prob_pause = PAUSE / (EXP_1_V*EXP_R + PAUSE);
00516
00517
00518 if (prob_pause > uniform()) {
00519
00520 if (PAUSETYPE == 1) {
00521 time_arrival = TIME + PAUSE;
00522 }
00523
00524 else if (PAUSETYPE == 2) {
00525 time_arrival = TIME + 2*PAUSE*uniform();
00526 }
00527
00528 first_trip = 0;
00529 }
00530
00531 else {
00532 time_arrival = TIME;
00533 first_trip = 1;
00534 }
00535 }
00536
00537
00538 time_update = TIME;
00539 time_transition = 0.0;
00540
00541 position.X = position.Y = position.Z = 0.0;
00542 destination.X = destination.Y = destination.Z = 0.0;
00543 direction.X = direction.Y = direction.Z = 0.0;
00544 speed = 0.0;
00545
00546 RandomPosition();
00547
00548 fprintf(stdout, NODE_FORMAT3, index, 'X', position.X);
00549 fprintf(stdout, NODE_FORMAT3, index, 'Y', position.Y);
00550 fprintf(stdout, NODE_FORMAT3, index, 'Z', position.Z);
00551
00552 neighbor = new Neighbor[NODES];
00553 if(neighbor == 0) {
00554 perror("new");
00555 exit(1);
00556 }
00557
00558 for(i = 0; i < NODES; i++) {
00559 neighbor[i].index = i;
00560 neighbor[i].reachable = (index == i) ? 1 : 0;
00561 neighbor[i].time_transition = 0.0;
00562 }
00563 }
00564
00565
00566
00567 void
00568 Node::RandomPosition()
00569 {
00570 position.X = uniform() * MAXX;
00571 position.Y = uniform() * MAXY;
00572 position.Z = 0.0;
00573 }
00574
00575
00576 void
00577 Node::RandomDestination()
00578 {
00579 destination.X = uniform() * MAXX;
00580 destination.Y = uniform() * MAXY;
00581 destination.Z = 0.0;
00582 assert(destination != position);
00583 }
00584
00585
00586
00587
00588
00589 void
00590 Node::RandomSpeed()
00591 {
00592
00593 if (VERSION == 1) {
00594 speed = uniform() * MAXSPEED;
00595 assert(speed != 0.0);
00596 }
00597
00598
00599 else if (VERSION == 2) {
00600
00601 if (SPEEDTYPE == 1) {
00602
00603 if (first_trip == 1) {
00604
00605 double temp_v, temp_fv;
00606
00607 do {
00608 temp_v = uniform() * (MAXSPEED - MINSPEED) + MINSPEED;
00609 temp_fv = uniform() * PDFMAX;
00610 } while (temp_fv > 1/temp_v*EXP_R / (EXP_1_V*EXP_R + PAUSE) / (MAXSPEED-MINSPEED));
00611
00612 speed = temp_v;
00613 first_trip = 0;
00614 }
00615
00616 else {
00617 speed = uniform() * (MAXSPEED - MINSPEED) + MINSPEED;
00618 assert(speed != 0.0);
00619 }
00620 }
00621
00622 else if (SPEEDTYPE == 2) {
00623
00624 if (first_trip == 1) {
00625 double temp_v, temp_fv, square, fv;
00626
00627
00628 do {
00629 temp_v = uniform() * (MAXSPEED - MINSPEED) + MINSPEED;
00630 temp_fv = uniform() * PDFMAX;
00631 square = (temp_v - MEAN)*(temp_v - MEAN)/SIGMA/SIGMA;
00632 fv = 1/KAPPA/sqrt(2.0*PI*SIGMA*SIGMA) * exp(-0.5*square);
00633 } while (temp_fv > 1.0/temp_v*fv*EXP_R / (EXP_1_V*EXP_R + PAUSE));
00634
00635 speed = temp_v;
00636 first_trip = 0;
00637 }
00638
00639 else {
00640 double temp_v, temp_fv, square;
00641 double max_normal = 1.0/KAPPA/sqrt(2.0*PI*SIGMA*SIGMA);
00642
00643
00644 do {
00645 temp_v = uniform() * (MAXSPEED - MINSPEED) + MINSPEED;
00646 temp_fv = uniform() * max_normal;
00647 square = (temp_v - MEAN)*(temp_v - MEAN)/SIGMA/SIGMA;
00648 } while (temp_fv > max_normal * exp(-0.5*square));
00649
00650 speed = temp_v;
00651 assert(speed != 0.0);
00652 }
00653 }
00654
00655 else
00656 ;
00657 }
00658 }
00659
00660
00661 void
00662 Node::Update()
00663 {
00664 position += (speed * (TIME - time_update)) * direction;
00665
00666 if(TIME == time_arrival) {
00667 vector v;
00668
00669 if(speed == 0.0 || PAUSE == 0.0) {
00670
00671 RandomDestination();
00672 RandomSpeed();
00673
00674 v = destination - position;
00675 direction = v / v.length();
00676 time_arrival = TIME + v.length() / speed;
00677 }
00678 else {
00679
00680 destination = position;
00681 speed = 0.0;
00682
00683
00684 if (VERSION == 1) {
00685 time_arrival = TIME + PAUSE;
00686 }
00687
00688 else if (VERSION == 2) {
00689
00690 if (PAUSETYPE == 1) {
00691 time_arrival = TIME + PAUSE;
00692 }
00693
00694 else if (PAUSETYPE == 2) {
00695 time_arrival = TIME + 2*PAUSE*uniform();
00696 }
00697 }
00698 }
00699
00700 fprintf(stdout, NODE_FORMAT,
00701 TIME, index, destination.X, destination.Y, speed);
00702
00703 }
00704
00705 time_update = TIME;
00706 time_transition = 0.0;
00707 }
00708
00709
00710 void
00711 Node::UpdateNeighbors()
00712 {
00713 static Node *n2;
00714 static Neighbor *m1, *m2;
00715 static vector D, B, v1, v2;
00716 static double a, b, c, t1, t2, Q;
00717 static u_int32_t i, reachable;
00718
00719 v1 = speed * direction;
00720
00721
00722
00723
00724
00725 for(i = index+1; i < NODES; i++) {
00726
00727 m1 = &neighbor[i];
00728 n2 = &NodeList[i];
00729 m2 = &n2->neighbor[index];
00730
00731 assert(i == m1->index);
00732 assert(m1->index == n2->index);
00733 assert(index == m2->index);
00734 assert(m1->reachable == m2->reachable);
00735
00736 reachable = m1->reachable;
00737
00738
00739
00740
00741 { vector d = position - n2->position;
00742
00743 if(d.length() < RANGE) {
00744 #ifdef SANITY_CHECKS
00745 if(TIME > 0.0 && m1->reachable == 0)
00746 assert(RANGE - d.length() < ROUND_ERROR);
00747 #endif
00748 m1->reachable = m2->reachable = 1;
00749 }
00750
00751 else {
00752 #ifdef SANITY_CHECKS
00753 if(TIME > 0.0 && m1->reachable == 1)
00754 assert(d.length() - RANGE < ROUND_ERROR);
00755 #endif
00756 m1->reachable = m2->reachable = 0;
00757 }
00758 #ifdef DEBUG
00759 fprintf(stdout, "# %.6f (%d, %d) %.2fm\n",
00760 TIME, index, m1->index, d.length());
00761 #endif
00762 }
00763
00764
00765
00766
00767 v2 = n2->speed * n2->direction;
00768
00769 D = v2 - v1;
00770 B = n2->position - position;
00771
00772 a = (D.X * D.X) + (D.Y * D.Y) + (D.Z * D.Z);
00773 b = 2 * ((D.X * B.X) + (D.Y * B.Y) + (D.Z * B.Z));
00774 c = (B.X * B.X) + (B.Y * B.Y) + (B.Z * B.Z) - (RANGE * RANGE);
00775
00776 if(a == 0.0) {
00777
00778
00779
00780 m1->time_transition= 0.0;
00781 m2->time_transition= 0.0;
00782 goto next;
00783 }
00784
00785 Q = b * b - 4 * a * c;
00786 if(Q < 0.0) {
00787
00788
00789
00790 m1->time_transition = 0.0;
00791 m2->time_transition = 0.0;
00792 goto next;
00793 }
00794 Q = sqrt(Q);
00795
00796 t1 = (-b + Q) / (2 * a);
00797 t2 = (-b - Q) / (2 * a);
00798
00799
00800 if(t1 > 0.0 && t1 < ROUND_ERROR) t1 = 0.0;
00801 if(t1 < 0.0 && -t1 < ROUND_ERROR) t1 = 0.0;
00802 if(t2 > 0.0 && t2 < ROUND_ERROR) t2 = 0.0;
00803 if(t2 < 0.0 && -t2 < ROUND_ERROR) t2 = 0.0;
00804
00805 if(t1 < 0.0 && t2 < 0.0) {
00806
00807
00808
00809 m1->time_transition = 0.0;
00810 m2->time_transition = 0.0;
00811 goto next;
00812 }
00813
00814
00815
00816
00817 if((t1 == 0.0 && t2 > 0.0) || (t2 == 0.0 && t1 > 0.0)) {
00818 m1->reachable = m2->reachable = 1;
00819 m1->time_transition = m2->time_transition = TIME + max(t1, t2);
00820 }
00821 else if((t1 == 0.0 && t2 < 0.0) || (t2 == 0.0 && t1 < 0.0)) {
00822 m1->reachable = m2->reachable = 0;
00823 m1->time_transition = m2->time_transition = 0.0;
00824 }
00825
00826
00827
00828
00829 else if(t1 > 0.0 && t2 > 0.0) {
00830 m1->time_transition = TIME + min(t1, t2);
00831 m2->time_transition = TIME + min(t1, t2);
00832 }
00833 else if(t1 > 0.0) {
00834 m1->time_transition = TIME + t1;
00835 m2->time_transition = TIME + t1;
00836 }
00837 else {
00838 m1->time_transition = TIME + t2;
00839 m2->time_transition = TIME + t2;
00840 }
00841
00842
00843
00844
00845 if(time_transition == 0.0 || (m1->time_transition &&
00846 time_transition > m1->time_transition)) {
00847 time_transition = m1->time_transition;
00848 }
00849 if(n2->time_transition == 0.0 || (m2->time_transition &&
00850 n2->time_transition > m2->time_transition)) {
00851 n2->time_transition = m2->time_transition;
00852 }
00853 next:
00854 if(reachable != m1->reachable && TIME > 0.0) {
00855 LinkChangeCount++;
00856 link_changes++;
00857 n2->link_changes++;
00858 }
00859 }
00860 }
00861
00862 void
00863 Node::Dump()
00864 {
00865 Neighbor *m;
00866 u_int32_t i;
00867
00868 fprintf(stdout,
00869 "Node: %d\tpos: (%.2f, %.2f, %.2f) dst: (%.2f, %.2f, %.2f)\n",
00870 index, position.X, position.Y, position.Z,
00871 destination.X, destination.Y, destination.Z);
00872 fprintf(stdout, "\tdir: (%.2f, %.2f, %.2f) speed: %.2f\n",
00873 direction.X, direction.Y, direction.Z, speed);
00874 fprintf(stdout, "\tArrival: %.2f, Update: %.2f, Transition: %.2f\n",
00875 time_arrival, time_update, time_transition);
00876
00877 for(i = 0; i < NODES; i++) {
00878 m = &neighbor[i];
00879 fprintf(stdout, "\tNeighbor: %d (%lx), Reachable: %d, Transition Time: %.2f\n",
00880 m->index, (long) m, m->reachable, m->time_transition);
00881 }
00882 }
00883
00884
00885
00886
00887
00888 void dumpall()
00889 {
00890 u_int32_t i;
00891
00892 fprintf(stdout, "\nTime: %.2f\n", TIME);
00893
00894 for(i = 0; i < NODES; i++) {
00895 NodeList[i].Dump();
00896 }
00897 }
00898
00899 void
00900 ComputeW()
00901 {
00902 u_int32_t i, j;
00903 u_int32_t *W = D2;
00904
00905 memset(W, '\xff', sizeof(int) * NODES * NODES);
00906
00907 for(i = 0; i < NODES; i++) {
00908 for(j = i; j < NODES; j++) {
00909 Neighbor *m = &NodeList[i].neighbor[j];
00910 if(i == j)
00911 W[i*NODES + j] = W[j*NODES + i] = 0;
00912 else
00913 W[i*NODES + j] = W[j*NODES + i] = m->reachable ? 1 : RTG_INFINITY;
00914 }
00915 }
00916 }
00917
00918 void
00919 floyd_warshall()
00920 {
00921 u_int32_t i, j, k;
00922
00923 ComputeW();
00924
00925 for(i = 0; i < NODES; i++) {
00926 for(j = 0; j < NODES; j++) {
00927 for(k = 0; k < NODES; k++) {
00928 D2[j*NODES + k] = min(D2[j*NODES + k], D2[j*NODES + i] + D2[i*NODES + k]);
00929 }
00930 }
00931 }
00932
00933 #ifdef SANITY_CHECKS
00934 for(i = 0; i < NODES; i++)
00935 for(j = 0; j < NODES; j++) {
00936 assert(D2[i*NODES + j] == D2[j*NODES + i]);
00937 assert(D2[i*NODES + j] <= RTG_INFINITY);
00938 }
00939 #endif
00940 }
00941
00942
00943
00944
00945
00946 void
00947 show_diffs()
00948 {
00949 u_int32_t i, j;
00950
00951 for(i = 0; i < NODES; i++) {
00952 for(j = i + 1; j < NODES; j++) {
00953 if(D1[i*NODES + j] != D2[i*NODES + j]) {
00954
00955 if(D2[i*NODES + j] == RTG_INFINITY)
00956 DestUnreachableCount++;
00957
00958 if(TIME > 0.0) {
00959 RouteChangeCount++;
00960 NodeList[i].route_changes++;
00961 NodeList[j].route_changes++;
00962 }
00963
00964 if(TIME == 0.0) {
00965 fprintf(stdout, GOD_FORMAT2,
00966 i, j, D2[i*NODES + j]);
00967 #ifdef SHOW_SYMMETRIC_PAIRS
00968 fprintf(stdout, GOD_FORMAT2,
00969 j, i, D2[j*NODES + i]);
00970 #endif
00971 }
00972 else {
00973 fprintf(stdout, GOD_FORMAT,
00974 TIME, i, j, D2[i*NODES + j]);
00975 #ifdef SHOW_SYMMETRIC_PAIRS
00976 fprintf(stdout, GOD_FORMAT,
00977 TIME, j, i, D2[j*NODES + i]);
00978 #endif
00979 }
00980 }
00981 }
00982 }
00983
00984 memcpy(D1, D2, sizeof(int) * NODES * NODES);
00985 }
00986
00987
00988 void
00989 show_routes()
00990 {
00991 u_int32_t i, j;
00992
00993 fprintf(stdout, "#\n# TIME: %.12f\n#\n", TIME);
00994 for(i = 0; i < NODES; i++) {
00995 fprintf(stdout, "# %2d) ", i);
00996 for(j = 0; j < NODES; j++)
00997 fprintf(stdout, "%3d ", D2[i*NODES + j] & 0xff);
00998 fprintf(stdout, "\n");
00999 }
01000 fprintf(stdout, "#\n");
01001 }
01002
01003 void
01004 show_counters()
01005 {
01006 u_int32_t i;
01007
01008 fprintf(stdout, "#\n# Destination Unreachables: %d\n#\n",
01009 DestUnreachableCount);
01010 fprintf(stdout, "# Route Changes: %d\n#\n", RouteChangeCount);
01011 fprintf(stdout, "# Link Changes: %d\n#\n", LinkChangeCount);
01012 fprintf(stdout, "# Node | Route Changes | Link Changes\n");
01013 for(i = 0; i < NODES; i++)
01014 fprintf(stdout, "# %4d | %4d | %4d\n",
01015 i, NodeList[i].route_changes,
01016 NodeList[i].link_changes);
01017 fprintf(stdout, "#\n");
01018 }
01019