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

在proc tcl之后引用数组和变量,tcl,ns2,Tcl,Ns2,我正在使用NS2创建一个无线传感器网络。在x-y平面上随机分布20个无线节点,通过距离计算找到邻居(广播可以到达的邻居)。从邻居开始,我从节点0开始为每个节点创建集群 例如,从节点0作为clusterhead开始,我们将得到如下输出: Cluster for Node 0 contains: 1 3 8 从此处移动到不包含在其中的下一个节点,以便: Cluster for Node 2 contains: 5 6 7 使用TCL中的列表,我在引用proc邻居中更改的集群阵列时遇到问题。我

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

例如,从节点0作为clusterhead开始,我们将得到如下输出:

Cluster for Node 0 contains: 
1
3
8
从此处移动到不包含在其中的下一个节点,以便:

Cluster for Node 2 contains: 
5
6
7
使用TCL中的列表,我在引用
proc邻居中更改的集群阵列时遇到问题。我可以将元素添加到节点0群集的列表中。但是,我只能在流程内部执行,循环会产生“重印”问题。我尝试了
globalcluster
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 && $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 AND 15
Cluster for Node 0:
0=8
1=12
2=15
如何正确引用此数组/列表?另外,我觉得我以后也需要使用
bool==1
。在简单的测试中,我也不能引用进程之外的更改


谢谢

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

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

我没有使用过ns2,但我不能说我理解您试图做什么,但是您尝试将集群索引移到进程外部的结果是有意义的,因为循环发生在调用进程之前,然后在执行进程时,就不会出现打印。我认为问题不在于如何引用集群,而在于逻辑。例如,第一个
if
可以写成
if{$dAs为什么它可能看起来是重复的,可能是一次迭代,
$d
低于40,而接下来的两次迭代,
$d
高于40,因此只有集群的打印发生,而没有打印
$nd1和$nd2
部分。我建议您使用类似于
put的“结果为$I,$j”
就在循环中的
$ns(0.0)行之前…
可以更好地指示发生了什么。@Jerry谢谢你的建议。我有
如果{$d这不能解决你的问题,但是
d
的计算应该是
集d[expr{int(hypot($x2-$x1,$y2-$y1))}
;hypot
函数(表示斜边)我没有使用过ns2,但是我不能说我理解你在尝试做什么,但是你尝试将集群索引移到进程外部的结果是有意义的,因为循环发生在调用进程之前,然后在执行进程时,没有打印可能会出现这种情况。我认为问题不在于如何引用
集群,而在于逻辑。例如,第一个
if
可以写成
if{$dAs为什么它可能看起来是重复的,可能是一次迭代,
$d
低于40,而接下来的两次迭代,
$d
高于40,因此只有集群的打印发生,而没有打印
$nd1和$nd2
部分。我建议您使用类似于
put的“结果为$I,$j”
就在循环中的
$ns(0.0)行之前…
可以更好地指示发生了什么。@Jerry谢谢你的建议。我有
如果{$d这不能解决你的问题,但是
d
的计算应该是
集d[expr{int(hypot($x2-$x1,$y2-$y1))}
;hypot
函数(对于“斜边”)被设计用于这类事情。似乎工作得很完美。一个模拟ex与您的代码…注意:tcl解释器是wish:可以删除。从不与ns2一起使用→ .... 注2:“ns”并不是真正的“说”tcl,但otcl.似乎工作得很好。一个带有代码的模拟ex…注:tcl解释器是wish:可以删除。从不与ns2一起使用→ .... 注2:“ns”并不是真正的“讲”tcl,而是otcl。
...
0 AND 15
Cluster for Node 0:
0=8
1=12
2=15
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