ns-leach.tcl 分析2

在start中调用下面这个方法。

Application/LEACH instproc decideClusterHead {} {

  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]

  set ISalive [[[$self node] set netif_(0)] set alive_] #从网络接口netif中查看当前节点状 况

如果节点存活,但是节点能量耗光,则$chan removeif [[$self node] set netif_(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] 
  }

上面是对thresh的计算,当(N - k mod(r,N/k))<1,则将thresh设置为1,否则节点thresh=k / (N - k mod(r,N/k)),

每个节点在一个1/p中都要成为簇头节点一次。p=簇头节点占所有节点的比例,在r=0的时候每个节点都有机会吃呢更为簇头节点。如果节点成为过簇头节点则thresh=0,则这个节点在1/p轮后才可以成为簇头节点。

  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)]     #opt(ra_adv) in leach.tcl
    
    $ns_ at [expr $now_ + $random_access] "$self advertiseClusterHead"
  } else {
    puts "$nodeID: *******************************************"
    $self unsetClusterHead
  }

如果thresh>getRandomNumber,则节点成为簇头节点。然后调用advertiseClusterHead方法。

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"

当节点成为簇头节点,则节点调用  advertiseClusterHead方法。


  set chID [$self nodeID]
  set currentCH_ $chID
  pp "Cluster Head $currentCH_ broadcasting ADV at time [$ns_ now]"
  set mac_dst $MAC_BROADCAST
  set link_dst $LINK_BROADCAST
  set msg [list $currentCH_]
  set datasize [expr $BYTES_ID * [llength $msg]]


  # Send beacons opt(max_dist) meters so all nodes can hear.
  $self send $mac_dst $link_dst $ADV_CH $msg $datasize $opt(max_dist) $code_

将该节点设置为簇头节点,设置当前节点所处的簇号。然后发送数据,广播该节点为簇头信息到全局网络。

$ns_ at [expr $now_ + $opt(ra_adv_total)] "$self findBestCluster"调用findBestCluster方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值