func run(name string, f func() *starter.Context) { wg := new(sync.WaitGroup) ch := make(chan float64, trials) for i := 0; i < trials; i++ { wg.Add(1) go func() { ctx := f() exp := &neat.Experiment{ExperimentSettings: ctx} exp.SetContext(ctx) if err := neat.Run(exp); err != nil { log.Fatalf("Fatal error in %s: %v\n", name, err) } if exp.Stopped() { ch <- 0.0 } else { ch <- 1.0 } wg.Done() }() } wg.Wait() sum := 0.0 for i := 0; i < trials; i++ { sum += <-ch } log.Println(name, "success rate:", sum/10.0) }
func Run(f func(int) (*neat.Experiment, error)) error { if *Profile { defer profile.Start(profile.CPUProfile).Stop() } // Create the collection variables n := *Trials exps := make([]*neat.Experiment, n) best := make([]neat.Genome, n) noso := make([]bool, n) fail := make([]bool, n) skip := make([]bool, n) errs := make([]error, n) var secs stats.Float64Data = make([]float64, 0, n) var fits stats.Float64Data = make([]float64, 0, n) var iters stats.Float64Data = make([]float64, 0, n) var nodes stats.Float64Data = make([]float64, 0, n) var conns stats.Float64Data = make([]float64, 0, n) var se, fi, it, no, co float64 // Begin the display fmt.Printf("Beginning trials %v\n", time.Now().Format(time.RFC3339)) fmt.Printf("\t%d trials requested\n", *Trials) if *CheckStop { fmt.Println("\tstop signals successful trial") } if *SkipEvolve { fmt.Println("\tskipping the evolution phase") } if *ShowWork { fmt.Println("\tshowing the detailed evaluation of best in each generation") } fmt.Printf("Run Iters. Seconds Nodes Conns Fitness Fail Comment \n") fmt.Printf("--- --------- --------- --------- --------- --------- ------ ---------\n") // Iterate the trials var showTime, showBest bool var err error for i := 0; i < n; i++ { var t0, t1 time.Time t0 = time.Now() if exps[i], err = f(i); err != nil { errs[i] = err fail[i] = true showBest = false showTime = false } else { if *SkipEvolve && len(exps[i].Population().Genomes) > 0 { skip[i] = true } else if err = neat.Run(exps[i]); err != nil { t1 = time.Now() errs[i] = err fail[i] = true } else { t1 = time.Now() if *CheckStop && !exps[i].Stopped() { errs[i] = fmt.Errorf("No solution found") noso[i] = true } } // Update the time stats if exps[i].Iteration() > 0 { showTime = true it = float64(exps[i].Iteration()) se = t1.Sub(t0).Seconds() if !fail[i] && !skip[i] { iters = append(iters, it) secs = append(secs, se) } } else { showTime = false } // Find the best and update the results if !fail[i] && len(exps[i].Population().Genomes) > 0 { showBest = true best[i] = findBest(exps[i].Population()) no = float64(len(best[i].Nodes)) co = float64(len(best[i].Conns)) fi = best[i].Fitness if !noso[i] { nodes = append(nodes, no) conns = append(conns, co) fits = append(fits, fi) } } else { showBest = false } } showTrial(padInt(i, 3), showTime, showBest, it, se, no, co, fi, fail[i] || noso[i], skip[i], errs[i]) } // Display the summary funcs := []func(stats.Float64Data) (float64, error){stats.Mean, stats.Median, stats.StdDevP, stats.Min, stats.Max} labs := []string{"AVG", "MED", "SDV", "MIN", "MAX"} // 3 characters var itm, sem, nom, com, fim [5]float64 if len(iters) > 0 { showTime = true for i := 0; i < len(funcs); i++ { itm[i], _ = funcs[i](iters) sem[i], _ = funcs[i](secs) } } else { showTime = false } if len(nodes) > 0 { showBest = true for i := 0; i < len(funcs); i++ { nom[i], _ = funcs[i](nodes) com[i], _ = funcs[i](conns) fim[i], _ = funcs[i](fits) } } else { showBest = false } fmt.Printf("\nSummary for trials excluding failures (and time for skipped)\n") fmt.Printf(" Iters. Seconds Nodes Conns Fitness\n") fmt.Printf("--- --------- --------- --------- --------- ---------\n") for i := 0; i < len(itm); i++ { showTrial(labs[i], showTime, showBest, itm[i], sem[i], nom[i], com[i], fim[i], false, false, nil) } // Show the evaluations of the best if *ShowWork { for i := 0; i < len(exps); i++ { if dh, ok := exps[i].Context().Evaluator().(neat.Demonstrable); ok { dh.ShowWork(true) if rst, ok := exps[i].Context().Archiver().(neat.Restorer); ok { ctx := exps[i].Context() if err := rst.Restore(ctx); err != nil { fmt.Printf("Error restoring the context for trial %d: %v\n", i, err) } } if p, err := exps[i].Context().Decoder().Decode(best[i]); err != nil { fmt.Printf("Error decoding phenome in show work: %v\n", err) } else { evl := exps[i].Context().Evaluator() if th, ok := evl.(neat.Trialable); ok { th.SetTrial(i) } r := evl.Evaluate(p) if r.Err() != nil { fmt.Printf("Error demonstrating phenome: %v\n", r.Err()) } } } } } return nil }