Changeset 1131


Ignore:
Timestamp:
04/20/21 14:33:05 (20 months ago)
Author:
Maciej Komosinski
Message:

The "standard.py" example now incorporates features of invalid.py (handling invalid genotypes)

File:
1 moved

Legend:

Unmodified
Added
Removed
  • framspy/evolalg/examples/standard.py

    r1130 r1131  
    1 import random
    2 
    31import argparse
    42import os
    53import sys
    64import numpy as np
     5
     6#TODO add new example: steadystate.py (analogous to standard.py) OR include steadysteate as a mode in this example or in niching_novelty.py
     7#TODO extend both standard.py and steadystate.py to support >1 criteria (using DEAP's selNSGA2() and selSPEA2())
     8#TODO add comments to all examples in this directory
     9#TODO add to standard.py and steadystate.py evaluating each genotype in HOF N (configurable, default 10) times when the evolution ends instead of evaluating the last population as it is now in niching_novelty.py
     10#TODO protect all examples against invalid genotypes (fill population until all genotypes are conrrectly evaluated). And maybe remove invalid.py if it overlaps with (is a subset of) other examples
     11#TODO "debug" mode, displaying Step-based class names and their arguments so it is easy to see what happens during evolution
    712
    813from evolalg.base.lambda_step import LambdaStep
     
    2227
    2328
     29
     30EVAL_LIFESPAN_BEHAVIOR = False  # if False, standard evaluation criteria can be used as fitness as defined by the -opt parameter. If True, it is assumed that the expdef provides custom dictionary fields in evaluation and they need to be handled specifically in python source code below (this could be parametrized in command-line too, but the syntax would be complex)
     31
     32
    2433def ensureDir(string):
    2534    if os.path.isdir(string):
     
    3342        description='Run this program with "python -u %s" if you want to disable buffering of its output.' % sys.argv[
    3443            0])
    35     parser.add_argument('-path', type=ensureDir, required=True, help='Path to Framsticks without trailing slash.')
    36     # parser.add_argument('-opt', required=True,
    37     #                     help='optimization criteria : vertpos, velocity, distance, vertvel, lifespan, numjoints, numparts, numneurons, numconnections. Single or multiple criteria.')
    38     parser.add_argument('-lib', required=False, help="Filename of .so or .dll with framsticks library")
     44    parser.add_argument('-path', type=ensureDir, required=True, help='Path to the Framsticks library without trailing slash.')
     45    parser.add_argument('-opt', required=True,
     46                        help='optimization criteria : vertpos, velocity, distance, vertvel, lifespan, numjoints, numparts, numneurons, numconnections (or other as long as it is provided by the .sim file and its .expdef). Single or multiple criteria.')
     47    parser.add_argument('-lib', required=False, help="Filename of .so or .dll with the Framsticks library")
    3948    parser.add_argument('-genformat', required=False, default="1",
    4049                        help='Genetic format for the demo run, for example 4, 9, or B. If not given, f1 is assumed.')
    41 
    42     parser.add_argument("-popsize", type=int, default=50, help="Size of population, default 50.")
     50    parser.add_argument('-sim', required=False, default="eval-allcriteria.sim", help="Name of the .sim file with all parameter values")
     51    parser.add_argument("-popsize", type=int, default=50, help="Population size, default 50.")
     52    parser.add_argument('-generations', type=int, default=5, help="Number of generations, default 5.")
     53    parser.add_argument('-tournament', type=int, default=5, help="Tournament size, default 5.")
    4354    return parser.parse_args()
    4455
     
    4960
    5061def print_population_count(pop):
    51     print("Current:",len(pop))
    52     return pop # Each step must return a population
    53 
    54 
    55 def random_remove(pop):
    56     return [_ for _ in pop if random.randint(0, 1) == 0]
     62    print("Current:", len(pop))
     63    return pop  # Each step must return a population
    5764
    5865
    5966def main():
    6067    parsed_args = parseArguments()
    61     frams_lib = FramsticksLib(parsed_args.path, parsed_args.lib, "eval-movement.sim")
     68    frams_lib = FramsticksLib(parsed_args.path, parsed_args.lib, parsed_args.sim)
    6269
    6370    hall_of_fame = HallOfFameStatistics(100, "fitness")
     
    7380    ])
    7481
    75     fitness_remove = UnionStep([
     82    fitness_remove = UnionStep(
     83        [
    7684        FitnessStep(frams_lib, fields={"velocity": "fitness", "data->recording": "recording"},
    77                     fields_defaults={"velocity": None, "data->recording": None}),
    78         FieldRemove("recording", None),
    79         print_population_count,  # Stages can be also any Callable
    80     ])
     85                    fields_defaults={"velocity": None, "data->recording": None})  # custom definitions and handling
     86        if EVAL_LIFESPAN_BEHAVIOR else
     87        FitnessStep(frams_lib, fields={parsed_args.opt: "fitness", }, fields_defaults={})
     88        ]
     89        +
     90        ([FieldRemove("recording", None)] if EVAL_LIFESPAN_BEHAVIOR else [])
     91        +
     92        [print_population_count]  # Stages can also be any Callable
     93    )
    8194
    82     selection = TournamentSelection(5, copy=True)
     95    selection = TournamentSelection(parsed_args.tournament, copy=True, fit_attr="fitness")
    8396    new_generation_steps = [
    8497        FramsCrossAndMutate(frams_lib, cross_prob=0.2, mutate_prob=0.9),
     
    94107                   statistics_union]
    95108
    96     end_steps = [PopulationSave("halloffame.gen", provider=hall_of_fame.halloffame, fields={"genotype": "genotype",
    97                                                                                            "fitness": "fitness",
    98                                                                                            "custom": "recording"})]
     109    end_steps = [PopulationSave("halloffame.gen", provider=hall_of_fame.halloffame,
     110                                fields={"genotype": "genotype", "fitness": "fitness", "custom": "recording"}
     111                                if EVAL_LIFESPAN_BEHAVIOR
     112                                else {"genotype": "genotype", "fitness": "fitness"}
     113                                )]
    99114
    100115    experiment = Experiment(init_population=init_stages,
     
    106121                            )
    107122    experiment.init()
    108     experiment.run(3)
     123    experiment.run(parsed_args.generations)
    109124    for ind in hall_of_fame.halloffame:
    110125        print("%g\t%s" % (ind.fitness, ind.genotype))
Note: See TracChangeset for help on using the changeset viewer.