topo-gen.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:19k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # Created May 98 by Ahmed Helmy; updated June 98
  2. # topology generator class
  3. Class TG proc usage { } { puts stderr {usage: topology [options] where options are given as: -key value example options: -outfile mytopo -type random -nodes 50 -method pure-random "topology -h" help } return # exit 1 } proc detailed-usage { } { puts {usage: topology [-<key 1> <value 1> -<key 2> <value 2> -<key n> <value n>] example options:  -generator itm -outfile myfile -type random -nodes 20 -connection_prob 0.6  keys and corresponding values: -generator   possible value: itm (default) [the georgia tech topology generator]   [note: you need to invoke itm and sgb2ns, e.g. by setting your path] -outfile [the output file that will contain the ns script describing the   generated topology. This must be given.] -type   possible values: random (default), transit_stub -seed   possible values: integer (default = random [uses ns-random])
  4. -nodes [the number of nodes in the topology; used with `-type random']   possible values: integer (default = 50 with random, 100 with    transit-stub) -scale [used by itm to place nodes in topologies] (default = nodes) -method [the node connection/linking method; used with `-type random']   possible values: waxman1, waxman2, pure-random, doar-leslie, exponential,                     and  locality (default = pure-random) -connection_prob [the connection probability between nodes; used in         all methods] [this sometimes is called `alpha']   possible values: 0.0 <= connection_prob <= 1.0 (default = 0.5) -beta [used only with waxman1, waxman2, doar-leslie and locality]   possible values: 0.0 <= beta (default = 0.5) -gamma [used only with doar-leslie and locality]   possible values: 0.0 <= gamma (default = 0.5)   } } proc itm-random-help { } { puts {Comment from ITM, on edge connection methods:    1. Edge is placed between two nodes by a probabilistic method, which       is determined by the "method" parameter.  Edge is placed with       probability p, where p is calculated by one of the methods below,       using:         alpha, beta, gamma: input parameters,         L is scale * sqrt(2.0): the max distance between two points,         d: the Euclidean distance between two nodes.         e: a random number uniformly distributed in [0,L]         Method 1: (Waxman's RG2, with alpha,beta)            p = alpha * exp(-e/L*beta)       Method 2: (Waxmans's RG1, with alpha,beta)            p = alpha * exp(-d/L*beta)       Method 3: (Pure random graph)            p = alpha       Method 4: ("EXP" - another distance varying function)            p = alpha * exp(-d/(L-d))       Method 5: (Doar-Leslie, with alpha,beta, gamma)            p = (gamma/n) * alpha * exp(-d/(L*beta))       Method 6: (Locality with two regions)            p = alpha     if d <= L*gamma,            p = beta      if d > L*gamma      2. Constraints         0.0 <=  alpha  <= 1.0  [alpha is a probability]         0.0 <= beta            [beta is nonnegative]         0.0 <= gamma           [gamma is nonnegative]         n <  scale*scale       [enough room for nodes]   } } proc itm-transit-stub-help { } { puts {Parameters for transit_stub topology by itm: -stubs_per_transit [number of stubs per transit node] (default = 3) -ts_extra_edges [number of extra transit-stub edges] (default = 0) -ss_extra_edges [number of extra stub-stub edges] (default = 0)  -transit_domains [number of transit domains] (default = 1) -domains_scale [top level scale used by ITM] (default = 20) * Connectivity of domains [similar to the random topology parameters] -domains_method (default = pure-random) -domains_connection_prob (default = 1.0) [fully connected] -domains_beta (default = 0.5) -domains_gamma (default = 0.5)
  5. * Connectivity of transit nodes:
  6. -transit_nodes (default = 4)
  7. -transit_scale (default = 20)
  8. -transit_method (default = pure-random)
  9. -transit_connection_prob (default = 0.6)
  10. -transit_beta (default = 0.5)
  11. -transit_gamma (default = 0.5)
  12. * Connectivity of stub nodes:
  13. -stub_nodes (default = 8)
  14. -stub_method (default = pure-random)
  15. -stub_connection_prob (default = 0.4)
  16. -stub_beta (default = 0.5)
  17. -stub_gamma (default = 0.5)
  18. * Total number of nodes is computed as follows:      
  19.  nodes=transit_domains * transit_nodes * (1 + stubs_per_transit * stub_nodes)
  20.  for example, for the above default settings we get:
  21.         1 * 4 ( 1 + 3 * 8 ) = 100 nodes
  22.   }
  23. }
  24. proc help-on-help { } {
  25. puts {Help available for random, transit stub, and edge connection method.
  26. Help usage "topology -h <i>" 
  27. where: 
  28. <i> = 1 for random, 2 for transit stub, and 3 for edge connection method.
  29.   }
  30. }
  31. proc help { x } {
  32. switch $x {
  33. 1 { detailed-usage }
  34. 2 { itm-transit-stub-help }
  35. 3 { itm-random-help }
  36. default { puts "invalid help option"; help-on-help } 
  37. }
  38. }
  39. proc topology { args } {
  40. set len [llength $args]
  41. if $len {
  42.     set key [lindex $args 0]
  43.             if {$key == "-?" || $key == "--help" || $key == "-help" 
  44. || $key == "-h" } {
  45. if { [set arg2 [lindex $args 1]] == "" } {
  46. usage
  47. help-on-help
  48. } else {
  49.                          help $arg2
  50. }
  51. return
  52.                 }
  53. }
  54.         if [expr $len % 2] {
  55.                 # if number is odd => error !
  56.                 puts "fewer number of arguments than needed in "$args""
  57.                 usage
  58. return
  59.         }
  60.         # default topology generator
  61.         set generator itm
  62.         if { $args != "" && [lindex $args 0] == "-generator" } {
  63. set generator [lindex $args 1]
  64. set args [lreplace $args 0 1]
  65. }
  66. # check if the generator type exists
  67. if [catch {set tg [TG/$generator info instances]}] {
  68. puts "unknown generator type $generator"
  69. usage
  70. return
  71. }
  72. if { $tg == "" } {
  73. set tg [new TG/$generator]
  74. }
  75. if ![llength $args] {
  76. $tg create
  77. } else {
  78. $tg create $args
  79. }
  80. ScenGen setTG $tg
  81. }
  82. Class TG/itm -superclass TG
  83. TG/itm instproc init { } {
  84. $self next
  85. }
  86. TG/itm instproc default_options { } {
  87. # default set may not be complete for now.. !XXX
  88. $self instvar opt_info
  89. set opt_info {
  90. # init file to -1, must be supplied by input
  91. outfile -1
  92. # number of graphs and seed
  93. # flat random
  94. type random
  95. # number should not be changed by input... should be left 
  96. # as 1, and a tcl loop may create multiple graphs... left it as 
  97. # place holder in case this may change later.. !
  98. number 1
  99. # seed is randomized later if not entered as input
  100. seed -1
  101. nodes 50
  102. # if not entered assign to nodes later 
  103. scale -1 
  104. method pure-random
  105. connection_prob 0.5
  106. beta 0.5
  107. gamma 0.5
  108. # defaults for transit stub
  109. # total number of nodes is:
  110. # transit_domains * transit_nodes * (1 + stubs_per_transit * stub_nodes)
  111. # 1 * 4 ( 1 + 3 * 8 ) = 100 nodes
  112. stubs_per_transit 3
  113. ts_extra_edges 0
  114. ss_extra_edges 0
  115. transit_domains 1
  116. domains_scale 20
  117. domains_method pure-random
  118. domains_connection_prob 1.0
  119. domains_beta 0.5
  120. domains_gamma 0.5
  121. transit_nodes 4
  122. transit_scale 20
  123. transit_method pure-random
  124. transit_connection_prob 0.6
  125. transit_beta 0.5
  126. transit_gamma 0.5
  127. stub_nodes 8
  128. # the stub scale is ignored by ITM, is computed as fraction
  129. # of the transit scale... see proc comment below !
  130. stub_scale 10
  131. stub_method pure-random
  132. stub_connection_prob 0.4
  133. stub_beta 0.5
  134. stub_gamma 0.5
  135. # for N level hierarchy
  136. # assume all levels use same vars
  137. levels 3
  138. level_nodes 10
  139. level_scale 10
  140. level_method waxman1
  141. level_connection_prob 0.7
  142. level_beta 0.2
  143. level_gamma 0.5
  144. }
  145. $self parse_opts
  146. }
  147. TG instproc parse_opts { } {
  148. $self instvar opts opt_info
  149. while { $opt_info != ""} {
  150. # parse line by line
  151.                 if {![regexp "^[^n]*n" $opt_info line]} {
  152.                         break  
  153.                 }
  154. # remove the parsed line
  155.                 regsub "^[^n]*n" $opt_info {} opt_info
  156. # remove leading spaces and tabs using trim
  157.                 set line [string trim $line]
  158. # skip comment lines beginning with #
  159.                 if {[regexp "^[ t]*#" $line]} {
  160.                         continue
  161.                 }
  162. # skip empty lines
  163.                 if {$line == ""} {
  164.                         continue
  165.                 } elseif [regexp {^([^ ]+)[ ]+([^ ]+)$} $line dummy key value] {
  166.                         set opts($key) $value
  167.                 } 
  168. }
  169. }
  170. TG instproc parse_input { args } {
  171. # remove the list brackets from the args list
  172.         set args [lindex $args 0]
  173.         set len [llength $args]
  174. $self instvar opts
  175. for { set i 0 } { $i < $len } { incr i } {
  176. set key [lindex $args $i]
  177. regsub {^-} $key {} key
  178.                 if {![info exists opts($key)]} {
  179. puts stderr "unrecognized option $key"
  180. usage
  181. return -1
  182. }
  183. incr i
  184. # puts "changing $key from $opts($key) to [lindex $args $i]"
  185. set opts($key) [lindex $args $i]
  186. }
  187. # puts "end of parsing... "
  188. return 0
  189. }
  190. TG instproc create { args } {
  191.         # remove the list brackets from the args list
  192.         set args [lindex $args 0]
  193.         set len [llength $args]
  194.         # puts "calling create with args $args, len $len"
  195. $self default_options
  196. if $len {
  197. if { [$self parse_input $args] == -1 } {
  198. return 
  199. }
  200. }
  201. # check that the filename is provided
  202. $self instvar opts
  203. if { $opts(outfile) == -1 } {
  204. puts {you must provide the outfile name !!.. use "topology -h" for help}
  205. return
  206. }
  207. $self create-topology
  208. }
  209. # XXX to be extended to include stubs... and other topo info
  210. TG instproc setNodes { type num } {
  211. $self instvar nodes
  212. set nodes($type) $num # puts "nodes($type) = $nodes($type)" # now we stor nodes(all) x
  213. # should be able to store nodes(stub1) x1-x2
  214. # keep track of the num of stubs... etc
  215. }
  216. TG instproc getNodes { type } {
  217. $self instvar nodes
  218. if { ![info exists nodes($type)]} { puts "error: $type doesnot exist! Check srcstub/deststub arguments" exit } return $nodes($type)
  219. } TG/itm instproc create-topology { } {
  220. $self instvar opts
  221. # initialize the seed if not given
  222. if { $opts(seed) == -1 } { set opts(seed) [ns-random]
  223. } puts "type $opts(type), seed $opts(seed)"
  224. switch $opts(type) {
  225.   "random" {
  226. # compose the filename
  227. set i 0
  228. while { 1 } {
  229. # avoid clashing with prev files, incr i
  230. set topo_filename rand-$opts(nodes)-$i
  231. if ![file exists $topo_filename] {
  232. break
  233. }
  234. incr i
  235. }
  236. set topo_file [open $topo_filename w]
  237.                 # write to a file in GA tech format  
  238.                 # for now generate 1 graph,... 
  239. # check the scale, if not give, assign # of nodes
  240. if { $opts(scale) == -1 } {
  241. set opts(scale) $opts(nodes)
  242. }
  243. $self setNodes all $opts(nodes)
  244. puts "nodes $opts(nodes), scale $opts(scale), 
  245.      method $opts(method)"
  246. puts "conn prob $opts(connection_prob), beta 
  247.      $opts(beta), gamma $opts(gamma)"
  248.                 puts $topo_file "geo $opts(number) $opts(seed)"
  249. set str [$self rand-line $opts(nodes) $opts(scale) 
  250.   $opts(method) $opts(connection_prob) $opts(beta) 
  251.   $opts(gamma)]
  252. puts $topo_file $str
  253.   }
  254.   "transit_stub" {
  255. # filename
  256.                 set i 0
  257.                 while { 1 } {
  258.                         # avoid clashing with prev files, incr i
  259. set topo_filename ts-$opts(transit_domains)-$opts(transit_nodes)-$i
  260.                         if ![file exists $topo_filename] {
  261.                                 break
  262.                         }
  263.                         incr i   
  264.                 }
  265.                 set topo_file [open $topo_filename w]  
  266.               
  267. # debugging stuff !!!
  268. puts "stubs per transit $opts(stubs_per_transit), 
  269.  ts extra $opts(ts_extra_edges), ss extra $opts(ss_extra_edges)"
  270. puts "transit domains $opts(transit_domains), 
  271.  domains_scale $opts(domains_scale), domains_method 
  272.  $opts(domains_method)"
  273. puts "domains_conn $opts(domains_connection_prob), 
  274. beta $opts(domains_beta), gamma $opts(domains_gamma)"
  275. puts "transit_nodes $opts(transit_nodes), 
  276.   transit_scale $opts(transit_scale), 
  277.   transit_method $opts(transit_method)"
  278. puts "transit prob $opts(transit_connection_prob) 
  279.   transit_beta $opts(transit_beta), 
  280.   transit_gamma $opts(transit_gamma)"
  281. puts "stub_nodes $opts(stub_nodes), 
  282.   stub_method $opts(stub_method), 
  283.   stub_conn $opts(stub_connection_prob) 
  284.   stub_beta $opts(stub_beta) 
  285.   stub_gamma $opts(stub_gamma)"
  286. set total_nodes [expr $opts(transit_domains) * 
  287.   $opts(transit_nodes) * [expr 1 + $opts(stubs_per_transit) 
  288.   * $opts(stub_nodes)]]
  289. puts "Total nodes = $total_nodesn"
  290. #check if number of nodes specified is diff from # the total nodes after computation. if {$opts(nodes) != $total_nodes} { puts "n ERROR: Nodes specified = $opts(nodes)                        nActual number of total nodes = $total_nodes nFor transit_stub type, specify value of "transit_domains", "transit_nodes", "stubs_per_transit" and "stub_nodes" to change the number of nodes in your topologyn" exit 1 } $self setNodes all $total_nodes
  291. puts $topo_file "ts $opts(number) $opts(seed)"
  292. puts $topo_file "$opts(stubs_per_transit) 
  293. $opts(ts_extra_edges) $opts(ss_extra_edges)"
  294. set str [$self rand-line $opts(transit_domains) 
  295.   $opts(domains_scale) $opts(domains_method) 
  296.   $opts(domains_connection_prob) $opts(domains_beta) 
  297.   $opts(domains_gamma)]
  298. puts $topo_file $str
  299. set str [$self rand-line $opts(transit_nodes) 
  300.   $opts(transit_scale) $opts(transit_method) 
  301.   $opts(transit_connection_prob) $opts(transit_beta) 
  302.   $opts(transit_gamma)]
  303. puts $topo_file $str
  304. set str [$self rand-line $opts(stub_nodes) 
  305.   $opts(stub_scale) $opts(stub_method) 
  306.   $opts(stub_connection_prob) $opts(stub_beta) 
  307.   $opts(stub_gamma)]
  308. puts $topo_file $str
  309.   }
  310.   default { 
  311.    puts "invalid type "$opts(type)"!! use "topology -h" for help"
  312.    return
  313.   }
  314. }
  315. flush $topo_file
  316. close $topo_file
  317.         $self generate-topo-gatech $topo_filename
  318. # cleanup if you want.. uncomment the next line !
  319. # exec rm $topo_filename
  320. # call the converter 'number' times
  321. # no need for this loop if number is always 1 .. XXX
  322. for { set i 0 } { $i < $opts(number) } { incr i } {
  323.          # output file is appended by -i.gb 
  324.          $self convert-to-ns $topo_filename-$i.gb $opts(outfile) $opts(type) }
  325. # clean up... not sure if the file is needed by hierarchical addressing
  326. # exec rm $topo_filename-0.gb
  327. }
  328. TG/itm instproc rand-line { nodes scale method conn_prob beta gamma } {
  329. lappend str $nodes $scale
  330. switch $method {
  331.                 "waxman1" {
  332.                   # need alpha and beta
  333.                   lappend str 1 $conn_prob $beta
  334.                 }
  335.                 "waxman2" {
  336.                   lappend str 2 $conn_prob $beta
  337.                 }
  338.                 "pure-random" {
  339.                   # needs only alpha
  340.                   lappend str 3 $conn_prob
  341.                 }
  342.                 "doar-leslie" {
  343.                   # alpha, beta and gamma... X seems to use only alpha !
  344.                   lappend str 4 $conn_prob $beta $gamma
  345.                 } 
  346.                 "exponential" {
  347.                    # alpha .. XXX doesn't work now !!
  348.                   lappend str 5 $conn_prob
  349. }
  350.                 "locality" {
  351.    # alpha , beta and gamma
  352.    lappend str 6 $conn_prob $beta $gamma
  353. }
  354.                 default {
  355.                         puts "unidentified method $method .. aborting !!"
  356. usage
  357.                         return
  358.                 }
  359. }
  360. # puts "str $str"
  361. return $str
  362. }
  363. TG/itm instproc generate-topo-gatech { fn } {         exec itm $fn }                    
  364. TG/itm instproc convert-to-ns { fn outfile type} {
  365. # to avoid generating false errors if sgb2ns is careless
  366. # about its return/exit value # # topofile generated by sgb2hierns program; has topology info used by # topogen and agentgen # So If type permits, read in topofile and cleanup. # if {$type == "transit_stub"} { set topofile $outfile.topoinfo catch { exec sgb2hierns $fn $outfile $topofile } $self getTopoInfo $topofile #exec rm $topofile return }  catch { exec sgb2ns $fn $outfile} } # # Read in topology info from topo.$outfile # TG/itm instproc getTopoInfo topofile { set input [open $topofile r] foreach line [split [read $input] n] { set stream [split $line] switch [lindex $stream 0] { "transits" {$self getLine $stream "transit"} "total-stubs" {$self setNodes "total-stubs" [lindex $stream 1]} "stubs" {$self getLine $line "stub"} "nodes/stub" {$self getLine $line "nodes/stub"} } } close $input } # # Read each line and store away topoinfo # TG/itm instproc getLine {line type} { $self instvar nodes for {set i 1} {$i < [llength $line]} {incr i} { if {$type == "nodes/stub"} { set start $nodes(stub$i) set range [lindex $line $i] # puts "start=$start range=$range" $self setNodes stub$i $start:[expr $start + $range - 1] } else { $self setNodes $type$i [lindex $line $i] } } } proc comment { } {
  367. puts {
  368.  * itm.c -- Driver to create graphs using geo(), geo_hier(), and transtub().
  369.  *
  370.  * Each argument is a file containing ONE set of specs for graph generation.
  371.  * Such a file has the following format:
  372.  *    <method keyword> <number of graphs> [<initial seed>]
  373.  *    <method-dependent parameter lines>
  374.  * Supported method names are "geo", "hier", and "ts".
  375.  * Method-dependent parameter lines are described by the following:
  376.  *    <geo_parms> ::=
  377.  *        <n> <scale> <edgeprobmethod> <alpha> [<beta>] [<gamma>]
  378.  *    <"geo" parms> ::= <geo_parms>
  379.  *    <"hier" parms> ::=
  380.  *          <number of levels> <edgeconnmethod> <threshold>
  381.  *          <geo_parms>+  {one per number of levels}
  382.  *    <"ts" parms> ::=
  383.  *          <# stubs/trans node> <#t-s edges> <#s-s edges>
  384.  *          <geo_parms>       {top-level parameters}
  385.  *          <geo_parms>       {transit domain parameters}
  386.  *          <geo_parms>       {stub domain parameters}
  387.  *
  388.  * Note that the stub domain "scale" parameter is ignored; a fraction
  389.  * of the transit scale range is used.  This fraction is STUB_OFF_FACTOR,
  390.  * defined in ts.c.
  391.  *
  392.  * From the foregoing, it follows that best results will be obtained with
  393.  *   -- a SMALL value for top-level scale parameter
  394.  *   -- a LARGE value for transit-level scale parameter
  395.  * and then the value of stub-level scale parameter won't matter.
  396.  *
  397.  * The indicated number of graphs is produced using the given parameters.
  398.  * If the initial seed is present, it is used; otherwise, DFLTSEED is used.
  399.  *
  400.  * OUTPUT FILE NAMING CONVENTION:
  401.  * The i'th graph created with the parameters from file "arg" is placed
  402.  * in file "arg-i.gb", where the first value of i is zero.
  403.  }
  404. }
  405. ###############################################################
  406. ### the scenario generator keeps track of topology generator ##
  407. ### and can be queried to get this info      ##
  408. ###############################################################
  409. Class ScenGen
  410. ScenGen set TG ""
  411. ScenGen proc setTG { tg } {
  412. ScenGen set TG $tg
  413. }
  414. ScenGen proc getTG { } {
  415. return [ScenGen set TG]
  416. }