我是ns2的新手。在下面的代码中
for {set i 0 }{$i < $val(nn)}{incr i }
{
set n$i [$ns node]
$n$i set X_[expr 10+round(rand()*40)]
}
我想创建50个节点,但是在执行tcl文件时,它会在执行“ $ n $ i set X_ [expr 10 + round(rand()* 40)]”时将错误显示为“无效的命令名” $ n0”。提供nn为50。
您发布的代码有两类问题。
for {set i 0 }{$i < $val(nn)}{incr i }
{
这是行不通的,因为您需要在参数之间添加空格for
(是的,for
在Tcl中不是关键字;它只是常规命令),并且必须将主体的开头放在行尾。你是强烈建议使用一个真正的布雷斯风格编码; 这就是Tcl的语法最简单的方法。
解决方法如下:
for {set i 0} {$i < $val(nn)} {incr i} {
请注意,我为解决此问题所做的所有工作都是在空格中移动(并插入)。
set n$i [$ns node]
$n$i set X_[expr 10+round(rand()*40)]
这些行的问题在于您尝试使用双重替换。好吧。这种$
处理确实是愚蠢的,因为它随后会检查一个非空的“ nice”变量名,如果有的话将其替换,$
否则变成一个普通的旧变量。这意味着这$n$i
是您从$n
和得到的东西的串联$i
。
最简单的解决方法是也使用另一个变量:
set thisnode [$ns node]
set n$i $thisnode
$thisnode set X_[expr 10+round(rand()*40)]
您甚至可以将前两行合并为一,因为的结果set
是刚刚设置的值:
set n$i [set thisnode [$ns node]]
$thisnode set X_[expr 10+round(rand()*40)]
但是我们真的应该鼓励您将数组用于这种事情,因为它们确实允许对某种数组进行双重替换。
set n($i) [$ns node]
$n($i) set X_[expr 10+round(rand()*40)]
这些额外的(
……)
产生了很大的不同!
您还可以使用列表来存储生成的项目:
lappend n [$ns node]
[lindex $n end] set X_[expr 10+round(rand()*40)]
但是在这种情况下,我真的很想使用辅助变量:
lappend n [set thisnode [$ns node]]
$thisnode set X_[expr 10+round(rand()*40)]
您还应该将表情放在花括号中。不要紧,在这种特殊情况下因为它没有得到它的任何换人,但它是一个非常好的习惯进入,因为它使得它更容易对Tcl编译一般的表达; 也就是说,当整个表达式是文字时,Tcl可以提前编译它,而且速度很快,而当表达式非文字时,它直到最后一刻才可以编译,而每次循环都要编译一次,并且还可能带来其他许多危害。如果您要遍历数百万个事物而不是50个事物,那将带来更大的不同。
为了清楚起见,可能值得将该表达式分解为一个小程序:
proc random {from to} {
expr {$from + round(rand() * ($to-$from))}
}
$n($i) set X_[random 10 50]
编写一次(并调试它!),然后在其他地方重用。这是懒惰的程序员的方式。
我猜这也确实是一个NS2问题。在这种情况下,你可能会遇到问题依然:在之间的下划线X
和[expr …]
是有点令人惊讶,除非你真的用了大量非常相似的变量,你想读(然后丢弃的值)对象随机选择其中之一。那将是……相当令人惊讶,是吗?我怀疑您可能会更好:
for {set i 0} {$i < $val(nn)} {incr i} {
set n($i) [$ns node]
$n($i) set X [expr {10+round(rand()*40)}]
}
您是否需要保留参考文献?如果没有,您甚至可以:
for {set i 0} {$i < $val(nn)} {incr i} {
[$ns node] set X [expr {10+round(rand()*40)}]
}
但这可能不是您想要的;在真实代码中,您将要引用其他位置的节点,以便可以在它们之间建立链接…
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句