سؤال

أنا باستخدام أحداث منفصلة محاكاة يسمى ns-2 التي تم بناؤها باستخدام Tcl و C++.كنت أحاول كتابة بعض التعليمات البرمجية في TCL:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 2.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global state
    global ns
    $ns at-now "set state [expr $state+1]"
    puts "Changed value of state to $state"
}

$ns run

هنا هو الإخراج:

At 0.0 value of state is: 0
Changed value of state to 0
At 2.0 values of state is: 0

قيمة الدولة لا يبدو أن تغيير.أنا لست متأكدا إذا أنا أفعل شيء خاطئ في استخدام TCL.أي شخص لديه فكرة عن ما يمكن أن يحدث الخطأ هنا ؟

تحرير:شكرا للمساعدة.في الواقع, ns-2 هو شيء أكثر من الذي لم يكن لديك الكثير من السيطرة (إلا إذا كنت إعادة ترجمة محاكاة نفسه).حاولت من الاقتراحات هنا هو الإخراج:

للحصول على التعليمات البرمجية:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 9.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global ns
    set ::state [expr {$::state+1}]
    $ns at-now "puts \"At [$ns now] changed value of state to $::state\""
}

$ns run

الناتج هو:

At 0.0 value of state is: 0
At 1 changed value of state to 1
At 2.0 values of state is: 0

و للحصول على التعليمات البرمجية:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 9.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global ns
    set ::state [expr {$::state+1}]
    $ns at 1.0 {puts "At 1.0 values of state is: $::state"}
}

$ns run

الناتج هو:

At 0.0 value of state is: 0
At 1.0 values of state is: 1
At 2.0 values of state is: 0

لا يبدو أن العمل...لست متأكدا إذا كان لها مشكلة مع ns2 أو قانون بلدي...

هل كانت مفيدة؟

المحلول

تحرير:الآن فهم آلة الدولة

أولا أقتبس جملة كنت تستخدم سوف تحصل في ورطة.يجب عليك عموما بناء Tcl الأوامر باستخدام القائمة, هذا يضمن أن Tcl لن تتوسع ما كنت لا تريد توسيع.

الخاص بك at-now المكالمات استبدال state متغير عند إجراء المكالمة (أيعندما تكون القيمة دون تغيير ، 0.ما تريده هو:

$ns at-now 0.0 {puts "At 0.0 value of state is: $::state"}
$ns at-now 2.0 {puts "At 2.0 value of state is: $::state"}

يبدو أن changeVal هو مكتوب بشكل صحيح (أول إصدار كان بعض من نفس استبدال المشاكل) ، وكذلك حقيقة أن كنت تمر في متغير المراجع التي يمكن استخدامها محليا ، وبالتالي عدم وضع الدولة العالمية.

حل جزء من النسخة الأولى من السؤال - استخدام المراجع العالمية و اقتبس كل [ و $ لمنع تبديل في نقطة الاتصال:

$ns at-now "set ::state \[expr {\$::state + 1}\]"

أو باستخدام الأقواس المتعرجة:

$ns at-now {set ::state [expr {$::state + 1}]}

نصائح أخرى

المشكلة هي أنك استبدال قيمة المتغيرات الخاصة بك على الفور ، وليس في الوقت رمز تقييمها.تحتاج إلى تأجيل تبديل.وهكذا بدلا من:

$ns at 2.0 "puts \"At 2.0 values of state is: $state\""

هل هذا:

$ns at 2.0 {puts "At 2.0 values of state is: $state"}

انها ممارسة جيدة أن تضع أي شيء أكثر تعقيدا من مكالمة بسيطة من الأوامر دون تبديل في الإجراء عند القيام دعوة من هذا القبيل.أسهل بكثير لجعل هذا العمل صحيح.

[عدل]
أيضا ، at-now لا يزال تأجيل القيام جسمها حتى بعد الحالي at العوائد.

أنا لست متأكدا لماذا هذا يعمل ولكن يعمل:

set ns [new Simulator]

set state 0

proc changeVal {} {
    global ns
    incr ::state
    $ns at-now {puts "Local::At [$ns now] values of state is: $::state"}
}

$ns at 0.0 "puts \"Global::At 0.0 value of state is: $state\""
changeVal
$ns at 9.0 "puts \"Global::At 2.0 values of state is: $state\""

$ns run

الإخراج:

Global::At 0.0 value of state is: 0
Local::At 0 values of state is: 1
Global::At 2.0 values of state is: 1

إذا كان أي شخص يعرف تفسيرا ، التي من شأنها أن تكون كبيرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top