Skip to content

Instantly share code, notes, and snippets.

@humamfauzi
Created August 13, 2018 09:53
Show Gist options
  • Save humamfauzi/7767a95c3c8ee311eadcd1f4bd4d397d to your computer and use it in GitHub Desktop.
Save humamfauzi/7767a95c3c8ee311eadcd1f4bd4d397d to your computer and use it in GitHub Desktop.
Creating a Random Choice with weight in Golang
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func main() {
rand.Seed(time.Now().Unix()) // Seeding for pseudo random
cat1 := []string{"Hello", "World"}
wt1 := []float32{0.9,0.1}
result := randomChoice(1 << 23, cat1, wt1) //Creating array with len 2^23
countString(cat1, result)
}
func randomChoice(size int, choice []string, weight []float32) []string{
// max number can varies, higher number will yield better result but longer computation time
// i find 2^8 is quite satisfying
var wg sync.WaitGroup
max := 1 << 8
// Creating a pool which we later draw upon
pp:= make([]string, max)
weightSize := make([]int, len(weight))
for i := 0; i < len(weight); i++ {
weightSize[i] = int(weight[i] * float32(max)) + 1
}
wg.Add(max)
categoryAppend := 0
go func() {
for i := 0; i < max; i++ {
pp[i] = choice[categoryAppend]
weightSize[categoryAppend]--
wg.Done()
if weightSize[categoryAppend] == 0 {
categoryAppend++
}
}
}()
wg.Wait()
// drawing from the pool we just makes
result := make([]string, size)
for i := 0; i < size; i++ {
result[i] = pp[rand.Intn(max)]
}
return result
}
func countString(choice []string, array []string) {
var wg sync.WaitGroup
countCat := make(map[string]int)
for _,v := range choice {
countCat[v] = 0
}
wg.Add(len(array))
go func() {
for i := 0; i < len(array); i++ {
for _, v := range choice {
if v == array[i]{
countCat[v]++
}
}
wg.Done()
}
}()
wg.Wait()
// verifying our random generated choice based on weight
for k, v := range countCat {
fmt.Println(k, "::", v, ":: RATIO", float32(v)/float32(len(array)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment