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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * a simplified version of setdest which bypass the computation of route length.
  3.  */
  4. extern "C" {
  5. #include <assert.h>
  6. #include <fcntl.h>
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/time.h>
  12. #include <sys/types.h>
  13. #include <sys/uio.h>
  14. #include <unistd.h>
  15. #if !defined(sun) && !defined(__CYGWIN__)
  16. #include <err.h>
  17. #endif
  18. };
  19. #include "../../../rng.h"
  20. #include "setdest.h"
  21. // #define DEBUG
  22. #define SANITY_CHECKS
  23. //#define SHOW_SYMMETRIC_PAIRS
  24. #define GOD_FORMAT "$ns_ at %.12f "$god_ set-dist %d %d %d"n"
  25. #define GOD_FORMAT2 "$god_ set-dist %d %d %dn"
  26. #define NODE_FORMAT "$ns_ at %.12f "$node_(%d) setdest %.12f %.12f %.12f"n"
  27. #define NODE_FORMAT2 "$node_(%d) setdest %.12f %.12f %.12fn"
  28. #define NODE_FORMAT3 "$node_(%d) set %c_ %.12fn"
  29. #define INFINITY 0x00ffffff
  30. #define min(x,y) ((x) < (y) ? (x) : (y))
  31. #define max(x,y) ((x) > (y) ? (x) : (y))
  32. #define ROUND_ERROR 1e-9
  33. static int count = 0;
  34. /* ======================================================================
  35.    Function Prototypes
  36.    ====================================================================== */
  37. void usage(char**);
  38. void init(void);
  39. double uniform(void);
  40. void dumpall(void);
  41. void ComputeW(void);
  42. void floyd_warshall(void);
  43. void show_diffs(void);
  44. void show_routes(void);
  45. void show_counters(void);
  46. /* ======================================================================
  47.    Global Variables
  48.    ====================================================================== */
  49. const double RANGE = 250.0; // transmitter range in meters
  50. double TIME = 0.0; // my clock;
  51. double MAXTIME = 0.0; // duration of simulation
  52. double MAXX = 0.0;
  53. double MAXY = 0.0;
  54. double MAXSPEED = 0.0;
  55. double PAUSE = 0.0;
  56. u_int32_t NODES = 0;
  57. u_int32_t RouteChangeCount = 0;
  58. u_int32_t       LinkChangeCount = 0;
  59. u_int32_t DestUnreachableCount = 0;
  60. Node *NodeList = 0;
  61. u_int32_t *D1 = 0;
  62. u_int32_t *D2 = 0;
  63. /* ======================================================================
  64.    Random Number Generation
  65.    ====================================================================== */
  66. #define M 2147483647L
  67. #define INVERSE_M ((double)4.656612875e-10)
  68. char random_state[32];
  69. RNG *rng;
  70. double
  71. uniform()
  72. {
  73.         count++;
  74.         return rng->uniform_double() ;
  75. /* ======================================================================
  76.    Misc Functions...
  77.    ====================================================================== */
  78. void
  79. usage(char **argv)
  80. {
  81. fprintf(stderr,
  82. "nusage: %st-n <nodes> -p <pause time> -s <max speed>n",
  83. argv[0]);
  84. fprintf(stderr,
  85. "tt-t <simulation time> -x <max X> -y <max Y>nn");
  86. }
  87. void
  88. init()
  89. {
  90. /*
  91.  * Initialized the Random Number Generation
  92.  */
  93. "
  94. /*"
  95.  * Allocate memory for globals
  96.  */
  97. NodeList = new Node[NODES];
  98. if(NodeList == 0) {
  99. perror("new");
  100. exit(1);
  101. }
  102. D1 = new u_int32_t[NODES * NODES];
  103. if(D1 == 0) {
  104. perror("new");
  105. exit(1);
  106. }
  107. memset(D1, 'xff', sizeof(u_int32_t) * NODES * NODES);
  108. D2 = new u_int32_t[NODES * NODES];
  109. if(D2 == 0) {
  110. perror("new");
  111. exit(1);
  112. }
  113. memset(D2, 'xff', sizeof(u_int32_t) * NODES * NODES);
  114. }
  115. extern "C" char *optarg;
  116. int
  117. main(int argc, char **argv)
  118. {
  119. char ch;
  120. while ((ch = getopt(argc, argv, "n:p:s:t:x:y:i:o:")) != EOF) {       
  121. switch (ch) { 
  122. case 'n':
  123. NODES = atoi(optarg);
  124. break;
  125. case 'p':
  126. PAUSE = atof(optarg);
  127. break;
  128. case 's':
  129. MAXSPEED = atof(optarg);
  130. break;
  131. case 't':
  132. MAXTIME = atof(optarg);
  133. break;
  134. case 'x':
  135. MAXX = atof(optarg);
  136. break;
  137. case 'y':
  138. MAXY = atof(optarg);
  139. break;
  140. default:
  141. usage(argv);
  142. exit(1);
  143. }
  144. }
  145. if(MAXX == 0.0 || MAXY == 0.0 || NODES == 0 || MAXTIME == 0.0) {
  146. usage(argv);
  147. exit(1);
  148. }
  149. fprintf(stdout, "#n# nodes: %d, pause: %.2f, max speed: %.2f  max x = %.2f, max y: %.2fn#n",
  150. NODES , PAUSE, MAXSPEED, MAXX, MAXY);
  151. // The more portable solution for random number generation
  152. rng = new RNG;
  153. rng->set_seed(RNG::HEURISTIC_SEED_SOURCE); 
  154. init();
  155. while(TIME <= MAXTIME) {
  156. double nexttime = 0.0;
  157. u_int32_t i;
  158. for(i = 0; i < NODES; i++) {
  159. NodeList[i].Update();
  160. }
  161. /*
  162. for(i = 0; i < NODES; i++) {
  163. NodeList[i].UpdateNeighbors();
  164. }
  165. */
  166. for(i = 0; i < NODES; i++) {
  167. Node *n = &NodeList[i];
  168. if(n->time_transition > 0.0) {
  169. if(nexttime == 0.0)
  170. nexttime = n->time_transition;
  171. else
  172. nexttime = min(nexttime, n->time_transition);
  173. }
  174. if(n->time_arrival > 0.0) {
  175. if(nexttime == 0.0)
  176. nexttime = n->time_arrival;
  177. else
  178. nexttime = min(nexttime, n->time_arrival);
  179. }
  180. }
  181. // floyd_warshall();
  182. #ifdef DEBUG
  183. show_routes();
  184. #endif
  185.   // show_diffs();
  186. #ifdef DEBUG
  187. dumpall();
  188. #endif
  189. assert(nexttime > TIME + ROUND_ERROR);
  190. TIME = nexttime;
  191. }
  192. show_counters();
  193. int of;
  194. if ((of = open(".rand_state",O_WRONLY | O_TRUNC | O_CREAT, 0777)) < 0) {
  195.   fprintf(stderr, "open rand staten");
  196.   exit(-1);
  197.   }
  198. for (unsigned int i = 0; i < sizeof(random_state); i++)
  199.           random_state[i] = 0xff & (int) (uniform() * 256);
  200. if (write(of,random_state, sizeof(random_state)) < 0) {
  201.   fprintf(stderr, "writing rand staten");
  202.   exit(-1);
  203.   }
  204. close(of);
  205. }
  206. /* ======================================================================
  207.    Node Class Functions
  208.    ====================================================================== */
  209. u_int32_t Node::NodeIndex = 0;
  210. Node::Node()
  211. {
  212. u_int32_t i;
  213. index = NodeIndex++;
  214. //if(index == 0)
  215. // return;
  216. route_changes = 0;
  217.         link_changes = 0;
  218.         /*
  219.          * For the first PAUSE seconds of the simulation, all nodes
  220.          * are stationary.
  221.          */
  222. time_arrival = TIME + PAUSE;
  223. time_update = TIME;
  224. time_transition = 0.0;
  225. position.X = position.Y = position.Z = 0.0;
  226. destination.X = destination.Y = destination.Z = 0.0;
  227. direction.X = direction.Y = direction.Z = 0.0;
  228. speed = 0.0;
  229. RandomPosition();
  230. fprintf(stdout, NODE_FORMAT3, index, 'X', position.X);
  231. fprintf(stdout, NODE_FORMAT3, index, 'Y', position.Y);
  232. fprintf(stdout, NODE_FORMAT3, index, 'Z', position.Z);
  233. neighbor = new Neighbor[NODES];
  234. if(neighbor == 0) {
  235. perror("new");
  236. exit(1);
  237. }
  238. for(i = 0; i < NODES; i++) {
  239. neighbor[i].index = i;
  240. neighbor[i].reachable = (index == i) ? 1 : 0;
  241. neighbor[i].time_transition = 0.0;
  242. }
  243. }
  244. void
  245. Node::RandomPosition()
  246. {
  247.         position.X = uniform() * MAXX;
  248.         position.Y = uniform() * MAXY;
  249. position.Z = 0.0;
  250. }
  251. void
  252. Node::RandomDestination()
  253. {
  254.         destination.X = uniform() * MAXX;
  255.         destination.Y = uniform() * MAXY;
  256. destination.Z = 0.0;
  257. assert(destination != position);
  258. }
  259. void
  260. Node::RandomSpeed()
  261. {
  262.         speed = uniform() * MAXSPEED;
  263. assert(speed != 0.0);
  264. }
  265. void
  266. Node::Update()
  267. {
  268. position += (speed * (TIME - time_update)) * direction;
  269. if(TIME == time_arrival) {
  270. vector v;
  271. if(speed == 0.0 || PAUSE == 0.0) {
  272.                         RandomDestination();
  273. RandomSpeed();
  274. v = destination - position;
  275. direction = v / v.length();
  276. time_arrival = TIME + v.length() / speed;
  277. }
  278. else {
  279. destination = position;
  280. speed = 0.0;
  281. time_arrival = TIME + PAUSE;
  282. }
  283. fprintf(stdout, NODE_FORMAT,
  284. TIME, index, destination.X, destination.Y, speed);
  285. }
  286. time_update = TIME;
  287. time_transition = 0.0;
  288. }
  289. void
  290. Node::UpdateNeighbors()
  291. {
  292. static Node *n2;
  293. static Neighbor *m1, *m2;
  294. static vector D, B, v1, v2;
  295. static double a, b, c, t1, t2, Q;
  296. static u_int32_t i, reachable;
  297. v1 = speed * direction;
  298. /*
  299.  *  Only need to go from INDEX --> N for each one since links
  300.  *  are symmetric.
  301.  */
  302. for(i = index+1; i < NODES; i++) {
  303. m1 = &neighbor[i];
  304. n2 = &NodeList[i];
  305. m2 = &n2->neighbor[index];
  306. assert(i == m1->index);
  307. assert(m1->index == n2->index);
  308. assert(index == m2->index);
  309.                 assert(m1->reachable == m2->reachable);
  310.                 reachable = m1->reachable;
  311. /* ==================================================
  312.    Determine Reachability
  313.    ================================================== */
  314. { vector d = position - n2->position;
  315. if(d.length() < RANGE) {
  316. #ifdef SANITY_CHECKS
  317. if(TIME > 0.0 && m1->reachable == 0)
  318. assert(RANGE - d.length() < ROUND_ERROR);
  319. #endif
  320. m1->reachable = m2->reachable = 1;
  321. }
  322. // Boundary condition handled below.
  323. else {
  324. #ifdef SANITY_CHECKS
  325. if(TIME > 0.0 && m1->reachable == 1)
  326. assert(d.length() - RANGE < ROUND_ERROR);
  327. #endif
  328. m1->reachable = m2->reachable = 0;
  329. }
  330. #ifdef DEBUG
  331.                         fprintf(stdout, "# %.6f (%d, %d) %.2fmn",
  332.                                 TIME, index, m1->index, d.length());
  333. #endif
  334. }
  335. /* ==================================================
  336.    Determine Next Event Time
  337.    ================================================== */
  338. v2 = n2->speed * n2->direction;
  339. D = v2 - v1;
  340. B = n2->position - position;
  341. a = (D.X * D.X) + (D.Y * D.Y) + (D.Z * D.Z);
  342. b = 2 * ((D.X * B.X) + (D.Y * B.Y) + (D.Z * B.Z));
  343. c = (B.X * B.X) + (B.Y * B.Y) + (B.Z * B.Z) - (RANGE * RANGE);
  344. if(a == 0.0) {
  345. /*
  346.  *  No Finite Solution
  347.  */
  348. m1->time_transition= 0.0;
  349. m2->time_transition= 0.0;
  350. goto  next;
  351. }
  352. Q = b * b - 4 * a * c;
  353. if(Q < 0.0) {
  354. /*
  355.  *  No real roots.
  356.  */
  357. m1->time_transition = 0.0;
  358. m2->time_transition = 0.0;
  359. goto next;
  360. }
  361. Q = sqrt(Q);
  362. t1 = (-b + Q) / (2 * a);
  363. t2 = (-b - Q) / (2 * a);
  364. // Stupid Rounding/Boundary Cases
  365. if(t1 > 0.0 && t1 < ROUND_ERROR) t1 = 0.0;
  366. if(t1 < 0.0 && -t1 < ROUND_ERROR) t1 = 0.0;
  367. if(t2 > 0.0 && t2 < ROUND_ERROR) t2 = 0.0;
  368. if(t2 < 0.0 && -t2 < ROUND_ERROR) t2 = 0.0;
  369. if(t1 < 0.0 && t2 < 0.0) {
  370. /*
  371.  *  No "future" time solution.
  372.  */
  373. m1->time_transition = 0.0;
  374. m2->time_transition = 0.0;
  375. goto next;
  376. }
  377. /*
  378.  * Boundary conditions.
  379.  */
  380. if((t1 == 0.0 && t2 > 0.0) || (t2 == 0.0 && t1 > 0.0)) {
  381. m1->reachable = m2->reachable = 1;
  382. m1->time_transition = m2->time_transition = TIME + max(t1, t2);
  383. }
  384. else if((t1 == 0.0 && t2 < 0.0) || (t2 == 0.0 && t1 < 0.0)) {
  385. m1->reachable = m2->reachable = 0;
  386. m1->time_transition = m2->time_transition = 0.0;
  387. }
  388. /*
  389.  * Non-boundary conditions.
  390.  */
  391. else if(t1 > 0.0 && t2 > 0.0) {
  392. m1->time_transition = TIME + min(t1, t2);
  393. m2->time_transition = TIME + min(t1, t2);
  394. }
  395. else if(t1 > 0.0) {
  396. m1->time_transition = TIME + t1;
  397. m2->time_transition = TIME + t1;
  398. }
  399. else {
  400. m1->time_transition = TIME + t2;
  401. m2->time_transition = TIME + t2;
  402. }
  403. /* ==================================================
  404.    Update the transition times for both NODEs.
  405.    ================================================== */
  406. if(time_transition == 0.0 || (m1->time_transition &&
  407.    time_transition > m1->time_transition)) {
  408. time_transition = m1->time_transition;
  409. }
  410. if(n2->time_transition == 0.0 || (m2->time_transition &&
  411.    n2->time_transition > m2->time_transition)) {
  412. n2->time_transition = m2->time_transition;
  413. }
  414.         next:
  415.                 if(reachable != m1->reachable && TIME > 0.0) {
  416.                         LinkChangeCount++;
  417.                         link_changes++;
  418.                         n2->link_changes++;
  419.                 }
  420. }
  421. }
  422. void
  423. Node::Dump()
  424. {
  425. Neighbor *m;
  426. u_int32_t i;
  427. fprintf(stdout,
  428. "Node: %dtpos: (%.2f, %.2f, %.2f) dst: (%.2f, %.2f, %.2f)n",
  429. index, position.X, position.Y, position.Z,
  430. destination.X, destination.Y, destination.Z);
  431. fprintf(stdout, "tdir: (%.2f, %.2f, %.2f) speed: %.2fn",
  432. direction.X, direction.Y, direction.Z, speed);
  433. fprintf(stdout, "tArrival: %.2f, Update: %.2f, Transition: %.2fn",
  434. time_arrival, time_update, time_transition);
  435. for(i = 0; i < NODES; i++) {
  436. m = &neighbor[i];
  437. fprintf(stdout, "tNeighbor: %d (%x), Reachable: %d, Transition Time: %.2fn",
  438. m->index, (int) m, m->reachable, m->time_transition);
  439. }
  440. }
  441. /* ======================================================================
  442.    Dijkstra's Shortest Path Algoritm
  443.    ====================================================================== */
  444. void dumpall()
  445. {
  446. u_int32_t i;
  447. fprintf(stdout, "nTime: %.2fn", TIME);
  448. for(i = 0; i < NODES; i++) {
  449. NodeList[i].Dump();
  450. }
  451. }
  452. void
  453. ComputeW()
  454. {
  455. u_int32_t i, j;
  456. u_int32_t *W = D2;
  457. memset(W, 'xff', sizeof(int) * NODES * NODES);
  458. for(i = 0; i < NODES; i++) {
  459. for(j = i; j < NODES; j++) {
  460. Neighbor *m = &NodeList[i].neighbor[j];
  461. if(i == j)
  462. W[i*NODES + j] = W[j*NODES + i] = 0;
  463. else
  464. W[i*NODES + j] = W[j*NODES + i] = m->reachable ? 1 : INFINITY;
  465. }
  466. }
  467. }
  468. void
  469. floyd_warshall()
  470. {
  471. u_int32_t i, j, k;
  472. ComputeW(); // the connectivity matrix
  473. for(i = 0; i < NODES; i++) {
  474. for(j = 0; j < NODES; j++) {
  475. for(k = 0; k < NODES; k++) {
  476. D2[j*NODES + k] = min(D2[j*NODES + k], D2[j*NODES + i] + D2[i*NODES + k]);
  477. }
  478. }
  479. }
  480. #ifdef SANITY_CHECKS
  481. for(i = 0; i < NODES; i++)
  482. for(j = 0; j < NODES; j++) {
  483. assert(D2[i*NODES + j] == D2[j*NODES + i]);
  484. assert(D2[i*NODES + j] <= INFINITY);
  485. }
  486. #endif
  487. }
  488. /*
  489.  *  Write the actual GOD entries to a TCL script.
  490.  */
  491. void
  492. show_diffs()
  493. {
  494. u_int32_t i, j;
  495. for(i = 0; i < NODES; i++) {
  496. for(j = i + 1; j < NODES; j++) {
  497. if(D1[i*NODES + j] != D2[i*NODES + j]) {
  498. if(D2[i*NODES + j] == INFINITY)
  499. DestUnreachableCount++;
  500.                                 if(TIME > 0.0) {
  501.                                         RouteChangeCount++;
  502.                                         NodeList[i].route_changes++;
  503.                                         NodeList[j].route_changes++;
  504.                                 }
  505. if(TIME == 0.0) {
  506. fprintf(stdout, GOD_FORMAT2,
  507. i, j, D2[i*NODES + j]);
  508. #ifdef SHOW_SYMMETRIC_PAIRS
  509. fprintf(stdout, GOD_FORMAT2,
  510. j, i, D2[j*NODES + i]);
  511. #endif
  512. }
  513. else {
  514. fprintf(stdout, GOD_FORMAT, 
  515. TIME, i, j, D2[i*NODES + j]);
  516. #ifdef SHOW_SYMMETRIC_PAIRS
  517. fprintf(stdout, GOD_FORMAT, 
  518. TIME, j, i, D2[j*NODES + i]);
  519. #endif
  520. }
  521. }
  522. }
  523. }
  524. memcpy(D1, D2, sizeof(int) * NODES * NODES);
  525. }
  526. void
  527. show_routes()
  528. {
  529. u_int32_t i, j;
  530. fprintf(stdout, "#n# TIME: %.12fn#n", TIME);
  531. for(i = 0; i < NODES; i++) {
  532. fprintf(stdout, "# %2d) ", i);
  533. for(j = 0; j < NODES; j++)
  534. fprintf(stdout, "%3d ", D2[i*NODES + j] & 0xff);
  535. fprintf(stdout, "n");
  536. }
  537. fprintf(stdout, "#n");
  538. }
  539. void
  540. show_counters()
  541. {
  542. u_int32_t i;
  543. fprintf(stdout, "#n# Destination Unreachables: %dn#n",
  544. DestUnreachableCount);
  545. fprintf(stdout, "# Route Changes: %dn#n", RouteChangeCount);
  546.         fprintf(stdout, "# Link Changes: %dn#n", LinkChangeCount);
  547.         fprintf(stdout, "# Node | Route Changes | Link Changesn");
  548. for(i = 0; i < NODES; i++)
  549. fprintf(stdout, "# %4d |          %4d |         %4dn",
  550.                         i, NodeList[i].route_changes,
  551.                         NodeList[i].link_changes);
  552. fprintf(stdout, "#n");
  553. }