proc tcl之后的引用数组和变量

时间:2019-06-27 14:38:33

标签: tcl ns2

我正在使用NS2创建无线传感器网络。在x-y平面上随机分布20个无线节点,并使用距离计算找到邻居(广播可以到达的邻居)。从邻居开始,我为每个从节点0开始的节点创建集群。

例如,以节点0作为簇头,我们将得到类似以下的输出:

Cluster for Node 0 contains: 
1
3
8

从此处移至其中不包含的下一个节点,这样:

Cluster for Node 2 contains: 
5
6
7

在TCL中使用列表,我在引用proc neighbors中更改的群集阵列时遇到了麻烦。我可以将元素添加到节点0群集的列表中。但是,我只能在流程内部执行此操作,并且循环会产生“重印”问题。我尝试了global clusterupvar的不同组合。在此过程之后,如何引用群集列表?

下面是我当前的输出和重印问题代码(邻居是正确的,我能够在模拟器中进行验证)。

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

输出的小部分(对于每个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。在简单的测试中,我也无法在proc之外引用它的更改。

谢谢

1 个答案:

答案 0 :(得分:0)

我想出了解决方案。 I THINK 的问题在于,模拟器必须在代码中运行所有进程,而不是实际的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