# AlohaC.py, form of slotted ALOHA

# here we will look finite time, finding the expected number of
# active nodes at epoch 8

# we'll run the simulation for many values of the backoff parameter b,
# to investigate the role b plays

import random, sys 

class node:  # one object of this class models one network node
   s = 4  # number of nodes
   b = None  # backoff parameter; refrain from sending with probability b
   q = 0.2  # msg creation probability
   activeset = []  # which nodes are active now
   inactiveset = []  # which nodes are inactive now
   r = random.Random(98765)  
   def __init__(self):  
      node.inactiveset.append(self)
   def checkgoactive():  # generate nodes which change to active
      for n in node.inactiveset:
         if node.r.uniform(0,1) < node.q:
            node.inactiveset.remove(n)
            node.activeset.append(n)
   checkgoactive = staticmethod(checkgoactive)  
   def trysend():  # the active nodes try to send, or not
      numnodestried = 0  
      whotriedlast = None  
      for n in node.activeset:
         if node.r.uniform(0,1) < node.b1:
            whotriedlast = n
            numnodestried += 1
      if numnodestried == 1:
         node.activeset.remove(whotriedlast)
         node.inactiveset.append(whotriedlast)
   trysend = staticmethod(trysend)  
   def reset():  
      for n in node.activeset:
         node.activeset.remove(n)
         node.inactiveset.append(n)
   reset = staticmethod(reset)  
            
def main():
   for i in range(node.s): node()
   bavg = []  # list of (b,avg) pairs
   nb = 100
   for i in range(nb):  # run for gridd of b values
      node.b = float(i)/nb
      node.b1 = 1 - node.b
      sum = 0  # running total of active nodes at time 8
      for rep in range(1000):  # for fixed b, simulate 1000 times
         for epoch in range(8):  # simulate for 8 units of time
            node.checkgoactive()
            node.trysend()
         sum += len(node.activeset) 
         node.reset()
      bavg.append((node.b,sum/1000.0))
   for x,y in bavg:
      print x,y  # redirect this output to a file

if __name__ == '__main__': main()
