Coverage for src/scicom/randomletters/agents.py: 0%
74 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-15 13:26 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-15 13:26 +0200
1import mesa
2import numpy as np
5class LetterAgent(mesa.Agent):
6 """An agent with fixed initial start position.
8 Each agent has a personal topic vector representing
9 the shares the agent has of topics 1 to 10 with values
10 between 0 and 1.
11 Each agent has two different ranges, moveRange for deciding
12 to move to another agents position, and letterRange to find
13 potential correspondence partners. In addition a threshold
14 value determines the necessary similarity between topic vectors
15 to send a letter or not.
17 Received and send letters are kept track of with two additional
18 internal variables.
19 """
21 def __init__(
22 self,
23 unique_id,
24 model,
25 pos,
26 topicVec,
27 updateTopic,
28 moveRange,
29 letterRange,
30 minSep,
31 threshold
32 ):
33 """Create letter with position, topic vector and parameters."""
34 super().__init__(unique_id, model)
35 self.pos = np.array(pos)
36 self.topicVec = topicVec
37 self.updateTopic = updateTopic
38 self.threshold = threshold
39 self.moveRange = moveRange
40 self.letterRange = letterRange
41 self.topicLedger = []
42 self.lettersReceived = []
43 self.numLettersReceived = 0
44 self.lettersSend = []
45 self.numLettersSend = 0
47 def move(self, neighbors):
48 """The agent can randomly move to neighboring positions."""
49 if neighbors:
50 weights = []
51 possible_steps = []
52 for n in neighbors:
53 possible_steps.append(n.pos)
54 weights.append(n.lettersReceived)
55 move = np.random.choice([0, 0, 0, 0, 0, 0, 0, 1])
56 if move == 1:
57 new_position = self.random.choice(possible_steps)
58 self.model.space.move_agent(self, new_position)
60 def sendLetter(self, neighbors):
61 """Sending a letter based on an urn model."""
62 possibleRec = []
63 senders = self.lettersReceived
64 receivers = self.lettersSend
65 possibleRec.extend(senders)
66 possibleRec.extend(receivers)
67 if neighbors:
68 neighborRec = []
69 for n in neighbors:
70 if n.numLettersReceived > 0:
71 nMult = [n.unique_id] * n.numLettersReceived
72 neighborRec.extend(nMult)
73 else:
74 neighborRec.append(n.unique_id)
75 possibleRec.extend(neighborRec)
76 if possibleRec:
77 recipientNr = np.random.choice(possibleRec)
78 recipient = self.model.schedule.agents[recipientNr]
79 topicChoices = self.topicLedger.copy()
80 topicChoices.extend(recipient.topicLedger.copy())
81 if topicChoices:
82 randix = np.random.choice(list(range(len(topicChoices))))
83 initTopic = topicChoices[randix]
84 else:
85 initTopic = self.topicVec
86 distance = np.linalg.norm(recipient.topicVec - initTopic)
87 if distance < self.threshold:
88 recipient.numLettersReceived += 1
89 recipient.lettersReceived.append(self.unique_id)
90 self.numLettersSend += 1
91 self.lettersSend.append(recipient.unique_id)
92 # Update model social network
93 self.model.G.add_edge(self.unique_id, recipient.unique_id)
94 self.model.G.nodes()[self.unique_id]['numLettersSend'] = self.numLettersSend
95 self.model.G.nodes()[recipient.unique_id]['numLettersReceived'] = recipient.numLettersReceived
96 # Update agents topic vector
97 updateTopicVec = self.topicVec + self.updateTopic * np.random.uniform(0, 1) * (recipient.topicVec - self.topicVec)
98 self.model.letterLedger.append(
99 (self.unique_id, recipient.unique_id, self.pos, recipient.pos, updateTopicVec, self.model.schedule.steps)
100 )
101 self.topicLedger.append(
102 self.topicVec
103 )
104 self.topicVec = updateTopicVec
106 def step(self):
107 neighborsMove = self.model.space.get_neighbors(self.pos, self.moveRange, False)
108 neighborsSend = self.model.space.get_neighbors(self.pos, self.letterRange, False)
109 self.sendLetter(neighborsSend)
110 self.move(neighborsMove)
113class LetterNode(mesa.Agent):
114 """An agent representing the network node.
116 Only necessary for visualization purposes.
117 """
119 def __init__(
120 self,
121 unique_id,
122 model,
123 topicVec
124 ):
125 """Create letter with position, topic vector and parameters."""
126 super().__init__(unique_id, model)
127 self.topicVec = topicVec
128 self.lettersReceived = 0
129 self.lettersSend = 0