⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns-leach.tcl

📁 Matlab下的大名鼎鼎的Leach分簇算法实现。对网络研究的有用处
💻 TCL
📖 第 1 页 / 共 2 页
字号:
############################################################################## This code was developed as part of the MIT uAMPS project. (June, 2000)############################################################################## Message Constantsset ADV_CH         0set JOIN_REQ       1set ADV_SCH        2set DATA           3set MAC_BROADCAST  0xffffffffset LINK_BROADCAST 0xffffffffset BYTES_ID       2############################################################################## LEACH Application#############################################################################Class Application/LEACH -superclass ApplicationApplication/LEACH instproc init args {  global opt  $self instvar rng_ isch_ hasbeench_ next_change_time_ round_  $self instvar clusterChoices_ clusterDist_ clusterNodes_ currentCH_   $self instvar xmitTime_ TDMAschedule_ dist_ code_  $self instvar now_ alive_ frame_time_ end_frm_time_  $self instvar begin_idle_ begin_sleep_  $self instvar myADVnum_ receivedFrom_ dataReceived_  set rng_ [new RNG]  $rng_ seed 0  set isch_ 0  set hasbeench_ 0  set next_change_time_ 0  set round_ 0  set clusterChoices_ ""  set clusterDist_ ""  set clusterNodes_ ""  set currentCH_ ""  set xmitTime_ ""  set TDMAschedule_ ""  set dist_ 0  set code_ 0  set now_ 0  set alive_ 1  set frame_time_ $opt(frame_time)  set end_frm_time_ 0  set begin_idle_ 0  set begin_sleep_ 0  set myADVnum_ 0  set receivedFrom_ ""  set dataReceived_ ""  $self next $args}Application/LEACH instproc start {} {  [$self mac] set node_num_ [$self nodeID]  $self decideClusterHead  $self checkAlive }############################################################################## Helper Functions#############################################################################Application/LEACH instproc getRandomNumber {llim ulim} {  $self instvar rng_  return [$rng_ uniform $llim $ulim]}Application/LEACH instproc node {} {  return [[$self agent] set node_]}Application/LEACH instproc nodeID {} {  return [[$self node] id]}Application/LEACH instproc mac {} {  return [[$self node] set mac_(0)]}Application/LEACH instproc getX {} {  return [[$self node] set X_]}Application/LEACH instproc getY {} {  return [[$self node] set Y_]}Application/LEACH instproc getER {} {  set er [[$self node] getER]  return $er}Application/LEACH instproc GoToSleep {} {  global opt ns_  $self instvar begin_idle_ begin_sleep_  [[$self node] set netif_(0)] set sleep_ 1  # If node has been awake, remove idle energy (e.g., the amount of energy  # dissipated while the node is in the idle state).  Otherwise, the node  # has been asleep and must remove sleep energy (e.g., the amount of  # energy dissipated while the node is in the sleep state).  if {$begin_idle_ > $begin_sleep_} {    set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]]    [$self getER] remove $idle_energy  } else {    set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]]    [$self getER] remove $sleep_energy  }  set begin_sleep_ [$ns_ now]  set begin_idle_ 0}Application/LEACH instproc WakeUp {} {  global opt ns_  $self instvar begin_idle_ begin_sleep_  [[$self node] set netif_(0)] set sleep_ 0  # If node has been asleep, remove sleep energy (e.g., the amount of energy  # dissipated while the node is in the sleep state).  Otherwise, the node  # has been idling and must remove idle energy (e.g., the amount of  # energy dissipated while the node is in the idle state).  if {$begin_sleep_ > $begin_idle_} {    set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]]    [$self getER] remove $sleep_energy  } else {    set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]]    [$self getER] remove $idle_energy  }  set begin_idle_ [$ns_ now]  set begin_sleep_ 0}Application/LEACH instproc setCode code {  $self instvar code_  set code_ $code  [$self mac] set code_ $code}Application/LEACH instproc checkAlive {} {  global ns_ chan opt node_  $self instvar alive_ TDMAschedule_  $self instvar begin_idle_ begin_sleep_  # Check the alive status of the node.  If the node has run out of  # energy, it no longer functions in the network.  set ISalive [[[$self node] set netif_(0)] set alive_]  if {$alive_ == 1} {    if {$ISalive == 0} {      puts "Node [$self nodeID] is DEAD!!!!"      $chan removeif [[$self node] set netif_(0)]      set alive_ 0      set opt(nn_) [expr $opt(nn_) - 1]      if {$opt(rcapp) == "LEACH-C/StatClustering" && \          [$self isClusterHead?]} {        foreach element $TDMAschedule_ {          if {$element != [$self nodeID]} {            puts "Node $element is effectively DEAD!!!!"            $chan removeif [$node_($element) set netif_(0)]            [$node_($element) set netif_(0)] set alive_ 0            [$node_($element) set rca_app_] set alive_ 0            set opt(nn_) [expr $opt(nn_) - 1]          }        }      }    } else {      $ns_ at [expr [$ns_ now] + 0.1] "$self checkAlive"      if {$begin_idle_ >= $begin_sleep_} {        set idle_energy [expr $opt(Pidle) * [expr [$ns_ now] - $begin_idle_]]        [$self getER] remove $idle_energy        set begin_idle_ [$ns_ now]      } else {        set sleep_energy [expr $opt(Psleep) * [expr [$ns_ now] - $begin_sleep_]]        [$self getER] remove $sleep_energy        set begin_sleep_ [$ns_ now]      }    }  }  if {$opt(nn_) < $opt(num_clusters)} "sens_finish"}############################################################################## Cluster Head Functions#############################################################################Application/LEACH instproc isClusterHead? {} {  $self instvar isch_  return $isch_}Application/LEACH instproc hasbeenClusterHead? {} {  $self instvar hasbeench_  return $hasbeench_}Application/LEACH instproc hasnotbeenClusterHead {} {  $self instvar hasbeench_  set hasbeench_ 0}Application/LEACH instproc setClusterHead {} {  $self instvar isch_ hasbeench_  set isch_ 1  set hasbeench_ 1  return }Application/LEACH instproc unsetClusterHead {} {  $self instvar isch_  set isch_ 0  return }############################################################################## Distributed Cluster Set-up Functions#############################################################################Application/LEACH instproc decideClusterHead {} {  global chan ns_ opt node_  $self instvar next_change_time_ round_ clusterNodes_   $self instvar now_ TDMAschedule_ beginningE_ alive_  $self instvar myADVnum_ CHheard_  set CHheard_ 0  [$self mac] set CHheard_ $CHheard_  set myADVnum_ 0  [$self mac] set myADVnum_ $myADVnum_  # Check the alive status of the node.  If the node has run out of  # energy, it no longer functions in the network.  set ISalive [[[$self node] set netif_(0)] set alive_]  if {$alive_ == 1 && $ISalive == 0} {    puts "Node [$self nodeID] is DEAD!!!! Energy = [[$self getER] query]"    $chan removeif [[$self node] set netif_(0)]    set alive_ 0    set opt(nn_) [expr $opt(nn_) - 1]  }  if {$alive_ == 0} {return}  set now_ [$ns_ now]  set nodeID [$self nodeID]  set beginningE_ [[$self getER] query]  $self setCode 0  $self WakeUp   set tot_rounds [expr int([expr $opt(nn_) / $opt(num_clusters)])]  if {$round_ >= $tot_rounds} {    set round_ 0  }  if {$opt(eq_energy) == 1} {    #    # Pi(t) = k / (N - k mod(r,N/k))    # where k is the expected number of clusters per round    # N is the total number of sensor nodes in the network    # and r is the number of rounds that have already passed.    #    set nn $opt(nn_)    if {[expr $nn - $opt(num_clusters) * $round_] < 1} {      set thresh 1    } else {      set thresh [expr double($opt(num_clusters)) /  \        [expr $nn - $opt(num_clusters) * $round_]]      # Whenever round_ is 0, all nodes are eligible to be cluster-head.      if {$round_ == 0} {        $self hasnotbeenClusterHead      }    }    # If node has been cluster-head in this group of rounds, it will not    # act as a cluster-head for this round.    if {[$self hasbeenClusterHead?]} {      set thresh 0    }  } else {    #    # Pi(t) = Ei(t) / Etotal(t) * k    # where k is the expected number of clusters per round,    # Ei(t) is the node's current energy, and Etotal(t) is the total     # energy from all nodes in the network.    #    set Etotal 0    # Note!  In a real network, would need a routing protocol to get this    # information.  Alternatively, each node could estimate Etotal(t) from     # the energy of nodes in its cluster.    for {set id 0} {$id < [expr $opt(nn)-1]} {incr id} {      set app [$node_($id) set rca_app_]      set E [[$app getER] query]      set Etotal [expr $Etotal + $E]    }    set E [[$self getER] query]    set thresh [expr double([expr $E * $opt(num_clusters)]) / $Etotal]   }  puts "THRESH = $thresh"  set clusterNodes_ ""  set TDMAschedule_ ""  if {[$self getRandomNumber 0 1] < $thresh} {    puts "$nodeID: *******************************************"    puts "$nodeID: Is a cluster head at time [$ns_ now]"    $self setClusterHead    set random_access [$self getRandomNumber 0 $opt(ra_adv)]    $ns_ at [expr $now_ + $random_access] "$self advertiseClusterHead"  } else {    puts "$nodeID: *******************************************"    $self unsetClusterHead  }  incr round_   set next_change_time_ [expr $now_ + $opt(ch_change)]   $ns_ at $next_change_time_ "$self decideClusterHead"  $ns_ at [expr $now_ + $opt(ra_adv_total)] "$self findBestCluster"}Application/LEACH instproc advertiseClusterHead {} {  global ns_ opt ADV_CH MAC_BROADCAST LINK_BROADCAST BYTES_ID  $self instvar currentCH_ code_   set chID [$self nodeID]  set currentCH_ $chID  pp "Cluster Head $currentCH_ broadcasting ADV at time [$ns_ now]"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -