Browse Source

Add options, enhance output + bugfixes

Yann Weber 6 years ago
parent
commit
a77bfd2e6c
3 changed files with 56 additions and 22 deletions
  1. 47
    15
      gte/__main__.py
  2. 7
    5
      gte/world.py
  3. 2
    2
      tests/test_rpnexpr.py

+ 47
- 15
gte/__main__.py View File

@@ -1,8 +1,10 @@
1
+import sys
1 2
 import os
2 3
 import os.path
3 4
 import argparse
4 5
 import logging
5 6
 import time
7
+import datetime
6 8
 import numpy as np
7 9
 from random import randint
8 10
 from multiprocessing import Pool
@@ -51,6 +53,15 @@ parser_evolve.add_argument('--threads', type=int, metavar='N',
51 53
 parser_evolve.add_argument('--max-generation', '-G', type=int, metavar='N',
52 54
                            default=0)
53 55
 
56
+parser_evolve.add_argument('--log-progs', '-L', type=str, metavar='FILENAME',
57
+                           default=None)
58
+
59
+parser_evolve.add_argument('--quiet', '-q', action='store_const',
60
+                           default=False, const=True)
61
+
62
+parser_evolve.add_argument('--pool-div', '-D', type=int, metavar='N',
63
+                           default=2, help='Each generation keep 1/N of the pool')
64
+
54 65
 parser_gen = subparsers.add_parser('generate', help='evolving help')
55 66
 
56 67
 parser_gen.add_argument('--prog', '-P', type=str, default=None)
@@ -71,31 +82,37 @@ if 'pool_size' in args:
71 82
     # Evolver
72 83
     if args.prog is None:
73 84
         progs = [rpnlib.RpnExpr.random(args.prog_size)
74
-                 for _ in range(args.pool_size)]
85
+                for _ in range(args.pool_size)]
75 86
     else:
76
-        progs = [rpnlib.RpnExpr.from_string(args.prog)]
77
-        progs = [mutate(progs[0], force=True) for _ in range(args.pool_size-1)]
87
+        prog = rpnlib.RpnExpr.from_string(args.prog)
88
+        progs = [mutate(prog, force=True) for _ in range(args.pool_size-1)]
78 89
 
79 90
     generation = 0
80 91
 
81 92
     pool = Pool(args.threads)
82 93
 
94
+    if args.log_progs is not None:
95
+        logprogs = open(args.log_progs, 'a')
96
+        logprogs.write('%s Run args %s\n' % (datetime.datetime.now(),
97
+                                             args))
98
+        logprogs.close()
99
+    else:
100
+        logger.warning('No log specified (--log-progs or -L)')
101
+
83 102
     while True:
84 103
         if args.max_generation > 0 and generation >= args.max_generation:
85 104
             exit(0)
86 105
         scores = []
87
-        for i, prog in enumerate(progs):
88
-            logger.info('Gen#%d P%d: %s' % (generation, i, str(prog)))
89
-        genstart = time.time()
90 106
         msg = 'Gen#%d Running %d eval with %d turmits and %d steps for each %d progs'
91 107
         logger.info(msg % (generation, args.repeat_eval, args.turmit_count,
92 108
                            args.steps, args.pool_size))
109
+        genstart = time.time()
93 110
 
94 111
         works = []
95 112
         for pid, prog in enumerate(progs):
96 113
             for i in range(args.repeat_eval):
97 114
                 works.append((pid, prog, i, args))
98
-        res = pool.map(eval_prog, works)
115
+        res = pool.imap(eval_prog, works)
99 116
         scores = [0 for _ in range(len(progs))]
100 117
         for pid, score in res:
101 118
             scores[pid] += score
@@ -107,17 +124,27 @@ if 'pool_size' in args:
107 124
 
108 125
         scores = sorted(scores, key=lambda x: x[0], reverse=True)
109 126
         for i, (score, prog) in enumerate(scores):
110
-            logger.debug('P%d %.3f : %s' % (i, score, str(prog)))
111
-
112
-        for score, prog in scores[:len(scores)//2]:
113
-            logger.info('Keeping %.3f : %s' % (score, str(prog)))
114
-
115
-        progs = [ prog for _, prog in scores[:len(scores)//2]]
116
-        for prog in list(progs):
117
-            progs.append(mutate(prog, force=True))
127
+            logger.info('P%d %.3f : "%s"' % (i, score, str(prog)))
128
+        if args.log_progs is not None:
129
+            with open(args.log_progs, 'a') as logprogs:
130
+                for i, (score, prog) in enumerate(scores):
131
+                    msg = 'Gen #%d P%d %.3f : "%s"\n'
132
+                    logprogs.write(msg % (generation, i, score, str(prog)))
133
+                    logprogs.flush()
134
+                logprogs.write('\n')
135
+
136
+        keep_div = 2
137
+        progs = []
138
+        for prog in [ prog for _, prog in scores[:len(scores)//keep_div]]:
139
+            progs.append(prog)
140
+            for _ in range(keep_div - 1):
141
+                progs.append(mutate(prog, force=True))
142
+                if len(progs) >= args.pool_size:
143
+                    break
118 144
             if len(progs) >= args.pool_size:
119 145
                 break
120 146
         generation += 1
147
+    exit(0)
121 148
 else:
122 149
     # Generate
123 150
     w = World(args.world_height, args.world_width)
@@ -128,6 +155,11 @@ else:
128 155
     logger.info(msg % (str(prog), args.steps, args.turmit_count))
129 156
     start = time.time()
130 157
     for step in range(args.steps):
158
+        if step % 512 == 1:
159
+            msg = 'Step %d/%d %dus/step'
160
+            msg %= (step, args.steps,
161
+                    ((time.time() - start)*1000000)//step//len(turmits))
162
+            logger.info(msg)
131 163
         for turmit in turmits:
132 164
             turmit()
133 165
     stop = time.time()

+ 7
- 5
gte/world.py View File

@@ -29,11 +29,13 @@ def eval_prog(args):
29 29
     stop = time.time()
30 30
 
31 31
     score = w.fractdim()
32
-    msg = 'P%d run#%d scores %.3f in %.2fs (%dus per step)'
33
-    msg %= (progid, trynum, score,
34
-            stop - start,
35
-            ((stop - start)*1000000)//args.steps)
36
-    logger.info(msg)
32
+    if not args.quiet:
33
+        msg = 'P%d run#%d scores %.3f in %.2fs (%dus per step)\t%s'
34
+        msg %= (progid, trynum, score,
35
+                stop - start,
36
+                ((stop - start)*1000000)//args.steps//len(turmits),
37
+                str(prog))
38
+        logger.info(msg)
37 39
     return progid, score
38 40
 
39 41
 class World(object):

+ 2
- 2
tests/test_rpnexpr.py View File

@@ -19,8 +19,8 @@ class RpnExprTestCase(unittest.TestCase):
19 19
         self.assertEqual(len(expr), 4)
20 20
         tests = ((RpnSymbol.VALUE, 5),
21 21
                  (RpnSymbol.VALUE, 255),
22
-                 (RpnSymbol.VARIABLE, 'X'),
23
-                 (RpnSymbol.OPERATION, 'MOD'))
22
+                 (RpnSymbol.VARIABLE, 'x'),
23
+                 (RpnSymbol.OPERATION, 'mod'))
24 24
         for i, (optype, val) in enumerate(tests):
25 25
             self.assertEqual(expr[i].optype, optype)
26 26
             self.assertEqual(expr[i].value, val)

Loading…
Cancel
Save