1 """Goals as piecewise linear reward functions
2 @author: David V. Pynadath <pynadath@ict.usc.edu>
3 """
4 from xml.dom.minidom import *
5 from teamwork.math.Keys import Key,StateKey,ActionKey
6 from teamwork.math.KeyedVector import KeyedVector
7 from teamwork.math.KeyedMatrix import ActionCountMatrix,IdentityMatrix
8 from teamwork.math.ProbabilityTree import ProbabilityTree
9 from teamwork.action.PsychActions import ActionCondition
10
12 """A reward subfunction represented as a PWL function of some vector (typically the world state)
13 @ivar dependency: set of decision trees that represent the reward subfunction over possible action triggers
14 @type dependency: list
15 @ivar keys: set of L{Key} instances that this goal depends on
16 @type keys: L{Key}[]
17 @ivar max: C{True} iff this goal represents a positive incentive; otherwise, it is a disincentive (default is C{True})
18 @type max: bool
19 """
20
22 self.max = True
23 self.dependency = []
24 self.keys = []
25
27 """
28 Adds a new dependency to this subfunction
29 @param condition: the trigger condition for this dependency
30 @type condition: L{ActionCondition}
31 @param tree: the PWL function to compute when triggered (ignored if the condition is a counting one)
32 @type tree: L{ProbabilityTree}
33 """
34 self.dependency.append((condition,tree))
35
37 if len(self.keys) == 1:
38 return self.keys[0]
39 else:
40 raise NotImplementedError,'Unable to manipulate goals over: %s' % \
41 (', '.join(map(str,self.keys)))
42
43 - def reward(self,context,actions=[]):
44 for entry in self.dependency:
45 if entry[0].count:
46
47 return self._sign(float(entry[0].match(actions)))
48 elif entry[0].match(actions):
49
50 return self._sign(entry[1][context['state']]*context['state'])
51 else:
52
53 return 0.
54
56 """Applies the appropriate sign to a goal magnitude
57 @param value: the (presumably nonnegative) magnitude of the reward
58 @type value: float
59 @return: the appropriately signed reward value
60 @rtype: float
61 """
62 if self.max:
63 return value
64 else:
65 return -value
66
73
75 return hash(str(self))
76
78 doc = Document()
79 root = doc.createElement('goal')
80 doc.appendChild(root)
81 root.setAttribute('max',str(self.max))
82 for key in self.keys:
83 root.appendChild(key.__xml__().documentElement)
84 for condition,tree in self.dependency:
85 root.appendChild(condition.__xml__().documentElement)
86 root.appendChild(tree.__xml__().documentElement)
87 return doc
88
108
128
130 """Creates a L{PWLGoal} corresponding to a minimization goal
131 @param key: the L{Key} that points to the vector element to be minimized
132 @type key: L{Key}
133 @rtype: L{PWLGoal}
134 """
135 goal = maxGoal(key)
136 goal.max = False
137 return goal
138