chore: add all updates, sort out later
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
leo 2022-12-24 11:30:22 +01:00
parent c3b9ddee27
commit 68b14f9960
Signed by: wanderer
SSH Key Fingerprint: SHA256:Dp8+iwKHSlrMEHzE3bJnPng70I7LEsa3IJXRH/U+idQ
16 changed files with 155 additions and 6 deletions

@ -316,4 +316,4 @@ def main(ctx):
} }
] ]
# vim: ft=bzl.starlark syntax=bzl.starlark noexpandtab ts=4 foldmethod=manual # vim:ft=bzl.starlark:syntax=bzl.starlark:noexpandtab:ts=4:sts=4:sw=4:foldmethod=manual

2
.envrc

@ -4,4 +4,6 @@ use flake
# comment out if not planning to use this # comment out if not planning to use this
add_extra_vimrc add_extra_vimrc
# alias gor='go run'
# vim: ff=unix ft=sh # vim: ff=unix ft=sh

@ -13,7 +13,7 @@ issues:
linters: linters:
enable: enable:
- bidichk - bidichk
- dupl # - dupl
# The linter 'deadcode' is deprecated (since v1.49.0) due to: The owner # The linter 'deadcode' is deprecated (since v1.49.0) due to: The owner
# seems to have abandoned the linter. Replaced by unused. # seems to have abandoned the linter. Replaced by unused.
# - deadcode # - deadcode

