From 1ce3a6d04f8c3cd0cb8883b06b16a27c0a189049 Mon Sep 17 00:00:00 2001 From: surtur Date: Sat, 20 Aug 2022 23:28:30 +0200 Subject: [PATCH] fix(go): collect and plot algo stats comparably ...i.e. based on FES, not Generations. --- algo/plot.go | 2 +- algo/stochasticHillClimbing.go | 27 +++++++++++++++++++++------ stats/stats.go | 5 ++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/algo/plot.go b/algo/plot.go index 084e87e..16baf69 100644 --- a/algo/plot.go +++ b/algo/plot.go @@ -55,7 +55,7 @@ func PlotMeanValsMulti( iterations, bench, dimens, ) - p.X.Label.Text = xAxisLabel + p.X.Label.Text = "Objective func. evaluations" p.X.Label.TextStyle.Font.Variant = preferredFont p.X.Label.TextStyle.Font.Weight = 1 // Medium p.X.Tick.Label.Font.Variant = preferredFont diff --git a/algo/stochasticHillClimbing.go b/algo/stochasticHillClimbing.go index c4291c1..7746bf5 100644 --- a/algo/stochasticHillClimbing.go +++ b/algo/stochasticHillClimbing.go @@ -157,6 +157,7 @@ func singleHillClimb( // HillClimb performs 30 iterations of SHC (30 singleHillClimb func calls // internally) to establish a semi-relevant statistical baseline, and reports // the results of the computation. +// nolint: gocognit func HillClimb( maxFES, benchMinIters, neighbours int, theD []int, @@ -207,10 +208,9 @@ func HillClimb( Algo: "Stochastic Hill Climbing", Dimens: dimens, Iterations: minIters, - // Generations for Stochastic Hill Climbing may vary based on both - // the maxFES and bench.Neighbourhood, since that is how we arrive - // at the value of fesPerIter. - Generations: fesPerIter, + // this is subject to change, see note on Stats struct in pkg + // stats. + Generations: fes, } funcStats := &stats.FuncStats{BenchName: benchFunc} benchFuncParams := bench.FunctionParams[benchFunc] @@ -218,7 +218,7 @@ func HillClimb( Bench: benchFunc, Dimens: dimens, Iterations: minIters, - Generations: fesPerIter, + Generations: fes, Neighbours: neighbours, } uniDist := distuv.Uniform{ @@ -293,6 +293,21 @@ func HillClimb( funcStats.BenchResults[iter].Results, bestResult, ) + + // this block makes sure we properly count func evaluations for + // the purpose of correctly comparable plot comparison. i.e. + // append the winning (current best) value neighbours-1 (the + // first best is already saved at this point) times to + // represent the fact that while evaluating the neighbours to + // the current best value is taking place in the background, + // the current best value itself is kept around and + // symbolically saved as the best of the Generation. + for x := 0; x < neighbours-1; x++ { + funcStats.BenchResults[iter].Results = append( + funcStats.BenchResults[iter].Results, + bestResult, + ) + } } } @@ -303,7 +318,7 @@ func HillClimb( ) // get mean vals. - dimXMean.MeanVals = stats.GetMeanVals(funcStats.BenchResults, fesPerIter) + dimXMean.MeanVals = stats.GetMeanVals(funcStats.BenchResults, fes) // save to funcStats, too. funcStats.MeanVals = dimXMean.MeanVals diff --git a/stats/stats.go b/stats/stats.go index a83ea87..a93fe64 100644 --- a/stats/stats.go +++ b/stats/stats.go @@ -63,7 +63,10 @@ type Stats struct { Dimens int BenchFuncStats []FuncStats Iterations int - Generations int + // this should perhaps be named FES as that is a smarter thing to be + // comparing than algo generations, which can vary based on the type of + // algo, number of neighbours, etc.. + Generations int } // Len implements the sort.Interface.