major updates for v2.1

pull/13/head
kstaats 2018-04-22 13:58:04 -07:00
parent 0c70669395
commit c6cee4928f
3 changed files with 604 additions and 555 deletions

View File

@ -1,7 +1,7 @@
# Karoo GP (desktop + server combined)
# Use Genetic Programming for Classification and Symbolic Regression
# by Kai Staats, MSc; see LICENSE.md
# version 2.0
# version 2.1
'''
A word to the newbie, expert, and brave--
@ -10,43 +10,39 @@ before running this application. While your computer will not burst into flames
hole if you do not, you will likely find more enjoyment of this particular flavour of GP with a little understanding
of its intent and design.
Without any arguments, Karoo GP relies entirely upon the scripted settings and the datasets located in karoo_gp/files/.
Without any command line arguments, Karoo GP relies upon user settings and the datasets located in karoo_gp/files/.
$ python karoo_gp_main.py
(or from iPython)
$ run karoo_gp_main.py
If you include the path to an external dataset, it will auto-load at launch:
$ python karoo_gp_main.py /[path]/[to_your]/[filename].csv
You can include a one or more additional arguments, they will override the default values, as follows:
If you include one or more additional arguments, they will override the default values, as follows:
-ker [r,c,m] fitness function: (r)egression, (c)lassification, or (m)atching
-typ [f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half
-bas [3...10] maximum Tree depth for the initial population
-max [3...10] maximum Tree depth for the entire run
-min [3...100] minimum number of nodes
-pop [10...1000] maximum population
-gen [1...100] number of generations
-tor [1...100] number of trees selected for the tournament
-evr [0.0 ... 1.0] fraction percent of genetic operator Reproduction
-evp [0.0 ... 1.0] fraction percent of genetic operator Point Mutation
-evb [0.0 ... 1.0] fraction percent of genetic operator Branch Mutation
-evc [0.0 ... 1.0] fraction percent of genetic operator Crossover
-ker [r,c,m] fitness function: (r)egression, (c)lassification, or (m)atching
-typ [f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half
-bas [3...10] maximum Tree depth for initial population
-max [3...10] maximum Tree depth for entire run
-min [3 to 2^(bas +1) - 1] minimum number of nodes
-pop [10...1000] number of trees in each generational population
-gen [1...100] number of generations
-tor [7 per 100] number of trees selected for tournament
-evr [0.0...1.0] decimal percent of pop generated through Reproduction
-evp [0.0...1.0] decimal percent of pop generated through Point Mutation
-evb [0.0...1.0] decimal percent of pop generated through Branch Mutation
-evc [0.0...1.0] decimal percent of pop generated through Crossover
If you include any of the above flags, then you *must* also include a flag to load an external dataset.
-fil [filename] an external dataset
-fil [path]/[to]/[data].csv an external dataset
An example is given, as follows:
$ python karoo_gp_server.py -ker c -typ r -bas 4 -fil /[path]/[to_your]/[filename].csv
$ python karoo_gp_server.py -ker c -typ r -bas 4 -fil [path]/[to]/[data].csv
'''
@ -71,146 +67,157 @@ print ''
#++++++++++++++++++++++++++++++++++++++++++
# User Interface Configuation |
# User Interface for Configuation |
#++++++++++++++++++++++++++++++++++++++++++
if len(sys.argv) < 3: # either no command line argument (1) or the filename (2) was provided
if len(sys.argv) < 3: # either no command line argument (1) or a filename (2) is provided
# menu = ['c','r','m','p',''] # inserted all menus directly into while loops on 2018 05/07
while True:
try:
query = raw_input('\t Select (c)lassification, (r)egression, (m)atching, or (p)lay (default m): ')
if query not in ['c','r','m','p','']: raise ValueError()
kernel = query or 'm'; break
else: kernel = query or 'm'; break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
if kernel == 'p':
if kernel == 'p': # play mode
while True:
try:
tree_type = raw_input('\t Select (f)ull or (g)row (default g): ')
if tree_type not in ['f','g','']: raise ValueError()
tree_type = tree_type or 'f'; break
query = raw_input('\t Select (f)ull or (g)row (default g): ')
if query not in ['f','g','']: raise ValueError()
else: tree_type = query or 'f'; break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
while True:
try:
tree_depth_base = raw_input('\t Enter the depth of the Tree (default 1): ')
if tree_depth_base not in str(range(1,11)) or tree_depth_base == '0': raise ValueError()
elif tree_depth_base == '': tree_depth_base = 1; break
tree_depth_base = int(tree_depth_base); break
query = raw_input('\t Enter the depth of the Tree (default 1): ')
if query not in str(range(1,11)) or query == '0': raise ValueError()
elif query == '': tree_depth_base = 1; break
else: tree_depth_base = int(query); break
except ValueError: print '\t\033[32m Enter a number from 1 including 10. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
tree_depth_max = tree_depth_base
tree_depth_min = 3
tree_pop_max = 1
generation_max = 1
gen_max = 1
tourn_size = 0
display = 'm'
# evolve_repro, evolve_point, evolve_branch, evolve_cross, tourn_size, precision, filename are not required
else: # if any other kernel is selected
while True:
try:
tree_type = raw_input('\t Select (f)ull, (g)row, or (r)amped 50/50 method (default r): ')
if tree_type not in ['f','g','r','']: raise ValueError()
tree_type = tree_type or 'r'; break
query = raw_input('\t Select (f)ull, (g)row, or (r)amped 50/50 method (default r): ')
if query not in ['f','g','r','']: raise ValueError()
else: tree_type = query or 'r'; break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
while True:
try:
tree_depth_base = raw_input('\t Enter depth of the \033[3minitial\033[0;0m population of Trees (default 3): ')
if tree_depth_base not in str(range(1,11)) or tree_depth_base == '0': raise ValueError()
elif tree_depth_base == '': tree_depth_base = 3; break
tree_depth_base = int(tree_depth_base); break
query = raw_input('\t Enter depth of the \033[3minitial\033[0;0m population of Trees (default 3): ')
if query not in str(range(1,11)) or query == '0': raise ValueError()
elif query == '': tree_depth_base = 3; break
else: tree_depth_base = int(query); break
except ValueError: print '\t\033[32m Enter a number from 1 including 10. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
if tree_type == 'f': tree_depth_max = tree_depth_base
else: # if type is Full, tree_depth_max is equal to tree_depth_base (initial pop setting)
while True:
try:
tree_depth_max = raw_input('\t Enter maximum Tree depth (default %i): ' %tree_depth_base)
if tree_depth_max not in str(range(tree_depth_base,11)): raise ValueError()
elif tree_depth_max == '': tree_depth_max = tree_depth_base
tree_depth_max = int(tree_depth_max)
if tree_depth_max < tree_depth_base: raise ValueError() # if max is set to < min 20170918
else: break
except ValueError: print '\t\033[32m Enter a number > or = the initial Tree depth. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
max_nodes = 2**(tree_depth_base +1) - 1 # auto calc the max number of nodes for the given depth
while True:
try:
query = raw_input('\t Enter maximum Tree depth (default %s): ' %str(tree_depth_base))
if query not in str(range(tree_depth_base,11)) or query == '0': raise ValueError()
elif query == '': tree_depth_max = tree_depth_base; break
else: tree_depth_max = int(query); break
except ValueError: print '\t\033[32m Enter a number > or = the initial Tree depth. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
max_nodes = 2**(tree_depth_base+1)-1 # calc the max number of nodes for the given depth
while True:
try:
tree_depth_min = raw_input('\t Enter minimum number of nodes for any given Tree (default 3; max %s): ' %str(max_nodes))
if tree_depth_min not in str(range(3,max_nodes)) or tree_depth_min == '0' or tree_depth_min == '1' or tree_depth_min == '2': raise ValueError()
elif tree_depth_min == '': tree_depth_min = 3
tree_depth_min = int(tree_depth_min); break
query = raw_input('\t Enter minimum number of nodes for any given Tree (default 3; max %s): ' %str(max_nodes))
if query not in str(range(3,max_nodes + 1)) or query == '0' or query == '1' or query == '2': raise ValueError()
elif query == '': tree_depth_min = 3; break
else: tree_depth_min = int(query); break
except ValueError: print '\t\033[32m Enter a number from 3 including %s. Try again ...\n\033[0;0m' %str(max_nodes)
except KeyboardInterrupt: sys.exit()
#while True:
#try:
#swim = raw_input('\t Select (p)artial or (f)ull operator inclusion (default p): ')
#if swim not in ['p','f','']: raise ValueError()
#swim = swim or 'p'; break
#except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
#except KeyboardInterrupt: sys.exit()
while True:
try:
tree_pop_max = raw_input('\t Enter number of Trees in each population (default 100): ')
if tree_pop_max not in str(range(1,1001)) or tree_pop_max == '0': raise ValueError()
elif tree_pop_max == '': tree_pop_max = 100
tree_pop_max = int(tree_pop_max); break
query = raw_input('\t Enter number of Trees in each population (default 100): ')
if query not in str(range(1,1001)) or query == '0': raise ValueError()
elif query == '': tree_pop_max = 100; break
else: tree_pop_max = int(query); break
except ValueError: print '\t\033[32m Enter a number from 1 including 1000. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
tourn_size = int(tree_pop_max * 0.07) # default 7% can be changed by selecting Generation, 'ts', and then enter the run.
# calculate the tournament size
tourn_size = int(tree_pop_max * 0.07) # default 7% can be changed by selecting (g)eneration and then 'ts'
if tourn_size < 2: tourn_size = 2 # forces some diversity for small populations
if tree_pop_max == 1: tourn_size = 1 # in theory, supports the evolution of a single Tree - NEED TO FIX 2018 04/19
while True:
try:
generation_max = raw_input('\t Enter max number of generations (default 10): ')
if generation_max not in str(range(1,101)) or generation_max == '0': raise ValueError()
elif generation_max == '': generation_max = 10
generation_max = int(generation_max); break
query = raw_input('\t Enter max number of generations (default 10): ')
if query not in str(range(1,101)) or query == '0': raise ValueError()
elif query == '': gen_max = 10; break
gen_max = int(query); break
except ValueError: print '\t\033[32m Enter a number from 1 including 100. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
while True:
try:
display = raw_input('\t Display (i)nteractive, (g)eneration, (m)iminal, (s)ilent, or (d)e(b)ug (default m): ')
if display not in ['i','g','m','s','db','']: raise ValueError()
display = display or 'm'; break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
if gen_max > 1:
while True:
try:
query = raw_input('\t Display (i)nteractive, (g)eneration, (m)iminal, (s)ilent, or (d)e(b)ug (default m): ')
if query not in ['i','g','m','s','db','']: raise ValueError()
display = query or 'm'; break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\n\033[0;0m'
except KeyboardInterrupt: sys.exit()
else: display = 's' # display mode is not used, but a value must be passed
### additional configuration parameters ###
evolve_repro = int(0.1 * tree_pop_max) # quantity of a population generated through Reproduction
evolve_point = int(0.0 * tree_pop_max) # quantity of a population generated through Point Mutation
evolve_branch = int(0.2 * tree_pop_max) # quantity of a population generated through Branch Mutation
evolve_cross = int(0.7 * tree_pop_max) # quantity of a population generated through Crossover
filename = '' # not required unless an external file is referenced
precision = 6 # number of floating points for the round function in 'fx_fitness_eval'
mode = 'm' # pause when complete, awaiting further user interaction
swim = 'p' # require (p)artial or (f)ull set of features (operators) for each Tree entering the gene_pool
mode = 'd' # pause at the (d)esktop when complete, awaiting further user interaction; or terminate in (s)erver mode
#++++++++++++++++++++++++++++++++++++++++++
# Command Line Configuation |
# Command Line for Configuation |
#++++++++++++++++++++++++++++++++++++++++++
else: # two or more command line argument were provided
else: # two or more command line arguments provided
ap = argparse.ArgumentParser(description = 'Karoo GP Server')
ap.add_argument('-ker', action = 'store', dest = 'kernel', default = 'c', help = '[c,r,m] fitness function: (r)egression, (c)lassification, or (m)atching')
ap.add_argument('-typ', action = 'store', dest = 'type', default = 'r', help = '[f,g,r] Tree type: (f)ull, (g)row, or (r)amped half/half')
ap.add_argument('-bas', action = 'store', dest = 'depth_base', default = 4, help = '[3...10] maximum Tree depth for the initial population')
ap.add_argument('-max', action = 'store', dest = 'depth_max', default = 4, help = '[3...10] maximum Tree depth for the entire run')
ap.add_argument('-min', action = 'store', dest = 'depth_min', default = 3, help = 'The minimum number of nodes ranges from 3 to 2^(base_depth +1) - 1')
ap.add_argument('-pop', action = 'store', dest = 'pop_max', default = 100, help = '[10...1000] maximum population')
ap.add_argument('-min', action = 'store', dest = 'depth_min', default = 3, help = 'minimum nodes, from 3 to 2^(base_depth +1) - 1')
ap.add_argument('-pop', action = 'store', dest = 'pop_max', default = 100, help = '[10...1000] number of trees per generation')
ap.add_argument('-gen', action = 'store', dest = 'gen_max', default = 10, help = '[1...100] number of generations')
ap.add_argument('-tor', action = 'store', dest = 'tor_size', default = 7, help = '[7 for each 100 recommended] tournament size')
ap.add_argument('-evr', action = 'store', dest = 'evo_r', default = 0.1, help = '[0.0-1.0] fraction of pop generated through Reproduction')
ap.add_argument('-evp', action = 'store', dest = 'evo_p', default = 0.0, help = '[0.0-1.0] fraction of pop generated through Point Mutation')
ap.add_argument('-evb', action = 'store', dest = 'evo_b', default = 0.2, help = '[0.0-1.0] fraction of pop generated through Branch Mutation')
ap.add_argument('-evc', action = 'store', dest = 'evo_c', default = 0.7, help = '[0.0-1.0] fraction of pop generated through Crossover')
ap.add_argument('-tor', action = 'store', dest = 'tor_size', default = 7, help = '[7 for each 100] recommended tournament size')
ap.add_argument('-evr', action = 'store', dest = 'evo_r', default = 0.1, help = '[0.0-1.0] decimal percent of pop generated through Reproduction')
ap.add_argument('-evp', action = 'store', dest = 'evo_p', default = 0.0, help = '[0.0-1.0] decimal percent of pop generated through Point Mutation')
ap.add_argument('-evb', action = 'store', dest = 'evo_b', default = 0.2, help = '[0.0-1.0] decimal percent of pop generated through Branch Mutation')
ap.add_argument('-evc', action = 'store', dest = 'evo_c', default = 0.7, help = '[0.0-1.0] decimal percent of pop generated through Crossover')
ap.add_argument('-fil', action = 'store', dest = 'filename', default = '', help = '/path/to_your/[data].csv')
args = ap.parse_args()
@ -222,25 +229,29 @@ else: # two or more command line argument were provided
tree_depth_max = int(args.depth_max)
tree_depth_min = int(args.depth_min)
tree_pop_max = int(args.pop_max)
generation_max = int(args.gen_max)
gen_max = int(args.gen_max)
tourn_size = int(args.tor_size)
evolve_repro = int(float(args.evo_r) * tree_pop_max) # quantity of each population generated through Reproduction
evolve_point = int(float(args.evo_p) * tree_pop_max) # quantity of each population generated through Point Mutation
evolve_branch = int(float(args.evo_b) * tree_pop_max) # quantity of each population generated through Branch Mutation
evolve_cross = int(float(args.evo_c) * tree_pop_max) # quantity of each population generated through Crossover
evolve_repro = int(float(args.evo_r) * tree_pop_max)
evolve_point = int(float(args.evo_p) * tree_pop_max)
evolve_branch = int(float(args.evo_b) * tree_pop_max)
evolve_cross = int(float(args.evo_c) * tree_pop_max)
filename = str(args.filename)
display = 's' # display mode is set to (s)ilent
precision = 6 # number of floating points for the round function in 'fx_fitness_eval'
mode = 's' # drop back to the command line when complete
swim = 'p' # require (p)artial or (f)ull set of features (operators) for each Tree entering the gene_pool
mode = 's' # pause at the (d)esktop when complete, awaiting further user interaction; or terminate in (s)erver mode
#++++++++++++++++++++++++++++++++++++++++++
# Pass all settings to the base_class |
# Conduct the GP run |
#++++++++++++++++++++++++++++++++++++++++++
gp.fx_karoo_gp(kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, generation_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, mode)
gp.fx_karoo_gp(kernel, tree_type, tree_depth_base, tree_depth_max, tree_depth_min, tree_pop_max, gen_max, tourn_size, filename, evolve_repro, evolve_point, evolve_branch, evolve_cross, display, precision, swim, mode)
print '\n\033[3m "It is not the strongest of the species that survive, nor the most intelligent,\033[0;0m'
print '\033[3m but the one most responsive to change."\033[0;0m --Charles Darwin\n'
print '\033[3m Congrats!\033[0;0m Your Karoo GP run is complete.\n'
sys.exit()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,245 @@
# Karoo GP Pause Menu
# A text-based user interface for mid-run parameter configuration and population studies
# by Kai Staats, MSc; see LICENSE.md
# version 2.1
def pause(menu_dict):
'''
Pause the program execution and invok the user to make one or more valid options. The "eol" parameter
instructs this method to display a different screen for mid-run or end-of-line, and then dive back into the
current run, or do nothing accordingly.
(would like to upgrade to 'select case')
Called by: fx_karoo_gp
Arguments required: eol, menu_dict
'''
options = ['','?','help','i','m','g','s','db','ts','min','bal','l','pop','t','p','id','dir','w','cont','q']
while True:
try:
menu = raw_input('\n\t\033[36m (pause) \033[0;0m')
if menu not in options: raise ValueError()
else: break
except ValueError: print '\t\033[32m Select from the options given. Try again ...\033[0;0m'
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
if menu == '': menu_dict['input_a'] = 'esc'; return menu_dict # ENTER enables next step in generational, interactive, and debug display
elif menu == '?' or menu == 'help':
print '\n\t\033[36mSelect one of the following options:\033[0;0m'
print '\t\033[36m\033[1m i \t\033[0;0m engage Interactive display mode'
print '\t\033[36m\033[1m m \t\033[0;0m engage Minimal display mode'
print '\t\033[36m\033[1m g \t\033[0;0m engage Generation display mode'
print '\t\033[36m\033[1m s \t\033[0;0m engage Silent display mode'
print '\t\033[36m\033[1m db \t\033[0;0m engage De-Bug display mode'
print ''
print '\t\033[36m\033[1m ts \t\033[0;0m adjust tournament size'
print '\t\033[36m\033[1m min \t\033[0;0m adjust minimum number of nodes'
# print '\t\033[36m\033[1m max \t\033[0;0m adjust maximum Tree depth' # future option
print '\t\033[36m\033[1m bal \t\033[0;0m adjust balance of genetic operators'
print ''
print '\t\033[36m\033[1m l \t\033[0;0m list Trees with leading fitness scores'
print '\t\033[36m\033[1m pop \t\033[0;0m list Trees in current population'
print '\t\033[36m\033[1m t \t\033[0;0m evaluate a single Tree against the test data'
print '\t\033[36m\033[1m p \t\033[0;0m print a single Tree to screen'
print ''
print '\t\033[36m\033[1m id \t\033[0;0m display current generation ID'
print '\t\033[36m\033[1m dir \t\033[0;0m display current working directory'
# print '\t\033[36m\033[1m load \t\033[0;0m load population_s (seed) to replace population_a (current)'
print '\t\033[36m\033[1m w \t\033[0;0m write the evolving population_b to disk'
print ''
print '\t\033[36m\033[1m cont \t\033[0;0m add generations and continue your run'
print '\t\033[36m\033[1m q \t\033[0;0m quit Karoo GP'
if menu_dict['gen_id'] == menu_dict['gen_max']: print '\n\t Your GP run is complete. You may \033[36m\033[1madd\033[0;0m generations and \033[36m\033[1mcont\033[0;0minue, or \033[36m\033[1mq\033[0;0muit.'
else: print '\n\t You are mid-run. You may \033[36m\033[1m cont\033[0;0minue or \033[36m\033[1mq\033[0;0muit without saving population_b.'
elif menu == 'i': menu_dict['display'] = 'i'; print '\n\t Interactive display mode engaged (for control freaks)'
elif menu == 'm': menu_dict['display'] = 'm'; print '\n\t Minimal display mode engaged (for recovering control freaks)'
elif menu == 'g': menu_dict['display'] = 'g'; print '\n\t Generation display mode engaged (for GP gurus)'
elif menu == 's': menu_dict['display'] = 's'; print '\n\t Silent display mode engaged (for zen masters)'
elif menu == 'db': menu_dict['display'] = 'db'; print '\n\t De-Bug display mode engaged (for evolutionary biologists)'
elif menu == 'ts': # adjust the tournament size
while True:
try:
print '\n\t The current tournament size is:', menu_dict['tourn_size']
query = raw_input('\t Adjust the tournament size (suggest 7 for each 100): ')
if query not in str(range(2,menu_dict['tree_pop_max'] + 1)) or query == '0' or query == '1': raise ValueError() # not ideal 20170918
elif query == '': break
else: menu_dict['tourn_size'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 2 including %s. Try again ...\033[0;0m' %str(menu_dict['tree_pop_max'])
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
elif menu == 'min': # adjust the minimum number of nodes per Tree
# max_nodes = 2**(tree_depth_base +1) - 1 # NEED TO calc to replace upper limit in range but tree_depth_base is not global - 2018 04/22
while True:
try:
print '\n\t The current minimum number of nodes is:', menu_dict['tree_depth_min']
query = raw_input('\t Adjust the minimum number of nodes for all Trees (min 3): ')
if query not in str(range(3,1000)) or query == '0' or query == '1' or query == '2': raise ValueError() # not ideal 20170918
elif query == '': break
else: menu_dict['tree_depth_min'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 3 including 1000. Try again ...\033[0;0m'
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
# NEED TO ADD: adjustable tree_depth_max
#elif menu == 'max': # adjust the maximum Tree depth
#
# while True:
# try:
# print '\n\t The current \033[3madjusted\033[0;0m maximum Tree depth is:', gp.tree_depth_max
# query = raw_input('\n\t Adjust the global maximum Tree depth to (1 ... 10): ')
# if query not in str(range(1,11)): raise ValueError()
# if query < gp.tree_depth_max:
# print '\n\t\033[32m This value is less than the current value.\033[0;0m'
# conf = raw_input('\n\t Are you ok with this? (y/n) ')
# if conf == 'n': break
# except ValueError: print '\n\t\033[32m Enter a number from 1 including 10. Try again ...\033[0;0m'
# except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
elif menu == 'bal': # adjust the balance of genetic operators'
print '\n\t The current balance of genetic operators is:'
print '\t\t Reproduction:', menu_dict['evolve_repro']; tmp_repro = menu_dict['evolve_repro']
print '\t\t Point Mutation:', menu_dict['evolve_point']; tmp_point = menu_dict['evolve_point']
print '\t\t Branch Mutation:', menu_dict['evolve_branch']; tmp_branch = menu_dict['evolve_branch']
print '\t\t Crossover:', menu_dict['evolve_cross'], '\n'; tmp_cross = menu_dict['evolve_cross']
while True:
try:
query = raw_input('\t Enter quantity of Trees to be generated by Reproduction: ')
if query not in str(range(0,1000)): raise ValueError()
elif query == '': break
else: tmp_repro = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 0 including %s. Try again ...\033[0;0m' %str(menu_dict['tree_pop_max'])
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
while True:
try:
query = raw_input('\t Enter quantity of Trees to be generated by Point Mutation: ')
if query not in str(range(0,1000)): raise ValueError()
elif query == '': break
else: tmp_point = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 0 including %s. Try again ...\033[0;0m' %str(menu_dict['tree_pop_max'])
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
while True:
try:
query = raw_input('\t Enter quantity of Trees to be generated by Branch Mutation: ')
if query not in str(range(0,1000)): raise ValueError()
elif query == '': break
else: tmp_branch = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 0 including %s. Try again ...\033[0;0m' %str(menu_dict['tree_pop_max'])
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
while True:
try:
query = raw_input('\t Enter quantity of Trees to be generated by Crossover: ')
if query not in str(range(0,1000)): raise ValueError()
elif query == '': break
else: tmp_cross = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 0 including %s. Try again ...\033[0;0m' %str(menu_dict['tree_pop_max'])
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
if tmp_repro + tmp_point + tmp_branch + tmp_cross != menu_dict['tree_pop_max']:
print '\n\t The sum of the above does not equal %s. Try again ...' %str(menu_dict['tree_pop_max'])
else:
print '\n\t The revised balance of genetic operators is:'
print '\t\t Reproduction:', tmp_repro; menu_dict['evolve_repro'] = tmp_repro
print '\t\t Point Mutation:', tmp_point; menu_dict['evolve_point'] = tmp_point
print '\t\t Branch Mutation:', tmp_branch; menu_dict['evolve_branch'] = tmp_branch
print '\t\t Crossover:', tmp_cross; menu_dict['evolve_cross'] = tmp_cross
elif menu == 'l': # display dictionary of Trees with the best fitness score
print '\n\t The leading Trees and their associated expressions are:'
for n in sorted(menu_dict['fittest_dict']): print '\t ', n, ':', menu_dict['fittest_dict'][n]
elif menu == 'pop': # list Trees in the current population
if menu_dict['gen_id'] == 1: menu_dict['input_a'] = 'pop_a'
else: menu_dict['input_a'] = 'pop_b'
elif menu == 't': # evaluate a Tree against the TEST data
if menu_dict['gen_id'] == 1: print '\n\t\033[32m You cannot evaluate the foundation population. Be patient ...\033[0;0m'
else: # gen_id > 1
while True:
try:
query = raw_input('\n\t Select a Tree to test: ')
if query not in str(range(1, menu_dict['pop_b_len'])) or query == '0': raise ValueError()
elif query == '': break
else: menu_dict['input_a'] = 'test'; menu_dict['input_b'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 1 including %s. Try again ...\033[0;0m' %str(menu_dict['pop_b_len'] - 1)
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
elif menu == 'p': # print a Tree to screen -- NEED TO ADD: SymPy graphical print option
if menu_dict['gen_id'] == 1:
while True:
try:
query = raw_input('\n\t Select a Tree to print: ')
if query not in str(range(1, menu_dict['pop_a_len'])) or query == '0': raise ValueError()
elif query == '': break
else: menu_dict['input_a'] = 'print_a'; menu_dict['input_b'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 1 including %s. Try again ...\033[0;0m' %str(menu_dict['pop_a_len'] - 1)
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
else: # gen_id > 1
while True:
try:
query = raw_input('\n\t Select a Tree to print: ')
if query not in str(range(1, menu_dict['pop_b_len'])) or query == '0': raise ValueError()
elif query == '': break
else: menu_dict['input_a'] = 'print_b'; menu_dict['input_b'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 1 including %s. Try again ...\033[0;0m' %str(menu_dict['pop_b_len'] - 1)
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
elif menu == 'id': print '\n\t The current generation is:', menu_dict['gen_id']
elif menu == 'dir': print '\n\t The current working directory is:', menu_dict['path']
# NEED TO review and fix
#elif menu == 'load': # load population_s to replace population_a
# while True:
# try:
# query = raw_input('\n\t Overwrite the current population with population_s? (y/n) ')
# if query not in ['y','n']: raise ValueError()
# if query == 'y': menu_dict['input_a'] = 'load'; break
# elif query == 'n': break
# except ValueError: print '\n\t\033[32m Enter (y)es or (n)o. Try again ...\033[0;0m'
# except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
elif menu == 'w': # write the evolving population_b to disk
if menu_dict['gen_id'] > 1: menu_dict['input_a'] = 'write'
else: print '\n\t\033[36m The evolving population_b does not yet exist\033[0;0m'
elif menu == 'cont': # continue a GP run
if menu_dict['gen_id'] == menu_dict['gen_max']:
while True:
try:
query = raw_input('\n\t\033[3m You are at the end of your run.\033[0;0m\n\t Add more generations to continue (1-100 or ENTER to escape): ')
if query not in str(range(1,101)) or query == '0': raise ValueError()
elif query == '': break
else: menu_dict['input_a'] = 'cont'; menu_dict['input_b'] = int(query); break
except ValueError: print '\n\t\033[32m Enter a number from 1 including 100. Try again ...\033[0;0m'
except KeyboardInterrupt: print '\n\t\033[32m Enter q to quit\033[0;0m'
else: menu_dict['input_a'] = 'cont'
elif menu == 'q': # quit
while True:
try:
query = raw_input('\n\t Quit Karoo GP? (y/n) ')
if query not in ['y','n','']: raise ValueError()
if query == 'y': menu_dict['input_a'] = 'quit'; break
else: break
except ValueError: print '\n\t\033[32m Enter (y)es or (n)o. Try again ...\033[0;0m'
except KeyboardInterrupt: print '\n\t\033[32m Enter (y)es or (n)o. Try again ...\033[0;0m'
return menu_dict