@ -14,6 +14,8 @@ import (
"git.dotya.ml/wanderer/math-optim/stats" "git.dotya.ml/wanderer/math-optim/stats"
) )
// var Algos = []string{"Random Search", "Stochastic Hill Climbing"}
// mu protects access to meanStats. // mu protects access to meanStats.
var mu sync.Mutex var mu sync.Mutex
@ -157,6 +159,11 @@ func DoRandomSearch(wg *sync.WaitGroup, m *sync.Mutex) {
algoStats[i] = s algoStats[i] = s
} }
// save stats to json.
// stats.SaveStats(schw, "schwefel")
// stats.SaveStats(djg1, "djg1")
// stats.SaveStats(djg2, "djg2")
pCh := make(chan report.PicList, funcCount*len(bench.Dimensions)) pCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
pMeanCh := make(chan report.PicList, funcCount*len(bench.Dimensions)) pMeanCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
@ -188,6 +195,14 @@ func DoRandomSearch(wg *sync.WaitGroup, m *sync.Mutex) {
m.Unlock() m.Unlock()
} }
// TODO(me): split this package to multiple - package per algo, common code here.
// TODO(me): implement Simulated Annaeling.
// TODO(me): implement a variant of Stochastic Hill Climber that tweaks its
// Neighbourhood size or MaxNeighbourVariancePercent based on the
// latest 5 values, if they don't change, params get tweaked to
// broaden the search space to make sure it's not stuck in a local
// extreme.
// DoStochasticHillClimbing performs a search using the 'Stochastic Hill // DoStochasticHillClimbing performs a search using the 'Stochastic Hill
// Climbing' method. // Climbing' method.
func DoStochasticHillClimbing(wg *sync.WaitGroup, m *sync.Mutex) { func DoStochasticHillClimbing(wg *sync.WaitGroup, m *sync.Mutex) {
@ -250,3 +265,56 @@ func DoStochasticHillClimbing(wg *sync.WaitGroup, m *sync.Mutex) {
stats.SaveTable(algoName, algoStats) stats.SaveTable(algoName, algoStats)
m.Unlock() m.Unlock()
} }
func DoStochasticHillClimbing100Neigh(wg *sync.WaitGroup, m *sync.Mutex) {
defer wg.Done()
printSHC("starting...")
// funcCount is the number of bench functions available.
funcCount := len(bench.Functions)
// stats for the current algo (StochasticHillClimber).
algoStats := make([][]stats.Stats, funcCount)
// ch serves as a way to get the actual computed output.
ch := make(chan []stats.Stats, funcCount)
for i := range algoStats {
go HillClimb(10000, 30, 100, bench.Dimensions, bench.FuncNames[i], ch)
}
// get results.
for i := range algoStats {
s := <-ch
algoStats[i] = s
}
pCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
pMeanCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
for _, algoStat := range algoStats {
go plotAllDims(algoStat, "plot", ".pdf", pCh, pMeanCh)
}
pLs := []report.PicList{}
pLsMean := []report.PicList{}
for range algoStats {
pL := <-pCh
pLMean := <-pMeanCh
pLs = append(pLs, pL)
pLsMean = append(pLsMean, pLMean)
}
algoName := "Stochastic Hill Climbing 100 Neighbours"
// protect access to shared data.
m.Lock()
report.SavePicsToFile(pLs, pLsMean, algoName)
// report.SavePicsToFile(pLsMean, pLs, algoName)
// stats.PrintStatisticTable(algoStats)
stats.SaveTable(algoName, algoStats)
m.Unlock()
}

@ -4,6 +4,7 @@
package algo package algo
import ( import (
"log"
"os" "os"
"sync" "sync"
"testing" "testing"
@ -16,14 +17,18 @@ var wg sync.WaitGroup
var m sync.Mutex var m sync.Mutex
func TestDoRandomSearchExec(t *testing.T) { func TestDoRandomSearchExec(t *testing.T) {
t.Parallel()
wg.Add(1) wg.Add(1)
// use t.tmpdir
go DoRandomSearch(&wg, &m) go DoRandomSearch(&wg, &m)
wg.Wait() wg.Wait()
picsDir := report.GetPicsDir() + "-test-rs" picsDir := report.GetPicsDir() + "-test-rs"
// attempt to clean up.
if err := os.RemoveAll(picsDir); err != nil { if err := os.RemoveAll(picsDir); err != nil {
t.Error(err) t.Error(err)
} }
@ -34,6 +39,7 @@ func TestDoRandomSearchExec(t *testing.T) {
t.Error("picsDir should have already been cleaned up") t.Error("picsDir should have already been cleaned up")
} }
log.Println("pwd:", os.Getenv("PWD"))
// clean up outdir. // clean up outdir.
if err := os.RemoveAll("out"); err != nil { if err := os.RemoveAll("out"); err != nil {
t.Error(err) t.Error(err)
@ -41,6 +47,8 @@ func TestDoRandomSearchExec(t *testing.T) {
} }
func TestDoSHCExec(t *testing.T) { func TestDoSHCExec(t *testing.T) {
t.Parallel()
wg.Add(1) wg.Add(1)
go DoStochasticHillClimbing(&wg, &m) go DoStochasticHillClimbing(&wg, &m)
@ -49,6 +57,7 @@ func TestDoSHCExec(t *testing.T) {
picsDir := report.GetPicsDir() + "-test-shc" picsDir := report.GetPicsDir() + "-test-shc"
// attempt to clean up.
if err := os.RemoveAll(picsDir); err != nil { if err := os.RemoveAll(picsDir); err != nil {
t.Error(err) t.Error(err)
} }
@ -59,6 +68,7 @@ func TestDoSHCExec(t *testing.T) {
t.Error("picsDir should have already been cleaned up") t.Error("picsDir should have already been cleaned up")
} }
log.Println("pwd:", os.Getenv("PWD"))
// clean up outdir. // clean up outdir.
if err := os.RemoveAll("out"); err != nil { if err := os.RemoveAll("out"); err != nil {
t.Error(err) t.Error(err)

@ -121,6 +121,7 @@ func PlotMeanValsMulti(
// set pic file path and caption. // set pic file path and caption.
pic.FilePath = filename pic.FilePath = filename
// pic.Caption = strings.ReplaceAll(filename, " ", "~")
pic.Caption = strings.ReplaceAll( pic.Caption = strings.ReplaceAll(
fmt.Sprintf("Comparison of Means (%dI) - %s (%dD)", fmt.Sprintf("Comparison of Means (%dI) - %s (%dD)",
iterations, bench, dimens, iterations, bench, dimens,
@ -157,21 +158,27 @@ func plotMeanVals(meanVals []float64, title string, fes int) *plot.Plot {
} }
p := plot.New() p := plot.New()
// pic := report.NewPic()
p.Title.Text = "Mean - " + title p.Title.Text = "Mean - " + title
p.X.Label.Text = xAxisLabel p.X.Label.Text = xAxisLabel
// p.X.Label.Padding = 8 * vg.Millimeter
p.X.Label.TextStyle.Font.Variant = preferredFont p.X.Label.TextStyle.Font.Variant = preferredFont
p.X.Label.TextStyle.Font.Weight = 1 // Medium p.X.Label.TextStyle.Font.Weight = 1 // Medium
p.X.Tick.Label.Font.Variant = preferredFont p.X.Tick.Label.Font.Variant = preferredFont
// p.X.Padding = 2 * vg.Millimeter
p.Y.Label.Text = yAxisLabel p.Y.Label.Text = yAxisLabel
// p.Y.Label.Padding = 2 * vg.Millimeter
p.Y.Label.TextStyle.Font.Variant = preferredFont p.Y.Label.TextStyle.Font.Variant = preferredFont
p.Y.Label.TextStyle.Font.Weight = 1 // Medium p.Y.Label.TextStyle.Font.Weight = 1 // Medium
p.Y.Tick.Label.Font.Variant = preferredFont p.Y.Tick.Label.Font.Variant = preferredFont
// p.Y.Padding = 1 * vg.Millimeter
p.Title.TextStyle.Font.Size = 14.5 p.Title.TextStyle.Font.Size = 14.5
p.Title.TextStyle.Font.Variant = titlePreferredFont p.Title.TextStyle.Font.Variant = titlePreferredFont
p.Title.TextStyle.Font.Weight = 2 // SemiBold p.Title.TextStyle.Font.Weight = 2 // SemiBold
// p.Title.Padding = 5 * vg.Millimeter
p.Title.Padding = 3 * vg.Millimeter p.Title.Padding = 3 * vg.Millimeter
// mark the end of the X axis with len(meanVals). // mark the end of the X axis with len(meanVals).
@ -255,12 +262,20 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
p.Y.Label.TextStyle.Font.Variant = preferredFont p.Y.Label.TextStyle.Font.Variant = preferredFont
p.Y.Label.TextStyle.Font.Weight = 1 // Medium p.Y.Label.TextStyle.Font.Weight = 1 // Medium
p.Y.Tick.Label.Font.Variant = preferredFont p.Y.Tick.Label.Font.Variant = preferredFont
// p.Y.Padding = 1 * vg.Millimeter
p.Title.TextStyle.Font.Size = 14.5 p.Title.TextStyle.Font.Size = 14.5
p.Title.TextStyle.Font.Variant = titlePreferredFont p.Title.TextStyle.Font.Variant = titlePreferredFont
p.Title.TextStyle.Font.Weight = 2 // SemiBold p.Title.TextStyle.Font.Weight = 2 // SemiBold
// p.Title.Padding = 5 * vg.Millimeter
p.Title.Padding = 3 * vg.Millimeter p.Title.Padding = 3 * vg.Millimeter
// p.Legend.TextStyle.Font.Variant = preferredFontStyle
// p.Legend.TextStyle.Font.Size = 8
// p.Legend.Top = true
// p.Legend.Padding = 0 * vg.Centimeter
// p.Add(plotter.NewGrid())
for _, dim := range s.BenchFuncStats { for _, dim := range s.BenchFuncStats {
// infinite thanks to this SO comment for the interface "hack": // infinite thanks to this SO comment for the interface "hack":
// https://stackoverflow.com/a/44872993 // https://stackoverflow.com/a/44872993
@ -286,6 +301,7 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
pts[k].Y = res pts[k].Y = res
} }
// lines = append(lines, "#"+fmt.Sprint(j), pts)
lines = append(lines, pts) lines = append(lines, pts)
} }
@ -299,6 +315,7 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
} }
// TODO(me): add Neighbourhood param // TODO(me): add Neighbourhood param
// TODO(me): add search space percent param
filename := fmt.Sprintf("%s%s-%s-%s-%dD-%dG-%dI", filename := fmt.Sprintf("%s%s-%s-%s-%dD-%dG-%dI",
picsDir, picsDir,
fPrefix, fPrefix,
@ -333,6 +350,7 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
filename, fExt, elapsed, filename, fExt, elapsed,
) )
// TODO(me): rework this.
if s.Algo == "Random Search" { if s.Algo == "Random Search" {
printRandomSearch(info) printRandomSearch(info)
} else { } else {
@ -347,6 +365,7 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
); err != nil { ); err != nil {
panic(err) panic(err)
} }
// log.Println(filename + fExt)
// save pic. // save pic.
pics = append(pics, *pic) pics = append(pics, *pic)

@ -59,6 +59,8 @@ func selectBestNeighbour(neighbours []neighbour, benchFuncName string) ([]float6
// f is the actual bench function, based on the name. // f is the actual bench function, based on the name.
f := bench.Functions[benchFuncName] f := bench.Functions[benchFuncName]
// fmt.Println("select best\nlen(neighbours)", len(neighbours))
for i, v := range neighbours { for i, v := range neighbours {
switch i { switch i {
case 0: case 0:
@ -92,6 +94,8 @@ func getBenchSearchSpaceSize(benchName string) float64 {
// the allowedTweak value should therefore the amount to at most 10% of the // the allowedTweak value should therefore the amount to at most 10% of the
// searchSpaceSize. TODO(me): floor this down. // searchSpaceSize. TODO(me): floor this down.
func getAllowedTweak(searchSpaceSize float64) float64 { func getAllowedTweak(searchSpaceSize float64) float64 {
// TODO(me): have this passed to HillClimb and from there into this func.
// return (bench.MaxNeighbourVariancePercent * 0.5) * (searchSpaceSize * 0.01)
return bench.MaxNeighbourVariancePercent * (searchSpaceSize * 0.01) return bench.MaxNeighbourVariancePercent * (searchSpaceSize * 0.01)
} }
@ -103,7 +107,9 @@ func genNeighbours(n, dimens int, benchName string, origin []float64, neighbVals
// create a new representation of the uniform distribution with the bounds // create a new representation of the uniform distribution with the bounds
// unset for the moment, since we need to find out what exactly those ought // unset for the moment, since we need to find out what exactly those ought
// to be (and we will - a couple of lines later). // to be (and we will - a couple of lines later).
// uniform := distuv.Uniform{Src: time.Now().UnixMicro()}
uniform := distuv.Uniform{} uniform := distuv.Uniform{}
// uniform.Src.Seed(uint64(time.Now().UnixNano()))
params := bench.FunctionParams[benchName] params := bench.FunctionParams[benchName]
// get bench function bounds. // get bench function bounds.
benchMin := params.Min() benchMin := params.Min()
@ -116,6 +122,7 @@ func genNeighbours(n, dimens int, benchName string, origin []float64, neighbVals
uniform.Src = rand.NewSource(uint64(time.Now().UnixNano())) uniform.Src = rand.NewSource(uint64(time.Now().UnixNano()))
for _, v := range neighbVals { for _, v := range neighbVals {
// for _, v := range neighbVals {
for i := 0; i < dimens; i++ { for i := 0; i < dimens; i++ {
newMin := origin[i] - allowedTweak newMin := origin[i] - allowedTweak
@ -130,7 +137,9 @@ func genNeighbours(n, dimens int, benchName string, origin []float64, neighbVals
if newMin > benchMax { if newMin > benchMax {
uniform.Max = newMax uniform.Max = newMax
} }
// fmt.Println("newMin:", newMin, "newMax", newMax)
// v = append(v, uniform.Rand())
v[i] = uniform.Rand() v[i] = uniform.Rand()
} }
} }
@ -236,7 +245,7 @@ func HillClimb(
funcStats.BenchResults = make([]stats.BenchRound, minIters) funcStats.BenchResults = make([]stats.BenchRound, minIters)
// create a source of preudo-randomness. // create and seed a source of preudo-randomness
src := rand.NewSource(uint64(rand.Int63())) src := rand.NewSource(uint64(rand.Int63()))
// src := rand.NewSource(uint64(time.Now().UnixNano())) // src := rand.NewSource(uint64(time.Now().UnixNano()))
@ -249,6 +258,7 @@ func HillClimb(
// create and stochastically populate the vals slice. // create and stochastically populate the vals slice.
initVals := make([]float64, dimens) initVals := make([]float64, dimens)
// reseed using current time.
uniDist.Src = src uniDist.Src = src
var bestResult float64 var bestResult float64
@ -337,6 +347,7 @@ func HillClimb(
shcMeans.BenchMeans = append(shcMeans.BenchMeans, *dimXMean) shcMeans.BenchMeans = append(shcMeans.BenchMeans, *dimXMean)
} }
// log.Printf("%+v\n", shcMeans)
sort.Sort(shcMeans) sort.Sort(shcMeans)
// export AlgoMeans. // export AlgoMeans.

@ -29,6 +29,8 @@ var FunctionParams = map[string]funcParams{
// Schwefel computes the value of the Schwefel function for x. // Schwefel computes the value of the Schwefel function for x.
func Schwefel(x []float64) float64 { func Schwefel(x []float64) float64 {
// - Domain is | x_i | < 500
// - Global minimum at fmin = -122569.5 at x_i = 420.9687
var res float64 var res float64
for _, val := range x { for _, val := range x {

@ -20,9 +20,15 @@
}: let }: let
projname = "math-optim"; projname = "math-optim";
system.configurationRevision =
self.rev
or throw "Refusing to build from a dirty Git tree!";
nix.registry.nixpkgs.flake = nixpkgs;
# to work with older version of flakes # to work with older version of flakes
lastModifiedDate = lastModifiedDate =
self.lastModifiedDate or self.lastModified or "19700101"; self.lastModifiedDate or self.lastModified or "19700101";
# lastModifiedDate = "19700101";
# Generate a user-friendly version number. # Generate a user-friendly version number.
version = "v0.0.0"; version = "v0.0.0";
@ -57,8 +63,12 @@
pname = "${projname}"; pname = "${projname}";
buildInputs = [ buildInputs = [
go go
# gcc
# glibc
# glibc.static
]; ];
nativeBuildInputs = [pkgconfig]; nativeBuildInputs = [pkgconfig];
# nativeBuildInputs = [go glibc.static];
overrideModAttrs = _: { overrideModAttrs = _: {
# GOPROXY = "direct"; # GOPROXY = "direct";
@ -189,11 +199,22 @@
{ {
name = "${projname}-" + version; name = "${projname}-" + version;
dontAutoPatchelf = "";
GOFLAGS = "-buildmode=pie -trimpath -mod=readonly -modcacherw"; GOFLAGS = "-buildmode=pie -trimpath -mod=readonly -modcacherw";
GOLDFLAGS = "-s -w -X main.version=${version}"; GOLDFLAGS = "-s -w -X main.version=${version}";
CGO_CFLAGS = "-g0 -mtune=native"; CGO_CFLAGS = "-g0 -Ofast -mtune=native -flto";
CGO_LDFLAGS = "-Wl,-O1,-sort-common,-as-needed,-z,relro,-z,now,-flto -pthread"; CGO_LDFLAGS = "-Wl,-O1,-sort-common,-as-needed,-z,relro,-z,now,-flto -pthread";
# GOLDFLAGS = "-s -w -X main.version=${version} -linkmode external -extldflags -static";
# CGO_CFLAGS = "-g0 -mtune=native
# -I${pkgs.glibc.dev}/include
# ";
# LDFLAGS = "-L${pkgs.glibc}/lib";
# CGO_LDFLAGS = "
# -Wl,-O1,-sort-common,-as-needed,-z,relro,-z,now,-flto -pthread
# -L${pkgs.glibc}/lib
# ";
GOPROXY = "direct"; GOPROXY = "direct";
# GOMEMLIMIT = "10GiB";
shellHook = '' shellHook = ''
echo " -- in math-optim dev shell..." echo " -- in math-optim dev shell..."
@ -212,6 +233,8 @@
statix statix
alejandra alejandra
# glibc.static
## ad-hoc cmds ## ad-hoc cmds
gob gob
gota gota

@ -10,7 +10,7 @@
\section{Per-algo benchmark comparison statistics} \section{Per-algo benchmark comparison statistics}
{{ range $i, $v := .AllTables.TexFiles }} {{ range $i, $v := .AllTables.TexFiles }}
{{- range $j, $u := $v.FilePaths }} {{- range $j, $u := $v.FilePaths }}
\input{ {{- $u -}} } \input{ {{- printf "{%s}" $u -}} }
\newpage \newpage
{{- end -}} {{- end -}}
{{ end }} {{ end }}

@ -64,7 +64,7 @@ func NewPicList() *PicList {
// SavePicsToFile saves each pic list for all bench funcs of a specified algo // SavePicsToFile saves each pic list for all bench funcs of a specified algo
// to a file. // to a file.
func SavePicsToFile(pls, plsMean []PicList, algoName string) { func SavePicsToFile(pls, plsMean []PicList, algoName string) {
var paths []string paths := make([]string, 0, len(pls))
ptf := picTexFiles{Algo: algoName} ptf := picTexFiles{Algo: algoName}

@ -19,8 +19,10 @@
{\includegraphics[scale=0.45]{ {{- printf "%s" $v.FilePath -}} }} {\includegraphics[scale=0.45]{ {{- printf "%s" $v.FilePath -}} }}
\caption{ {{- printf "\\scriptsize{%s}" $v.Caption -}} } \caption{ {{- printf "\\scriptsize{%s}" $v.Caption -}} }
\end{subfigure} \end{subfigure}
% \hspace{1.3em}
\hfill \hfill
{{- end -}} {{- end -}}
% \newline
{{ range $k, $w := .PicsMean }} {{ range $k, $w := .PicsMean }}
\begin{subfigure}{0.30\textwidth} \begin{subfigure}{0.30\textwidth}
\vspace{2em} \vspace{2em}
@ -29,6 +31,7 @@
{\includegraphics[scale=0.45]{ {{- printf "%s" $w.FilePath -}} }} {\includegraphics[scale=0.45]{ {{- printf "%s" $w.FilePath -}} }}
\caption{ {{- printf "\\scriptsize{%s}" $w.Caption -}} } \caption{ {{- printf "\\scriptsize{%s}" $w.Caption -}} }
\end{subfigure} \end{subfigure}
% \hspace{1.3em}
\hfill \hfill
{{- end }} {{- end }}
\caption{ {{- printf "%s - %s" .Algo .Bench -}} } \caption{ {{- printf "%s - %s" .Algo .Bench -}} }

@ -28,6 +28,10 @@ var (
tmplReportFile []byte tmplReportFile []byte
) )
func GetOutPrefix() string {
return outPrefix
}
// GetPicsDirPrefix returns the path to the folder meant for tex files. // GetPicsDirPrefix returns the path to the folder meant for tex files.
func GetTexDir() string { func GetTexDir() string {
return outPrefix + texDir return outPrefix + texDir

@ -7,11 +7,14 @@
left=12mm, left=12mm,
right=12mm, right=12mm,
} }
% \usepackage{lmodern}
\usepackage[utf8]{inputenc} \usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} \usepackage[T1]{fontenc}
\usepackage[fleqn]{amsmath} \usepackage[fleqn]{amsmath}
\usepackage{amssymb} \usepackage{amssymb}
\usepackage{amsfonts} \usepackage{amsfonts}
% \usepackage{fontspec}
% \usefonttheme[onlymath]{serif}
\usepackage{multirow} \usepackage{multirow}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{textcomp} \usepackage{textcomp}
@ -24,6 +27,7 @@
% inkscapelatex=false is important to not have jumbled plot labels as a result of latex trying to render plot/axis labels with the default latex fonts. % inkscapelatex=false is important to not have jumbled plot labels as a result of latex trying to render plot/axis labels with the default latex fonts.
\svgsetup{inkscapelatex=false,clean=true,inkscapepath=svgsubdir} \svgsetup{inkscapelatex=false,clean=true,inkscapepath=svgsubdir}
\pdfsuppresswarningpagegroup=1 % pdflatex complains svg-turned-pdf files \pdfsuppresswarningpagegroup=1 % pdflatex complains svg-turned-pdf files
\pdfinclusioncopyfonts=1
\usepackage{meta} \usepackage{meta}
\usepackage[affil-it]{authblk} \usepackage[affil-it]{authblk}

@ -10,6 +10,7 @@
\subsection{ {{- .Algo -}} } \subsection{ {{- .Algo -}} }
\begin{table}[!htb] \begin{table}[!htb]
% \begin{tabular}[t]{ |l|{{- range $i, $v := .ColLayout }}{{$v}}| {{- end}} }
\resizebox{\columnwidth}{!}{\begin{tabular}[t]{r||{{- range $i, $v := .ColLayout }}{{$v}}| {{- end -}} } \resizebox{\columnwidth}{!}{\begin{tabular}[t]{r||{{- range $i, $v := .ColLayout }}{{$v}}| {{- end -}} }
\textbf{params} & {{ range $i, $v := .ColNames }}{{ printf "\\textbf{%s}" $v }} & {{ end}}\\ \textbf{params} & {{ range $i, $v := .ColNames }}{{ printf "\\textbf{%s}" $v }} & {{ end}}\\
{{- range $j, $v := .Rs }} {{- range $j, $v := .Rs }}

2
run.go

@ -19,6 +19,7 @@ func run() {
doPrint := flag.Bool("printreport", true, "print report.tex to console") doPrint := flag.Bool("printreport", true, "print report.tex to console")
generate := flag.Bool("generate", true, "run algos and generate plot pics/statistical tables (anew)") generate := flag.Bool("generate", true, "run algos and generate plot pics/statistical tables (anew)")
// TODO(me): add flag for plot output format: -plotout=(svg,eps,pdf)
flag.Parse() flag.Parse()
if *generate { if *generate {
@ -33,6 +34,7 @@ func run() {
go algo.DoRandomSearch(&wg, &m) go algo.DoRandomSearch(&wg, &m)
go algo.DoStochasticHillClimbing(&wg, &m) go algo.DoStochasticHillClimbing(&wg, &m)
// go algo.DoStochasticHillClimbing100Neigh(&wg, &m)
wg.Wait() wg.Wait()