Home > Backend Development > Golang > How to randomly select an item from a slice that is biased toward one end of the slice using Go?

How to randomly select an item from a slice that is biased toward one end of the slice using Go?

王林
Release: 2024-02-05 23:12:12
forward
1040 people have browsed it

如何使用 Go 从切片中随机选择一个偏向切片一端的项目?

Question content

I know a way to select random values ​​from slice in go

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

But how do I select a random item from slice and bias it to one end of slice? For my use case, I will have a slice that grows over time using append(). My understanding is that the newest item will be added to the right of slice. I want to create a function that selects a random item from slice and favors the newest member of slice. My first guess would be to use the normal distribution via rand.normfloat64() but I'm not sure how or if I can use it to achieve this.

This function should be able to pick any item from slice, but should pick new items added to slice with greater frequency.


Correct Answer


Assuming you are satisfied with a normal distribution, you can use rand.normfloat64(). If your array has 20 items:

int(math.abs(rand.normfloat64())*10) % 20
Copy after login

will generate numbers weighted towards the beginning of the list. and

20 - int(math.abs(rand.normfloat64())*10) % 20
Copy after login

will generate numbers weighted towards the end of the list.

This is an example demonstrating the random distribution of samples. Mobile playground: https://www.php.cn/link/34ff028fc02b773b8885b59aee142e60

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)
}
Copy after login

Example output:

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

It's randomized though, so you can still get all the tail items...

If you want a step function where the number in the first half is 10 times the number in the left half, just use two random numbers.

n := rand.intn(10)
if rand.float64() < 0.1 {
    n = n + 10
}
Copy after login

go playground example: https://www.php.cn/link/d5c82d99f0edb85fc94ffa4204146aad

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)
}
Copy after login

Example output

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

The above is the detailed content of How to randomly select an item from a slice that is biased toward one end of the slice using Go?. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template