generator.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. from pypdevs.DEVS import AtomicDEVS
  2. from job import Job
  3. import random
  4. # Define the state of the generator as a structured object
  5. class GeneratorState:
  6. def __init__(self, gen_num):
  7. # Current simulation time (statistics)
  8. self.current_time = 0.0
  9. # Remaining time until generation of new event
  10. self.remaining = 0.0
  11. # Counter on how many events to generate still
  12. self.to_generate = gen_num
  13. class Generator(AtomicDEVS):
  14. def __init__(self, gen_param, size_param, gen_num):
  15. AtomicDEVS.__init__(self, "Generator")
  16. # Output port for the event
  17. self.out_event = self.addOutPort("out_event")
  18. # Define the state
  19. self.state = GeneratorState(gen_num)
  20. # Parameters defining the generator's behaviour
  21. self.gen_param = gen_param
  22. self.size_param = size_param
  23. def intTransition(self):
  24. # Update simulation time
  25. self.state.current_time += self.timeAdvance()
  26. # Update number of generated events
  27. self.state.to_generate -= 1
  28. if self.state.to_generate == 0:
  29. # Already generated enough events, so stop
  30. self.state.remaining = float('inf')
  31. else:
  32. # Still have to generate events, so sample for new duration
  33. self.state.remaining = random.expovariate(self.gen_param)
  34. return self.state
  35. def timeAdvance(self):
  36. # Return remaining time; infinity when generated enough
  37. return self.state.remaining
  38. def outputFnc(self):
  39. # Determine size of the event to generate
  40. size = max(1, int(random.gauss(self.size_param, 5)))
  41. # Calculate current time (note the addition!)
  42. creation = self.state.current_time + self.state.remaining
  43. # Output the new event on the output port
  44. return {self.out_event: Job(size, creation)}