How to split up dependent events in SimPy -


i want implement discrete-event maintenance scheduling simulation in maintenance activities must happen whenever 1 happens.

for example, if walls repainted every 5 years, , dry-lining replaced every 14 years, walls must repainted whenever dry-lining replaced , clock restarted.

yr 5:  paint walls yr 10: paint walls yr 14: replace dry-lining yr 14: paint walls yr 19: paint walls ... 

i'm not sure whether should implement each activity process refers dependent process, or if "wall maintenance" should process logic handled internally, or other way of.

the code have has each activity process dependent process stored attribute feel i'm missing correct way of doing i'm seeing events happen twice in same year.

you should start simple (and wrong) implementation better understanding of use-case , feeling how works, e.g.:

import simpy   def paint_walls(env, interval):     while true:         yield env.timeout(interval)         print('yr %2d: paint walls' % env.now)   def replace_dry_lining(env, interval):     while true:         yield env.timeout(interval)         print('yr %d: replace dry-lining' % env.now)   env = simpy.environment() env.process(paint_walls(env, interval=5)) env.process(replace_dry_lining(env, interval=14)) env.run(until=20) 

output:

yr  5: paint walls yr 10: paint walls yr 14: replace dry-lining yr 15: paint walls 

then can start extending/modifying simulation. here 2 possibilities how problem can modeled:

variant a

we keep using 2 separate processes need way exchange event "dry-lining replaced" between them, can paint wall:

import simpy   class maintenance:     paint_wall_interval = 5     replace_dry_lining_interval= 14      def __init__(self, env):         self.env = env         self.dry_lining_replaced = env.event()          self.p_paint_walls = env.process(self.paint_walls())         self.p_replace_dry_lining = env.process(self.replace_dry_lining())      def paint_walls(self):         timeout = self.paint_wall_interval         while true:             yield self.env.timeout(timeout) | self.dry_lining_replaced             print('yr %2d: paint walls' % self.env.now)      def replace_dry_lining(self):         timeout = self.replace_dry_lining_interval         while true:             yield self.env.timeout(timeout)             print('yr %2d: replace dry-lining' % self.env.now)             self.dry_lining_replaced.succeed()             self.dry_lining_replaced = self.env.event()   env = simpy.environment() m = maintenance(env) env.run(until=20) 

output:

yr  5: paint walls yr 10: paint walls yr 14: replace dry-lining yr 14: paint walls yr 19: paint walls 

variant b

we can model 1 process waits either "paint walls" or "replace dry-lining" event:

import simpy   def maintenance(env):     paint_wall_interval = 5     replace_dry_lining_interval = 14      paint_wall = env.timeout(paint_wall_interval)     replace_dry_lining = env.timeout(replace_dry_lining_interval)      while true:         results = yield paint_wall | replace_dry_lining         do_paint = paint_wall in results         do_replace = replace_dry_lining in results          if do_replace:             print('yr %2d: replace dry-lining' % env.now)             replace_dry_lining = env.timeout(replace_dry_lining_interval)          if do_paint or do_replace:             print('yr %2d: paint walls' % env.now)             paint_wall = env.timeout(paint_wall_interval)   env = simpy.environment() env.process(maintenance(env)) env.run(until=20) 

output:

yr  5: paint walls yr 10: paint walls yr 14: replace dry-lining yr 14: paint walls yr 19: paint walls 

Comments