Exemple #1
0
def main(rl):
    """
    Runs the monitor snapshot until clock reaches or exceeds run length. Then closes monitor.

    :param rl: run length

    :return: None
    """
    monitor = specification.Monitor()
    clock = 0
    while clock < rl:
        driver = GraphDatabase.driver(specification.database_uri,
                                      auth=specification.Monitor_auth,
                                      max_connection_lifetime=20000)
        with driver.session() as session:
            # modifying and redrawing plot over time and saving plot rather than an animation
            session.write_transaction(monitor.snapshot, clock)
            tx = session.begin_transaction()
            current_time = intf.gettime(tx)
            while clock == current_time:
                current_time = intf.gettime(tx)
            clock = current_time
        driver.close()
    print("Monitor Capture complete")
    driver = GraphDatabase.driver(specification.database_uri,
                                  auth=specification.Monitor_auth,
                                  max_connection_lifetime=2000)
    with driver.session() as session:
        session.write_transaction(monitor.close)
    driver.close()
    print("Monitor closed")
def main(rl, ps):
    """
    Checks population levels meet requirements and adds additional agents if needed until clock reaches or exceeds run
    length

    :param rl: run length
    :param ps: population size

    :return: None
    """
    clock = 0
    agent = specification.Agents(None)
    while clock < rl:
        dri = GraphDatabase.driver(specification.database_uri,
                                   auth=specification.Population_auth,
                                   max_connection_lifetime=2000)
        with dri.session() as ses:
            populationdeficite = specification.Population.check(ses, ps)
            if populationdeficite:
                for i in range(populationdeficite):
                    ses.write_transaction(agent.generator,
                                          specification.Population.params)
            tx = ses.begin_transaction()
            time = intf.gettime(tx)
            while clock == time:
                time = intf.gettime(tx)
            clock = time
        dri.close()
    print("Population closed")
Exemple #3
0
    def talk(self, tx):
        """
        Determine if agent forms a new social link with random co-located agent based on their social values and
        shortest social path

        :param tx: neo4j write transaction

        :return: None
        """
        super(Patient, self).talk(tx)
        if self.colocated:
            newcontacts = [
                nc for nc in self.colocated if nc not in self.contacts
            ]
            if newcontacts:
                if len(newcontacts) > 1:
                    newfriend = npr.sample(newcontacts)
                else:
                    newfriend = newcontacts
                # Based on relative social values and length of shortest path set probability for forming link with a
                #  randomly sampled co-located unknown agent. social from 2-8 per agent, combined from 4-16. So combined -4
                #  over 24 gives value between 0 and 0.5 plus the if minimum path greater than 6 nothing, else from m=2-6
                #  then 1/(2m-2) gives 0.1-0.5 (m=1 or 0 means itself or already connected).
                prob1 = (newfriend.end_node["social"] + self.social - 4) / 24
                sp = intf.shortestpath(tx, self.id, newfriend.end_node["id"],
                                       'Agent', 'Social')
                if sp < 2:
                    prob2 = 0
                elif sp > 6:
                    prob2 = 0
                else:
                    prob2 = 1 / (2 * sp - 2)
                if npr.random(1) <= (prob1 + prob2):
                    # form friend link
                    intf.createedge(
                        self.id, newfriend.end_node["id"], 'Agent', 'Agent',
                        'SOCIAL:FRIEND', 'created: ' + intf.gettime() +
                        ', usage: ' + intf.gettime() + ', carer: False')
                    self.contacts = newfriend
                else:
                    self.contacts = None
            else:
                self.contacts = None
        else:
            self.contacts = None
Exemple #4
0
    def react(self, tx):
        """
        If the agent now has more social bonds than they can manage we drop new non carer friends then those not used
        recently and finally reduce the carers from most recent.

        :param tx: neo4j write transaction

        :return: None
        """
        super(Patient, self).react(tx)
        self.contacts = intf.agentcontacts(tx, self.id, "Agent")
        carers = self.contacts + intf.agentcontacts(tx, self.id, "Agent",
                                                    "Carer")
        if len(self.contacts) > self.social:
            while len(carers) > self.social:
                carer_drop = None
                latest_time = 0
                for carer in carers:
                    if carer["created"] > latest_time:
                        carer_drop = carer
                        latest_time = carer["created"]
                intf.deletecontact(tx, self.id, carer_drop.end_node["id"],
                                   "Agent", "Carer")
            if len(carers) == self.social:
                for contact in contacts:
                    intf.deletecontact(tx, self.id, contact.end_node["id"],
                                       "Agent", "Agent")
            if len(carers) + len(contacts) > self.social:
                for contact in contacts:
                    if len(carers) + len(contacts) > self.social:
                        if intf.gettime() - contact['created'] < 5:
                            intf.deletecontact(tx, self.id,
                                               contact.end_node["id"], "Agent",
                                               "Agent")
            oldest_usage = 0
            contact_drop = None
            while len(carers) + len(contacts) > self.social:
                for contact in contacts:
                    if intf.gettime() - contact["usage"] > oldest_usage:
                        contact_drop = contact
                        oldest_usage = intf.gettime() - contact["usage"]
                intf.deletecontact(tx, self.id, contact_drop.end_node["id"],
                                   "Agent", "Agent")
