44
55
66class Comparator (object ):
7- def __init__ (self , compare_method = "position" ):
7+ def __init__ (self , compare_method = "position" , k = 2 ):
88 self .__method = compare_method
9- self .__k = 2
9+ self .__k = k
1010
1111 def set_compare_method (self , compare_method ):
1212 self .__method = compare_method
1313
14+ def set_k (self , k ):
15+ self .__k = k
16+
1417 def compare (self , traces_pre , traces_real ):
1518 """
1619 Compare two input traces. A trace can be a list or a state.
@@ -34,8 +37,12 @@ def compare(self, traces_pre, traces_real):
3437 distances = self .__compare_action (traces_pre , traces_real )
3538 elif self .__method == "position" :
3639 distances = self .__compare_position (traces_pre , traces_real )
40+ elif self .__method == "position_all" :
41+ distances = self .__compare_position (traces_pre , traces_real , compare_all = True )
3742 elif self .__method == "interaction" :
3843 distances = self .__compare_interaction (traces_pre , traces_real )
44+ elif self .__method == "utility" :
45+ distances = self .__compare_utility (traces_pre , traces_real )
3946 else :
4047 exit (- 1 )
4148
@@ -51,14 +58,18 @@ def __compare_action(self, traces_1, traces_2):
5158 for ID in state_2 ["cameras" ].keys ():
5259 action_r = state_2 ["cameras" ][ID ]["actions" ]
5360 action_p = state_1 ["cameras" ][ID ]["actions" ]
54- d += self .__action_deviation (action_p , action_r )
61+ d += self .__action_deviation_v2 (action_p , action_r )
5562 distances .append (float (d )/ len (state_2 ["cameras" ]))
5663 return distances
5764
58- def __compare_position (self , traces_pre , traces_real ):
65+ def __compare_position (self , traces_pre , traces_real , compare_all = False ):
5966 distances = []
60- for state_pre , state_real in zip (traces_pre , traces_real ):
61- distances .append (self .__position_deviation (state_pre , state_real ))
67+ if compare_all is False :
68+ for state_pre , state_real in zip (traces_pre , traces_real ):
69+ distances .append (self .__position_deviation (state_pre , state_real ))
70+ else :
71+ for state_pre , state_real in zip (traces_pre , traces_real ):
72+ distances .append (self .__position_deviation_all (state_pre , state_real ))
6273 return distances
6374
6475 def __compare_interaction (self , traces_1 , traces_2 ):
@@ -67,6 +78,12 @@ def __compare_interaction(self, traces_1, traces_2):
6778 distances .append (self .__interaction_deviation (state_1 ["graph" ], state_2 ["graph" ]))
6879 return distances
6980
81+ def __compare_utility (self , traces_1 , traces_2 ):
82+ distances = []
83+ for state_1 , state_2 in zip (traces_1 , traces_2 ):
84+ distances .append (self .__utility_deviation (state_1 , state_2 ))
85+ return distances
86+
7087 def __action_deviation (self , action_1 , action_2 ):
7188 if action_1 ["random" ] == 1 and action_2 ["random" ] == 1 :
7289 return 0
@@ -94,6 +111,51 @@ def __action_deviation(self, action_1, action_2):
94111 else :
95112 return 1
96113
114+
115+ def __action_deviation_v2 (self , action_1 , action_2 ):
116+ # both random movement
117+ if action_1 ["random" ] == 1 and action_2 ["random" ] == 1 :
118+ return 0
119+ # both responding to someone else (and follow)
120+ elif action_1 ["respond" ] != - 1 and action_2 ["respond" ] != - 1 :
121+ return 0
122+ # both notifying someone else
123+ elif len (action_1 ["notify" ]) != 0 and len (action_2 ["notify" ]) != 0 :
124+ return 0
125+ # both only following
126+ elif action_1 ["respond" ] == - 1 and action_2 ["respond" ] == - 1 and \
127+ len (action_1 ["notify" ]) == 0 and len (action_2 ["notify" ]) == 0 :
128+ return 0
129+ # otherwise
130+ else :
131+ return 1
132+
133+ def __position_deviation_all (self , state_p , state_r ): # p for predicted and r for real
134+ # store only the value [x,y] in the array, discarding id
135+
136+ # read all cameras
137+ cams_r_array = []
138+ cams_p_array = []
139+ for cam_id , cam in state_r ["cameras" ].items ():
140+ cams_r_array .append ([cam ["x" ], cam ["y" ]])
141+ cam_p = state_p ["cameras" ].get (cam_id )
142+ cams_p_array .append ([cam_p ["x" ], cam_p ["y" ]])
143+ cams_p_array = np .array (cams_p_array )
144+ cams_r_array = np .array (cams_r_array )
145+
146+ # get all objects
147+ objs_r = Loader .get_all_objects (state_r )
148+ objs_p = Loader .get_all_objects (state_p )
149+
150+ sorted_objs_r = sorted (objs_r .items ())
151+ objs_r_array = np .array ([item [1 ] for item in sorted_objs_r ])
152+ sorted_objs_p = sorted (objs_p .items ())
153+ objs_p_array = np .array ([item [1 ] for item in sorted_objs_p ])
154+
155+ p_array = np .concatenate ([objs_p_array , cams_p_array ])
156+ r_array = np .concatenate ([objs_r_array , cams_r_array ])
157+ return np .linalg .norm (p_array - r_array )
158+
97159 def __position_deviation (self , state_p , state_r ): # p for predicted and r for real
98160 # store only the value [x,y] in the array, discarding id
99161
@@ -141,6 +203,11 @@ def __interaction_deviation(self, graph_1: list, graph_2: list):
141203 strengths_2 = [edge ['strength' ] for edge in graph_2 ]
142204 return np .linalg .norm (np .array (strengths_1 ) - np .array (strengths_2 ))
143205
206+ def __utility_deviation (self , state_1 , state_2 ):
207+ util_1 = self .calc_k_coverage_value (self .__k , state_1 )
208+ util_2 = self .calc_k_coverage_value (self .__k , state_2 )
209+ return np .linalg .norm (np .array (util_1 ) - np .array (util_2 ))
210+
144211 def calc_k_coverage_value (self , k , state ):
145212 num_objs = Loader .get_num_objs (state )
146213 return len (self .filter_k_coverage (k , state )) / float (num_objs )
@@ -163,7 +230,3 @@ def calc_cov_for_objs(self, state):
163230 cov_objs += obj_list
164231 return dict (Counter (cov_objs ))
165232
166- def knowledge_distance (self , k , state_1 , state_2 ):
167- knowledge_1 = self .calc_k_coverage_value (k , state_1 )
168- knowledge_2 = self .calc_k_coverage_value (k , state_2 )
169- return np .linalg .norm (np .array (knowledge_1 ) - np .array (knowledge_2 ))
0 commit comments