Parcourir la source

Add a direction variation score

Yann Weber il y a 6 ans
Parent
révision
538906994e
2 fichiers modifiés avec 69 ajouts et 12 suppressions
  1. 24
    8
      gte/__main__.py
  2. 45
    4
      gte/world.py

+ 24
- 8
gte/__main__.py Voir le fichier

@@ -154,9 +154,21 @@ if 'pool_size' in args:
154 154
             scores = [(max(scores[i]), progs[i]) for i in range(len(progs))]
155 155
         else:
156 156
             scores = [0 for _ in range(len(progs))]
157
-            for pid, score in res:
157
+            sinfos = [dict() for _ in range(len(progs))]
158
+            for pid, score, sinfo in res:
158 159
                 scores[pid] += score
159
-            scores = [(scores[i] / args.repeat_eval, progs[i])
160
+                # sum all score infos
161
+                for k, s in sinfo.items():
162
+                    if k not in sinfos[pid]:
163
+                        sinfos[pid][k] = 0
164
+                    sinfos[pid][k] += s
165
+            # avg all infos
166
+            for i in range(len(sinfos)):
167
+                sinfo = sinfos[i]
168
+                for k in sinfo:
169
+                    sinfo[k] /= args.repeat_eval
170
+                scores[i] /= args.repeat_eval
171
+            scores = [(scores[i], progs[i], sinfos[i])
160 172
                       for i in range(len(progs))]
161 173
 
162 174
         genstop = time.time()
@@ -167,20 +179,24 @@ if 'pool_size' in args:
167 179
             scores = sorted(scores, key=lambda x: x[0], reverse=True)
168 180
         else:
169 181
             scores = sorted(scores, key=lambda x: abs(x[0] - args.target),)
170
-        for i, (score, prog) in enumerate(scores):
171
-            logger.info('P%d %.3f : "%s"' % (i, score, str(prog)))
182
+        for i, (score, prog, sinfo) in enumerate(scores):
183
+            logger.info('P%d %.3f:(D:%.3f,F:%.3f) : "%s"' % (i, score,
184
+                                                             sinfo['D'],
185
+                                                             sinfo['F'],
186
+                                                             str(prog)))
172 187
         if args.log_progs is not None:
173 188
             with open(args.log_progs, 'a') as logprogs:
174
-                for i, (score, prog) in enumerate(scores):
175
-                    msg = 'Gen #%d P%d %.3f : "%s"\n'
176
-                    logprogs.write(msg % (generation, i, score, str(prog)))
189
+                for i, (score, prog, sinfo) in enumerate(scores):
190
+                    msg = 'Gen #%d P%d %.3f(D:%.3f,F:%.3f): "%s"\n'
191
+                    logprogs.write(msg % (generation, i, score, sinfo['D'],
192
+                                          sinfo['F'], str(prog)))
177 193
                     logprogs.flush()
178 194
                 logprogs.write('\n')
179 195
 
180 196
         # Split pool & mutate the one we kept
181 197
         keep_div = args.pool_div
182 198
         progs = []
183
-        for prog in [ prog for _, prog in scores[:len(scores)//keep_div]]:
199
+        for prog in [ prog for _, prog, _ in scores[:len(scores)//keep_div]]:
184 200
             progs.append(prog)
185 201
             for cur_mut in range(keep_div - 1):
186 202
                 if args.exp_mutate:

+ 45
- 4
gte/world.py Voir le fichier

@@ -32,14 +32,19 @@ def eval_prog(args):
32 32
             turmit()
33 33
     stop = time.time()
34 34
 
35
-    score = w.fractdim()
35
+    score_dir = sum([t.dirvar() for t in turmits]) / len(turmits)
36
+    score_fract = w.fractdim()
37
+    score = score_dir * score_fract
38
+    sinfo = {'F':score_fract, 'D':score_dir}
39
+    #score = sum([score_fract] + [score_dir] * 4) / 5
36 40
     if not args.quiet:
37
-        msg = 'G%d P%d run#%d %d steps scores %.3f in %.2fs (%dus per step)\t%s'
38
-        msg %= (generation, progid, trynum, steps, score, stop - start,
41
+        msg = 'G%d P%d run#%d %d steps scores %.3f:(D:%.3f,F:%.3f) in %.2fs (%dus per step)\t%s'
42
+        msg %= (generation, progid, trynum, steps, score, score_dir,
43
+                score_fract, stop - start,
39 44
                 ((stop - start)*1000000)//steps//len(turmits),
40 45
                 str(prog))
41 46
         logger.info(msg)
42
-    return progid, score
47
+    return progid, score, sinfo
43 48
 
44 49
 class World(object):
45 50
     ''' @brief A Turmit world. An array of dim == 2 with tuple(R,G,B) '''
@@ -192,6 +197,15 @@ class LivingTurmit(Turmit):
192 197
                 raise ValueError('Invalid Y position %d' % y)
193 198
             self._y = y
194 199
 
200
+        # Direction variation addon
201
+        self._absx = self._absy = 0
202
+        self._prev_abs = (0, 0)
203
+        self._dirvar = 0
204
+        self._prev_dirvar = None
205
+        self._dirvar_res = 50
206
+        self._steps = 1
207
+        
208
+
195 209
     def __call__(self):
196 210
         ''' @brief Exec a turmit and move it '''
197 211
         if self._world._gray:
@@ -201,6 +215,29 @@ class LivingTurmit(Turmit):
201 215
         tdir = super().__call__(x=self._x, y=self._y, r=r, g=g, b=b)
202 216
         self.move(tdir)
203 217
 
218
+        # direction variation handling
219
+        if self._steps % self._dirvar_res == 0:
220
+            dy = self._absy - self._prev_abs[0]
221
+            dx = self._absx - self._prev_abs[1]
222
+            self._prev_abs = (self._absy, self._absx)
223
+            if self._prev_dirvar is not None:
224
+                pdvar = self._prev_dirvar
225
+                self._dirvar += abs(pdvar[0] - dy) + abs(pdvar[1] - dx)
226
+            self._prev_dirvar = (dy, dx)
227
+            
228
+        self._steps += 1
229
+
230
+    def dirvar(self):
231
+        ''' @brief Process @ref _dirvar to return a direction variation
232
+            score
233
+            @return a score in [0..2]
234
+        '''
235
+        return self._dirvar / (self._steps * 2)
236
+        #d = self._dirvar
237
+        #return sum([sum([abs(d[i][j] - d[i+1][j]) for j in (0,1)])
238
+        #                 for i in range(len(d)-1)]) / (self._steps * 2)
239
+
240
+
204 241
     def move(self, tdir, setcol=True):
205 242
         ''' @brief Update coordinates given a direction
206 243
             @param tdir int : One of 8 directions (integer is understanded
@@ -215,17 +252,21 @@ class LivingTurmit(Turmit):
215 252
         tdir %= 8 if self._diag else 4
216 253
 
217 254
         if tdir == 0 or tdir == 4 or tdir == 5:
255
+            self._absx += 1
218 256
             self._x += 1
219 257
             self._x %= self._world.width
220 258
         elif tdir == 2 or tdir == 7 or tdir == 6:
259
+            self._absx -= 1
221 260
             if self._x == 0:
222 261
                 self._x = self._world.width -1
223 262
             else:
224 263
                 self._x -= 1
225 264
         if tdir == 1 or tdir == 4 or tdir == 6:
265
+            self._absy += 1
226 266
             self._y += 1
227 267
             self._y %= self._world.height
228 268
         elif tdir == 3 or tdir == 7 or tdir == 5:
269
+            self._absy -= 1
229 270
             if self._y == 0:
230 271
                 self._y = self._world.height - 1
231 272
             else:

Loading…
Annuler
Enregistrer