class RoundedPareto: def __init__(self, xi): self.dist = Distribution(scipy.stats.pareto(1/xi)) def rvs(self, size=1): return [math.floor(pareto) for pareto in self.dist.rvs(size)]
class MixedPoisson: def __init__(self, xi): self.distpareto = Distribution(scipy.stats.pareto(1/xi)) self.poisson = scipy.stats.poisson def rvs(self, size=1): pareto_sample = self.distpareto.rvs(size) return [self.poisson.rvs(pareto, loc=1) for pareto in pareto_sample]
class Simulation: def __init__(self, p, network): self.p = p self.network = network self.network_dicts = nx.convert.to_dict_of_dicts( self.network) #convert to dictionaryform self.N = len(set(self.network_dicts.keys())) self.distr = Distribution(stats.bernoulli(self.p)) print("transmission-probability: {}, populationsize: {}".format( self.p, self.N)) def simulate(self, verbose=False, makeGIF=False): simres = SimulationResults(self.network) susceptible = set(self.network_dicts.keys()) infected = set() recovered = set() first_infect = random.sample(susceptible, 1)[0] susceptible.remove(first_infect) infected.add(first_infect) t = 0 while len(infected) > 0: assert len(susceptible) + len(infected) + len( recovered) == self.N, "incorrect populationsize" simres.registerState(susceptible, infected, recovered, drawGIF=makeGIF) #new infects new_infects = set() for person in infected: for friend in self.network_dicts[person].keys(): if friend in susceptible: if self.distr.rvs(): new_infects.add(friend) #move infected to susceptible recovered = recovered.union(infected) susceptible = susceptible.difference(new_infects) infected = new_infects t += 1 if verbose: print("not-infected: {}, recovered: {}, timesteps: {}".format( len(susceptible), len(recovered), t)) simres.plotStates() simres.registerFinalAffected(recovered) return simres
class Simulation: def __init__(self, s, m, h): #init simulations self.mainArrDist = Distribution(stats.expon(scale=1/m)) self.sideArrDist = Distribution(stats.expon(scale=1/s)) self.s = s self.m = m self.h = h def simulate(self, T, verbose=False, immediate_departure=False): #start simulation untill time reaches T fes = FES() simres = SimulationResults(self.s, self.m, self.h, T) queue = deque() t = 0 prev_gap_time = 0 #schedule first arrival c0 = Car(self.sideArrDist.rvs()) fes.add(Event(c0.arrTime, Event.ARRIVAL, car=c0)) #schedule first gap fes.add( Event(self.mainArrDist.rvs(), Event.GAP)) simres.registerQueue(t, len(queue)) while t < T: if verbose: print(fes.getTypesList(), fes.events) #next event e = fes.next() if e.type == Event.GAP: t = e.time #register the transitionprobability if there is no immediate_departure if not immediate_departure: simres.registerQueue(t, len(queue)) #depart the right amount of cars from the queue duration = e.time - prev_gap_time prev_gap_time = e.time departures = int(duration // self.h) for _ in range(departures): #a car leaves the queue, we save their waitingtime if len(queue) != 0: c = queue.popleft() #register the transitionprobability if there is immediate_departure if immediate_departure: simres.registerQueue(t, len(queue)) # schedule next gap fes.add( Event(t+self.mainArrDist.rvs(), Event.GAP) ) if e.type == Event.ARRIVAL: #add car to the queue t = e.time queue.append(e.car) #schedule next car c1 = Car(t + self.sideArrDist.rvs()) fes.add(Event(c1.arrTime,Event.ARRIVAL, car=c1)) simres.registerQueue(t, len(queue)) return simres