你可以使用Go语言来从一个切片中选择一个具有偏向于切片一端的随机项。

huangapple go评论93阅读模式
英文:

How could I pick a random item from a slice with bias towards one end of the slice using Go?

问题

我理解你想要从一个slice中以某种方式随机选择一个值的方法。以下是代码示例:

rand.Seed(time.Now().UTC().UnixNano())

var db [500]string
log.Println(db[rand.Intn(len(db))])

但是,如果我想要从slice中以偏向于某一端的方式选择一个随机项,该怎么办呢?根据我的使用情况,我会使用append()函数不断向slice中添加新的项。我希望创建一个函数,从slice中随机选择一个项,偏向于最新添加的项。我最初的想法是使用正态分布,通过rand.NormFloat64()来实现,但我不确定如何使用它来达到这个目的。

这个函数应该能够从slice中选择任何项,但是应该更频繁地选择新添加的项。

英文:

I understand one way to pick a random value from a slice in Go:

rand.Seed(time.Now().UTC().UnixNano())     
                                                
var db [500]string                         
log.Println(db[rand.Intn(len(db))])        

But how would I pick a random item from the slice, with a bias towards one end of the slice? For my use case I'll have a slice that grows over time using append(). My understanding is that the newest items will be added to the right-hand side of the slice. I'd like to create a function that picks a random item from the slice, with bias towards the newest members of the slice. My first guess is to use a normal distribution via rand.NormFloat64(), but I'm not sure how or if I can use it to achieve this.

The function should be capable of picking any item from the slice, but should pick new items added to the slice at a much higher frequency.

答案1

得分: 1

假设你对正态分布满意,你可以使用rand.Normfloat64()函数。如果你的数组有20个元素:

int(math.Abs(rand.NormFloat64())*10) % 20

将生成偏向列表开头的数字。而

20 - int(math.Abs(rand.NormFloat64())*10) % 20

将生成偏向列表末尾的数字。

下面是一个演示随机分布的示例。在Go Playground上查看:https://go.dev/play/p/AwEPEzQO7P8

package main

import (
    "fmt"
    "math"
    "math/rand"
)

func main() {
    var buckets [20]int
    for i := 0; i < 1000; i++ {
        r := int(math.Abs(rand.NormFloat64())*10) % 20
        buckets[r]++
    }
    fmt.Println(buckets)
}

示例输出:

[86 92 76 80 73 69 60 69 58 51 47 38 44 30 29 24 19 27 18 10]

不过这是随机的,所以你仍然可能得到全部末尾项...

如果你想要一个步进函数,其中前半部分的数字是后半部分的10倍,只需使用两个随机数。

n := rand.Intn(10)
if rand.Float64() < 0.1 {
    n = n + 10
}

在Go Playground上查看示例:https://go.dev/play/p/CitUsHmwQez

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    var buckets [20]int
    for i := 0; i < 1000; i++ {
        r := rand.Intn(10)
        if rand.Float64() < 0.1 {
            r = r + 10
        }
        buckets[r]++
    }
    fmt.Println(buckets)
}

示例输出:

[96 92 89 89 88 78 95 86 83 98 15 10 15 10 10 12 4 11 11 8]

英文:

Assuming you're happy with the normal distribution, you can use rand.Normfloat64(). If your array has 20 items:

int(math.Abs(rand.NormFloat64())*10) % 20

Will produce numbers that are weighted toward the start of the list. And

20 - int(math.Abs(rand.NormFloat64())*10) % 20

Will produce numbers that are weighted toward the end of the list.

Here's an example that demonstrates a sample random distribution.
On go playground: https://go.dev/play/p/AwEPEzQO7P8

package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
	&quot;math/rand&quot;
)
func main() {
	var buckets [20]int
	for i := 0; i &lt; 1000; i++ {
		r := int(math.Abs(rand.NormFloat64())*10) % 20
		buckets[r]++
	}
	fmt.Println(buckets)
}

Sample output:

[86 92 76 80 73 69 60 69 58 51 47 38 44 30 29 24 19 27 18 10]

It's random though, so you could still get all tail end items ....

If you want a step function where the numbers of the first half are 10x the numbers of the left, just use two rands.

n := rand.Intn(10)
if rand.Float64() &lt; 0.1 {
    n = n + 10
}

Example on go playground: https://go.dev/play/p/CitUsHmwQez

package main

import (
	&quot;fmt&quot;
	&quot;math/rand&quot;
)

func main() {
	var buckets [20]int
	for i := 0; i &lt; 1000; i++ {
		r := rand.Intn(10)
		if rand.Float64() &lt; 0.1 {
			r = r + 10
		}
		buckets[r]++
	}
	fmt.Println(buckets)
}

Sample output

[96 92 89 89 88 78 95 86 83 98 15 10 15 10 10 12 4 11 11 8]

huangapple
  • 本文由 发表于 2023年2月14日 22:58:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75449641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定