не удалось сортировать список в tcl

60
10

У меня есть код в NS2, который вычисляет расстояние между двумя узлами и помещает его в список "nbr". Я хочу отсортировать этот список в порядке возрастания в соответствии с значением "d" и снова сохранить его в списке для дальнейшего использования, поскольку я использовал команду lsort но он дает мне тот же список, который не сортирован. пожалуйста помоги

код:.

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"
}
}

выход:

{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}

спросил(а) 2017-06-21T21:31:00+03:00 3 года, 4 месяца назад
1
Решение
58

Прямо сейчас вы вычисляете каждый из расстояний отдельно, но на самом деле не собираете их все в список, который можно сортировать.

Позвольте исправить это путем первого переписывания distance чтобы просто выполнить вычисления расстояния:

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]
}

Затем нам нужна другая процедура, которая будет обрабатывать всю коллекцию (во время вызова имитатора) и выполнять сортировку. Он назовет distance чтобы получить отдельную запись, поскольку мы учли эту информацию.

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}"
}
}

Затем мы организуем, чтобы вся эта процедура была вызвана в нужное время:

# We recommend building callbacks using [list], not double quotes
$ns at 5.5 [list processDistances $val(nn) 300 11]

ответил(а) 2017-06-22T11:58:00+03:00 3 года, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема