simple epidemic simulator in swift

Here's a simple epidemic simulator in Swift using a basic model that assumes the following:

  • All individuals can interact with everyone else.
  • Each individual can be in one of three states: Susceptible, Infected, or Recovered.
  • An infected individual can infect others at a rate determined by the infectionRate property.
  • An infected individual will recover after a time determined by the recoveryTime property.
main.swift
class Person {
    enum State {
        case susceptible, infected, recovered
    }

    let infectionRate: Double
    let recoveryTime: Double

    var state: State = .susceptible
    var daysInfected = 0
    
    init(infectionRate: Double, recoveryTime: Double) {
        self.infectionRate = infectionRate
        self.recoveryTime = recoveryTime
    }
    
    func infect() {
        state = .infected
        daysInfected = 0
    }
    
    func step() {
        switch state {
        case .infected:
            daysInfected += 1
            if daysInfected >= recoveryTime {
                state = .recovered
            }
        default:
            break
        }
    }
}

class EpidemicSimulator {
    let population: [Person]
    
    init(population: [Person]) {
        self.population = population
    }
    
    func runSimulation() {
        var totalInfected = 1
        var day = 0
        
        while totalInfected > 0 {
            totalInfected = 0
            
            for person in population {
                if person.state == .infected {
                    for otherPerson in population where otherPerson !== person {
                        if otherPerson.state == .susceptible {
                            let r = Double.random(in: 0...1)
                            if r < person.infectionRate {
                                otherPerson.infect()
                                totalInfected += 1
                            }
                        }
                    }
                }
                
                person.step()
            }
            
            day += 1
            print("Day \(day): \(totalInfected) people infected.")
        }
        
        print("Epidemic contained after \(day) days.")
    }
}
1785 chars
72 lines

This simulator sets up a population of n individuals with given infectionRate and recoveryTime properties for each individual. These can be calibrated to model different epidemics. Then, we run the simulation by stepping through each day and checking whether infected individuals infect others. We stop the simulation when there are no more infected individuals. The output of the simulator is the number of people infected each day and the total number of days until the epidemic is contained.

related categories

gistlibby LogSnag