Reputation: 47
I have below code in NS2 which calculates distance between two nodes and put it in a list "nbr". I want to sort out that list in ascending order as per value "d" and again store it in a list for further use for that I used lsort
command but it is giving me same list that is unsorted.
please help
code:.
proc distance { n1 n2 nd1 nd2} {
set x1 [expr int([$n1 set X_])]
set y1 [expr int([$n1 set Y_])]
set x2 [expr int([$n2 set X_])]
set y2 [expr int([$n2 set Y_])]
set d [expr int(sqrt(pow(($x2-$x1),2)+pow(($y2-$y1),2)))]
if {$d<300} {
if {$nd2!=$nd1 && $nd2 == 11} {
set nbr "{$nd1 $nd2 $x1 $y1 $d}"
set m [lsort -increasing -index 4 $nbr]
puts $m
}
}
}
for {set i 1} {$i < $val(nn)} {incr i} {
for {set j 1} {$j < $val(nn)} {incr j} {
$ns at 5.5 "distance $node_($i) $node_($j) $i $j"
}
}
output:
{1 11 305 455 273}
{4 11 308 386 208}
{5 11 378 426 274}
{7 11 403 377 249}
{8 11 244 405 215}
{9 11 256 343 154}
{10 11 342 328 172}
{12 11 319 192 81}
{13 11 395 196 157}
{14 11 469 191 231}
{15 11 443 140 211}
{16 11 363 115 145}
{17 11 290 135 75}
{18 11 234 121 69}
{19 11 263 60 132}
{20 11 347 60 169}
Upvotes: 1
Views: 479
Reputation: 137577
Right now, you're calculating each of the distances separately, but aren't actually collecting them all into a list that can be sorted.
Let's fix this by first rewriting distance
to just do the distance calculations themselves:
proc distance {n1 n2 nd1 nd2} {
set x1 [expr int([$n1 set X_])]
set y1 [expr int([$n1 set Y_])]
set x2 [expr int([$n2 set X_])]
set y2 [expr int([$n2 set Y_])]
set d [expr int(sqrt(pow(($x2-$x1),2)+pow(($y2-$y1),2)))]
# Why not: set d [expr hypot($x2-$x1,$y2-$y1)]
# I'm keeping *everything* we know at this point
return [list $nd1 $nd2 $n1 $n2 $d $x1 $y1 $x2 $y2]
}
Then, we need another procedure that will process the whole collection (at the time the simulator calls it) and do the sorting. It will call distance
to get the individual record, since we've factored that information out.
proc processDistances {count threshold {filter ""}} {
global node_
set distances {}
for {set i 1} {$i < $count} {incr i} {
for {set j 1} {$j < $count} {incr j} {
# Skip self comparisons
if {$i == $j} continue
# Apply target filter
if {$filter ne "" && $j != $filter} continue
# Get the distance information
set thisDistance [distance $node_($i) $node_($j) $i $j]
# Check that the nodes are close enough
if {[lindex $thisDistance 4] < $threshold} {
lappend distances $thisDistance
}
}
}
# Sort the pairs, by distances
set distances [lsort -real -increasing -index 4 $distances]
# Print the sorted list
foreach tuple $distances {
puts "{$tuple}"
}
}
Then we arrange for that whole procedure to be called at the right time:
# We recommend building callbacks using [list], not double quotes
$ns at 5.5 [list processDistances $val(nn) 300 11]
Upvotes: 1