Exemple #5
0
    def listen(self, tx):
        """
        If the agent has a new social link check if the new friend has a link to a carer if they do for a random carer
        they form a link with a .5 chance.

        :param tx: neo4j write transaction

        :return: None
        """
        super(Patient, self).listen(tx)
        if self.contacts:
            carers = intf.agentcontacts(tx, self.contacts.end_node["id"],
                                        "Agent", "Carer")
            carers = [carer for carer in carers if carer["carer"]]
            carer = npr.sample(carers)
            if npr.random(1) < 0.5:
                intf.createedge(
                    self.id, carer.end_node["id"], 'Patient', 'Carer',
                    'SOCIAL:FRIEND', 'created: ' + intf.gettime() +
                    ', usage: ' + intf.gettime() + ', carer: True')
Exemple #6
0
    def generate_population(tx, ps):
        """
        Generates the required number of agents and starts them at the Home node.
        Builds social connections between agents.

        :param tx: neo4j database write transaction
        :param ps: population size

        :return: None
        """
        fa = Patient(None)
        for j in range(ps // 4):
            tx.run("CREATE (a:Carer {id:{j_id}, energy:20})", j_id=j)
        for i in range(ps):
            fa.generator(tx, [0.8, 0.9, 1, [2, 0, 1, 2], 2, 8])
            if npr.random(1) < 0.5:
                if npr.random(1) < 0.5:
                    samplesize = 2
                else:
                    samplesize = 1
                newfriends = npr.choice(range(ps // 4),
                                        size=samplesize,
                                        replace=False)
                for nf in newfriends:
                    intf.createedge(
                        tx, i, nf, 'Agent', 'Carer', 'SOCIAL',
                        'created: ' + str(intf.gettime(tx)) + ', usage: ' +
                        str(intf.gettime(tx)) + ', carer: True')
                    intf.createedge(tx, i, nf, 'Agent', 'Carer', 'FRIEND')
        for i in range(ps):
            newfriends = npr.choice(range(ps),
                                    size=npr.choice(range(3)),
                                    replace=False)
            for nf in newfriends:
                if not nf == i:
                    intf.createedge(
                        tx, i, nf, 'Agent', 'Agent', 'SOCIAL',
                        'created: ' + str(intf.gettime(tx)) + ', usage: ' +
                        str(intf.gettime(tx)) + ', carer: False')
                    intf.createedge(tx, i, nf, 'Agent', 'Agent', 'FRIEND')
def main(rl):
    """
    Implements a FlowReaction repeatedly until the clock in the database reaches the run length.

    :param rl: run length

    :return: None
    """
    flowreaction = specification.Balancer.FlowReaction()
    clock = 0
    while clock < rl:
        dri = GraphDatabase.driver(specification.database_uri,
                                   auth=specification.Balancer_auth,
                                   max_connection_lifetime=2000)
        with dri.session() as ses:
            ses.write_transaction(flowreaction.applyrules)
            tx = ses.begin_transaction()
            time = intf.gettime(tx)
            while clock == time:
                time = intf.gettime(tx)
            clock = time
        dri.close()
    print("Balancer closed")
def timesincedischarge(txl):
    """
    Utility function reports the time between any hospital discharge and attending an intervention. Only recorded if
    both events occur.

    :param txl: neo4j database write transaction

    :return: list of times in integer timesteps
    """
    times = []
    agents = intf.getnodeagents(txl, "Intervention", "name")
    for agent in agents:
        log = parselog(agent["log"])
        log.reverse()
        lasthosdis = [entry for entry in log if entry[0] == "Hos discharge"]
        if lasthosdis:
            lasthosdis = lasthosdis[0]
            times = times + [intf.gettime(txl) - lasthosdis[1]]
    return times
Exemple #9
0
    def update(self, tx):
        """
        Check agent contacts compare list with co-located agents and update co-located contacts with new last usage

        :param tx: neo4j database write transaction

        :return: None
        """
        super(Patient, self).update(tx)
        # Update existing com links with latest co-location
        self.contacts = intf.agentcontacts(tx, self.id, "Patient")
        if self.contacts and self.colocated:
            update = [
                contact for contact in self.contacts
                if contact in self.colocated
            ]
            for contact in update:
                intf.updatecontactedge(tx, contact.end_node["id"], self.id,
                                       "last_usage", intf.gettime())
Exemple #10
0
    def agentsready(self, tx):
        """
        Identifies the set of current agents for processing, either the correct set in the queue or all the agents at
        the node. It checks for unqueued agents in nodes with queue and runs the nodes prediction function to add them
        to the queue. It then gathers the agents local environment perception and passes that to the agent when calling
        the move function. We then delete the part of the queue that has been processed to save space. Subclass must
        implement this function for any aspects unique to model.

        :param tx: neo4j write transaction

        :return: None
        """
        agents = intf.getnodeagents(tx, self.name, "name")
        clock = intf.gettime(tx)
        if self.queue or self.queue == {}:
            queueagents = [
                key for time in self.queue.keys()
                for key in self.queue[time].keys()
            ]
            newagents = [ag for ag in agents if ag["id"] not in queueagents]
            # run prediction on each unqueued agent
            for ag in newagents:
                self.agentprediction(tx, ag)
        for ag in agents:
            if self.queue:
                if clock in self.queue.keys():
                    if ag["id"] in self.queue[clock].keys():
                        agper = self.agentperception(
                            tx, ag, self.queue[clock][ag["id"]][0],
                            self.queue[clock][ag["id"]])
                        specification.Agent(ag["id"]).move(tx, agper)
            else:
                agper = self.agentperception(tx, ag)
                specification.Agent(ag["id"]).move(tx, agper)
        if self.queue and clock in self.queue.keys():
            del self.queue[clock]
Exemple #11
0
    def payment(self, tx):
        """
        Modifies chosen edge and agent. These include mobility, confidence and energy modifications.

        :param tx: neo4j database write transaction

        :return: None
        """
        super(Patient, self).payment(tx)
        # Deduct energy used on edge
        if "energy" in self.choice.keys():
            if "energy" in self.choice.end_node.keys():
                if self.choice["energy"] + self.choice.end_node[
                        "energy"] > self.current_energy:
                    # Check for carers
                    carers = intf.agentcontacts(tx, self.id, "Agent", "Carer")
                    # Check for sufficient energy
                    for carer in carers:
                        print(carer)
                        if carer.end_node["energy"] >= self.choice["energy"]:
                            intf.updatenode(tx,
                                            carer.end_node["id"],
                                            "energy",
                                            carer.end_node["energy"] -
                                            self.choice["energy"],
                                            label='Carer')
                            self.current_energy = self.current_energy + self.choice[
                                "energy"]
                            intf.updateagent(tx, self.id, "energy",
                                             self.current_energy)
                            intf.updatecontactedge(tx, self.id,
                                                   carer.end_node["id"],
                                                   "usage", intf.gettime(tx),
                                                   "Agent", "Carer")
                            break
                    else:
                        return False
            self.current_energy = npr.normal(self.choice["energy"],
                                             0.05) + self.current_energy
            intf.updateagent(tx, self.id, "energy", self.current_energy)
        # mod variables based on edges
        if "modm" in self.choice:
            self.mobility = self.positive(
                npr.normal(self.choice["modm"], 0.05) + self.mobility)
            intf.updateagent(tx, self.id, "mob", self.mobility)
            if self.mobility == 0:
                if self.wellbeing != "Fallen":
                    self.wellbeing = "Fallen"
                    intf.updateagent(tx, self.id, "wellbeing", self.wellbeing)
                    clock = tx.run("MATCH (a:Clock) "
                                   "RETURN a.time").values()[0][0]
                    self.log = self.log + ", (Fallen, " + str(clock) + ")"
            elif self.mobility > 1:
                if self.wellbeing != "Healthy":
                    self.wellbeing = "Healthy"
                    intf.updateagent(tx, self.id, "wellbeing", self.wellbeing)
                    clock = tx.run("MATCH (a:Clock) "
                                   "RETURN a.time").values()[0][0]
                    self.log = self.log + ", (Healthy, " + str(clock) + ")"
            elif self.mobility <= 1:
                if self.wellbeing == "Healthy":
                    self.wellbeing = "At risk"
                    intf.updateagent(tx, self.id, "wellbeing", self.wellbeing)
                    clock = tx.run("MATCH (a:Clock) "
                                   "RETURN a.time").values()[0][0]
                    self.log = self.log + ", (At risk, " + str(clock) + ")"
        if "modmood" in self.choice:
            self.mood = self.positive(
                npr.normal(self.choice["modmood"], 0.05) + self.mood)
            intf.updateagent(tx, self.id, "mood", self.mood)
        return True