Welcome, guest | Sign In | My Account | Store | Cart
import random

HIGH_ACTIVITY_RATE = 0.10
HIGH_ACTIVITY_INITIAL_INFECTION = 0.5
CONDOM_FAILURE_RATE = 0.01

class Player(object):
    def __init__(self, id, activity, use_condom=False):
        self.id = id
        self.activity = activity
        self.use_condom = use_condom
        self.infected = False
        self.history = []
        self.conversion_day = None
        
class LowActivityPlayer(Player):
    def __init__(self, id, activity, use_condom):
        Player.__init__(self, id, activity, use_condom)
        self.infected = False
        
class HighActivityPlayer(Player):
    def __init__(self, id, activity, use_condom, infected):
        Player.__init__(self, id, activity, False)
        self.infected = infected

class Manager():
    def __init__(self, low_activity, high_activity, transmission, players_count, days, use_condom):
        self.low_activity = low_activity
        self.high_activity = high_activity
        self.transmission = transmission
        self.players_count = players_count
        self.days = days
        self.use_condom = use_condom
        random.seed()
        self.pool = {}
        self.hookup_queue = []
        
        for id in range(self.players_count):
            if id < self.players_count * HIGH_ACTIVITY_RATE:
                infected = False
                if id < self.players_count * HIGH_ACTIVITY_RATE * HIGH_ACTIVITY_INITIAL_INFECTION:
                    infected = True
                player = HighActivityPlayer(id, self.high_activity, use_condom, infected)
            else:
                player = LowActivityPlayer(id, self.low_activity, use_condom)
            self.pool[id] = player
                
    def run(self):
        for day in range(self.days):
            self.hookup_queue = []
            for player in self.pool.values():
                if random.random() < player.activity:
                    self.hookup_queue.append(player)
            
            while self.hookup_queue:
                player_1 = player_2 = None
                player_1 = random.choice(self.hookup_queue)
                self.hookup_queue.remove(player_1)
                if self.hookup_queue:
                    player_2 = random.choice(self.hookup_queue)
                    self.hookup_queue.remove(player_2)
                if player_1 and player_2:
                    self.expose(player_1, player_2, day)
        return self
            
    def expose(self, player_1, player_2, day):
        transmission = self.transmission
        player_1.history.append(day)
        player_2.history.append(day)
        if player_1.infected or player_2.infected:
            if player_1.use_condom or player_2.use_condom:
                transmission *= CONDOM_FAILURE_RATE
            infection = (random.random() < transmission)
            if infection:
                if not player_1.infected:
                    player_1.infected = True
                    player_1.conversion_day = day
                if not player_2.infected:
                    player_2.infected = True
                    player_2.conversion_day = day

def trial(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom):                    
    new_infections = 0.0
    new_low_infections = 0.0
    new_high_infections = 0.0
    contacts = 0.0
    low_contacts = 0.0
    high_contacts = 0.0
    
    for i in range(max_runs):
        mgr = Manager(low_activity, high_activity, transmission, players_count, days, use_condom).run()
        for player in mgr.pool.values():
            if isinstance(player, LowActivityPlayer):
                if player.conversion_day:
                    new_low_infections += 1
                low_contacts += len(player.history)
            elif isinstance(player, HighActivityPlayer):
                if player.conversion_day:
                    new_high_infections += 1
                high_contacts += len(player.history)
            else:
                raise Exception("trial: invalid player %d", player.id)
            contacts += len(player.history)
    
    new_infections = new_low_infections + new_high_infections
    avg_new_infections = new_infections/max_runs
    avg_new_low_infections = new_low_infections/max_runs
    avg_new_high_infections = new_high_infections/max_runs
    
    avg_contacts = contacts/max_runs
    avg_low_contacts = low_contacts/max_runs
    avg_high_contacts = high_contacts/max_runs
    risk_per_contact = avg_new_infections / avg_contacts
    
    print "\t%-15.2f%-15.2f%-15.2f%-15.2f%-15.1f%-15.2f%-15.5f" %(low_activity, high_activity, \
            avg_new_low_infections, avg_new_high_infections, avg_contacts, avg_new_infections, risk_per_contact)


def print_heading():
    print "\t%-15s%-15s%-15s%-15s%-15s%-15s%-15s" %\
    ("Low_Activity", "High_Activity", "Low_Infects", "High_Infects", "Contacts", "New_Infects", "Risk" )
    
def test_landsburg(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom):
    print "\t%s" % ("Landsburg: increase activity of low-activity players")
    print
    print_heading()
    for i in range(6):
        trial(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
        low_activity += 0.01
    print
    print
                        
def test_landsburg_condom(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom):
    print "\t%s" % ("Landsburg w/ condoms: increase activity of low-activity players, use condoms")
    print
    print_heading()
    for i in range(6):
        trial(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
        low_activity += 0.01
    print
    print
                        
def test_kremer(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom):
    print "\t%s" % ("Kremer: increase activity of low-activity players, decrease activity of high-activity players")
    print
    print_heading()
    for i in range(6):
        trial(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
        low_activity += 0.01
        high_activity -= 0.01
    print
    print
                        
def test_commonsense(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom):
    print "\t%s" % ("Commonsense: decrease activity of high-activity players")
    print
    print_heading()
    for i in range(6):
        trial(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
        high_activity -= 0.01
    print
    print
                        
def main():
    max_runs = 100
    low_activity = 0.01
    high_activity = 0.1
    transmission = 0.01
    players_count = 1000
    days = 1000
    use_condom = False
    test_landsburg(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
    test_landsburg_condom(max_runs, low_activity, high_activity, transmission, players_count, days, True)
    test_kremer(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)
    test_commonsense(max_runs, low_activity, high_activity, transmission, players_count, days, use_condom)

if __name__ == "__main__":
    main()

History