github.com/yaricom/goNEAT@v0.0.0-20210507221059-e2110b885482/executor.go (about)

     1  package main
     2  
     3  import (
     4  	"os"
     5  	"time"
     6  	"fmt"
     7  	"log"
     8  	"flag"
     9  	"math/rand"
    10  	"github.com/yaricom/goNEAT/experiments"
    11  	"github.com/yaricom/goNEAT/neat"
    12  	"github.com/yaricom/goNEAT/neat/genetics"
    13  	"github.com/yaricom/goNEAT/experiments/xor"
    14  	"github.com/yaricom/goNEAT/experiments/pole"
    15  )
    16  
    17  // The experiment runner boilerplate code
    18  func main() {
    19  	var out_dir_path = flag.String("out", "./out", "The output directory to store results.")
    20  	var context_path = flag.String("context", "./data/xor.neat", "The execution context configuration file.")
    21  	var genome_path = flag.String("genome", "./data/xorstartgenes", "The seed genome to start with.")
    22  	var experiment_name = flag.String("experiment", "XOR", "The name of experiment to run. [XOR, cart_pole, cart_2pole_markov, cart_2pole_non-markov]")
    23  	var trials_count = flag.Int("trials", 0, "The numbar of trials for experiment. Overrides the one set in configuration.")
    24  	var log_level = flag.Int("log_level", -1, "The logger level to be used. Overrides the one set in configuration.")
    25  
    26  	flag.Parse()
    27  
    28  	// Seed the random-number generator with current time so that
    29  	// the numbers will be different every time we run.
    30  	rand.Seed(time.Now().Unix())
    31  
    32  	// Load context configuration
    33  	configFile, err := os.Open(*context_path)
    34  	if err != nil {
    35  		log.Fatal("Failed to open context configuration file: ", err)
    36  	}
    37  	context := neat.LoadContext(configFile)
    38  
    39  	// Load Genome
    40  	log.Printf("Loading start genome for %s experiment\n", *experiment_name)
    41  	genomeFile, err := os.Open(*genome_path)
    42  	if err != nil {
    43  		log.Fatal("Failed to open genome file: ", err)
    44  	}
    45  	start_genome, err := genetics.ReadGenome(genomeFile, 1)
    46  	if err != nil {
    47  		log.Fatal("Failed to read start genome: ", err)
    48  	}
    49  	fmt.Println(start_genome)
    50  
    51  	// Check if output dir exists
    52  	out_dir := *out_dir_path
    53  	if _, err := os.Stat(out_dir); err == nil {
    54  		// backup it
    55  		back_up_dir := fmt.Sprintf("%s-%s", out_dir, time.Now().Format("2006-01-02T15_04_05"))
    56  		// clear it
    57  		err = os.Rename(out_dir, back_up_dir)
    58  		if err != nil {
    59  			log.Fatal("Failed to do previous results backup: ", err)
    60  		}
    61  	}
    62  	// create output dir
    63  	err = os.MkdirAll(out_dir, os.ModePerm)
    64  	if err != nil {
    65  		log.Fatal("Failed to create output directory: ", err)
    66  	}
    67  
    68  	// Override context configuration parameters with ones set from command line
    69  	if *trials_count > 0 {
    70  		context.NumRuns = *trials_count
    71  	}
    72  	if *log_level >= 0 {
    73  		neat.LogLevel = neat.LoggerLevel(*log_level)
    74  	}
    75  
    76  	// The 100 generation XOR experiment
    77  	experiment := experiments.Experiment{
    78  		Id:0,
    79  		Trials:make(experiments.Trials, context.NumRuns),
    80  	}
    81  	var generationEvaluator experiments.GenerationEvaluator
    82  	if *experiment_name == "XOR" {
    83  		experiment.MaxFintessScore = 16.0 // as given by fitness function definition
    84  		generationEvaluator = xor.XORGenerationEvaluator{OutputPath:out_dir}
    85  	} else if *experiment_name == "cart_pole" {
    86  		experiment.MaxFintessScore = 1.0 // as given by fitness function definition
    87  		generationEvaluator = pole.CartPoleGenerationEvaluator{
    88  			OutputPath:out_dir,
    89  			WinBalancingSteps:500000,
    90  			RandomStart:true,
    91  		}
    92  	} else if *experiment_name == "cart_2pole_markov" {
    93  		experiment.MaxFintessScore = 1.0 // as given by fitness function definition
    94  		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
    95  			OutputPath:out_dir,
    96  			Markov:true,
    97  			ActionType:experiments.ContinuousAction,
    98  		}
    99  	} else if *experiment_name == "cart_2pole_non-markov" {
   100  		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
   101  			OutputPath:out_dir,
   102  			Markov:false,
   103  			ActionType:experiments.ContinuousAction,
   104  		}
   105  	}
   106  
   107  	err = experiment.Execute(context, start_genome, generationEvaluator)
   108  	if err != nil {
   109  		log.Fatal("Failed to perform XOR experiment: ", err)
   110  	}
   111  
   112  	// Print statistics
   113  	experiment.PrintStatistics()
   114  
   115  	fmt.Printf(">>> Start genome file:  %s\n", *genome_path)
   116  	fmt.Printf(">>> Configuration file: %s\n", *context_path)
   117  
   118  	// Save experiment data
   119  	expResPath := fmt.Sprintf("%s/%s.dat", out_dir, *experiment_name)
   120  	expResFile, err := os.Create(expResPath)
   121  	if err == nil {
   122  		err = experiment.Write(expResFile)
   123  	}
   124  	if err != nil {
   125  		log.Fatal("Failed to save experiment results", err)
   126  	}
   127  }