-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtranscendenceAgent.py
More file actions
93 lines (82 loc) · 3.19 KB
/
transcendenceAgent.py
File metadata and controls
93 lines (82 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import random
import numpy as np
from ethicalAgent import ethicalAgent
from miscFunctions import *
class transcendenceAgent(ethicalAgent):
def __init__(self, attrs={}):
'''
default values
'''
super().__init__("Transcendence", attrs)
if('gamma' in attrs):
self.gamma = attrs['gamma']
else:
self.gamma = 0.5
if('updateEvery' in attrs):
self.updateEvery = attrs['updateEvery']
else:
self.updateEvery = 50
if('delta' in attrs):
self.delta = attrs['delta']
else:
self.delta = 0.01
if('learningRate' in attrs):
self.learningRate = attrs['learningRate']
else:
self.learningRate = 0.07
self.virtualUtility = {}
self.distance = {}
self.firstIter = True
def initNeig(self, neigs):
super().initNeig(neigs)
for nei in neigs:
self.virtualUtility[nei] = 0
if(self.firstIter):
for nei in neigs:
self.distance[nei] = 1
self.firstIter = False
def __updateDistances(self):
sources = list(self.msgForwardedOf.keys())
inters = list(self.msgForwardedBy.keys())
costVec = []
rewardVec = []
# for nei in neighs:
# asSource = self.msgSentTo[nei]-
costVec = [self.msgForwardedOf[source]*self.msgCost for source in sources]
rewardVec = [self.msgForwardedBy[neig]*self.msgUtility+self.virtualUtility[neig] for neig in inters]
normCost = softmax(costVec)
normReward = softmax(rewardVec)
for itr, nei in enumerate(inters):
deltaDist = normReward[itr]-normCost[itr]
if(self.distance[nei]-(self.learningRate*deltaDist)<=0):
self.distance[nei] = 0
else:
self.distance[nei] = self.distance[nei] - (self.learningRate*deltaDist)
def forwardMessage(self, source, dest):
# self.msgRecvFrom[source] += 1
cost = self.delta*(self.getNodeCost()-self.getNodeUtility())+self.msgCost
d = self.distance[source]
forwardUtility = (-cost+np.power(self.gamma, d)*self.msgUtility)/(1+np.power(self.gamma, d))
dropUtility = (-np.power(self.gamma, d)*self.msgUtility)/(1+np.power(self.gamma, d))
forwardProb = softmax([forwardUtility, dropUtility])[0]
if(random.random() < forwardProb): #Forward message
self.msgSentInter[dest] += 1
self.msgForwardedOf[source] += 1
self.virtualUtility[source] += np.power(self.gamma, d)*self.msgUtility
return True
else:
self.virtualUtility[source] -= np.power(self.gamma, d)*self.msgUtility
return False
def epochUpdate(self):
self.__updateDistances()
return
def getDistances(self):
return self.distance
def isStable(self, previousState):
curDist = list(self.distance.values())
prevDist = list(previousState.getDistances().values())
for i in range(len(curDist)):
delta = curDist[i] - prevDist[i]
if np.absolute(delta) > 49e-3:
return 0
return 1