Ссылочные массивы и переменные после proc tcl - PullRequest
1 голос
/ 27 июня 2019

Я нахожусь в процессе создания беспроводной сенсорной сети с использованием NS2. 20 беспроводных узлов распределяются случайным образом по плоскости x-y, и с помощью вычисления расстояния обнаруживаются соседи (те, которых может достичь широковещательная рассылка). Из соседей я создаю кластеры для каждого узла, начиная с узла 0.

Например, начиная с узла 0 в качестве заголовка кластера, мы получим вывод наподобие:

Cluster for Node 0 contains: 
1
3
8

Оттуда перейдите к следующему узлу, НЕ содержащемуся в нем, так:

Cluster for Node 2 contains: 
5
6
7

При использовании списков в TCL у меня возникают проблемы со ссылкой на массив кластеров, измененный в proc neighbors. Я могу добавить элементы в список для кластера Node 0. Однако я могу сделать это только внутри процесса, и циклы создают проблему «перепечатки». Я пробовал разные комбинации global cluster и upvar. Как мне ссылаться на мой список кластеров ПОСЛЕ процесса?

Ниже приведен мой текущий код с проблемой вывода и перепечатки (соседи верны, я могу проверить это в симуляторе).

set cluster {}
set bool 0 

proc neighbors {n1 n2 nd1 nd2} {
    global bool cluster 
    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<40} {
        if {$nd1!=$nd2} {
            set bool 1

            if {$bool ==1} {
                puts "$nd1 AND $nd2"
                if {$nd1 == 0} {             
                    lappend cluster $nd2
                }
            }
        }
    }

    for {set i 0} {$i < [llength $::cluster]} {incr i} {
        puts "${i}=[lindex $::cluster $i]" 
    } 
}

for {set i 0} {$i < $val(nn)} {incr i} {
    for {set j 0} {$j < $val(nn)} {incr j} {
        $ns at 0.0 "neighbors $node($i) $node($j) $i $j"
    }
}

Небольшая секция Output (она повторяется для каждого комбо nd1 и nd2) - Для узла 0 идентификатор 0-7 ссылается на правильного соседа.

0 AND 19
0=2
1=4
2=5
3=6
4=10
5=13
6=15
7=19
0=2
1=4
2=5
3=6
4=10
5=13
6=15
7=19
0=2
1=4
2=5
3=6
4=10
5=13
6=15
7=19

Теперь, если я переместу индекс кластера ВНЕ ПРОЦЕССА. Я не получаю вывод со ссылкой на список кластеров.

set cluster {}
set bool 0 

proc neighbors {n1 n2 nd1 nd2} {
  global bool cluster 
  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<40 && $nd1!=$nd2} {
            puts "$nd1 AND $nd2"
            if {$nd1 == 0} {             
                lappend cluster $nd2
            }
    }
}


for {set i 0} {$i < $val(nn)} {incr i} {
    for {set j 0} {$j < $val(nn)} {incr j} {
        puts "$i, $j"
        $ns at 0.0 "neighbors $node($i) $node($j) $i $j"
    }
}

for {set i 0} {$i < [llength $::cluster]} {incr i} {
    puts "${i}=[lindex $::cluster $i]" 
}

Вывод (только для узла 0):

0, 0
0, 1
0, 2
0, 3
...
0 AND 4
0 AND 6
0 AND 8
0 AND 9
0 AND 11
0 AND 12
0 AND 15
0 AND 16
0 AND 19

Хотя я бы ожидал / хотел что-то вроде

...
0 AND 15
Cluster for Node 0:
0=8
1=12
2=15

Как правильно ссылаться на этот массив / список? Кроме того, я чувствую, что мне нужно будет использовать bool == 1 позже. В простых тестах я не могу ссылаться на то, что это изменение и вне процесса.

Спасибо

1 Ответ

0 голосов
/ 28 июня 2019

Я разобрался с решением. Я ДУМАЮ проблема заключается в том, что симулятор должен запускать весь процесс в коде, а не фактический компилятор TCL.В любом случае, добавление нового proc printCluster дает вам один выход кластера вместе с соседями.

set ::cluster {}
set bool 0 

proc neighbors {n1 n2 nd1 nd2} {
  global bool ::cluster {}
  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<40 && $nd1!=$nd2} {
            puts "$nd1 AND $nd2"
            if {$nd1 == 0} {             
                lappend ::cluster $nd2
            }
    }
    proc printCluster {} {
        puts "Node 0 Cluster:"
        for {set i 0} {$i < [llength $::cluster]} {incr i} {
            puts "[lindex $::cluster $i]"
        }
}
}


for {set i 0} {$i < $val(nn)} {incr i} {
    for {set j 0} {$j < $val(nn)} {incr j} {
        $ns at 0.0 "neighbors $node($i) $node($j) $i $j"
    }
}

$ns at 0.0 "printCluster"

Выход:

... 
Node 0 Cluster:
1
2
6
15
18
...