Coverage for .tox/p311/lib/python3.10/site-packages/scicom/randomletters/agents.py: 0%

74 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-16 09:50 +0200

1import mesa 

2import numpy as np 

3 

4 

5class LetterAgent(mesa.Agent): 

6 """An agent with fixed initial start position. 

7  

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. 

16 

17 Received and send letters are kept track of with two additional 

18 internal variables. 

19 """ 

20 

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 

46 

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) 

59 

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 

105 

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) 

111 

112 

113class LetterNode(mesa.Agent): 

114 """An agent representing the network node. 

115 

116 Only necessary for visualization purposes. 

117 """ 

118 

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