Algorithm to randomize output order of a short array in Go

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

Algorithm to randomize output order of a short array in Go

问题

这个问题与许多重复答案的关键区别在于,输入数组很短,只有3个元素。

假设我有一个有序的整数集合。数组的大小只有3个(或稍多一些)。我需要随机化它们的顺序并返回一个新的数组。虽然这是一个纯粹的算法问题,但首选的答案语言是Go。

使用Python,答案是random.shuffle。参考链接:https://stackoverflow.com/questions/71937148/how-can-i-output-a-list-in-random-order

使用Go,答案应该是rand.Shuffle。参考链接:https://yourbasic.org/golang/shuffle-slice-array/

然而,这是我的代码:

func randShuffle(a []int) {
    rand.Seed(time.Now().UnixNano())
    rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
}

这是我的一个测试运行结果:

[2 1 3]
[1 3 2]
[2 1 3]
[2 1 3]
[1 3 2]
[1 2 3]
[2 3 1]

看起来并不是非常随机。

有没有好的方法来对一个只有3个元素的数组进行更好的随机化?

另外,

英文:

The key difference between this question and the lots of duplicated answers is that, the input array is short, only 3 elements. --

Say I have an ordered set of int. The size of array is only 3 (or a bit more). I need to randomize their order and return a new array. Although it is a pure algorithm question, but the prefered answer language is in Go.

However, this is my code:

https://go.dev/play/p/CVu8_Q96-9F

func randShuffle(a []int) {
	rand.Seed(time.Now().UnixNano())
	rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
}

And this is one of my test run result:

[2 1 3]
[1 3 2]
[2 1 3]
[2 1 3]
[1 3 2]
[1 2 3]
[2 3 1]

which doesn't seems to be very randomized.

Any good idea to have a better randomization for a short 3-elements array?

BTW,

答案1

得分: 1

random.Seed从你的洗牌函数移动到主函数中。对 PRNG 的种子进行播种应该在程序中只执行一次,成功模拟随机性是通过生成器的状态转换而不是种子来实现的。除非你真正理解 PRNG 的工作原理并且试图明确控制过程以实现可重现性等原因,否则不要重新播种。

以下是你的代码的简单修改,可以满足你的需求:

package main

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

func main() {
	rand.Seed(time.Now().UnixNano())

	a := []int{1, 2, 3}
	for i := 0; i < 10; i++ {
		randShuffle(a)
		fmt.Println(a)
	}
}

func randShuffle(a []int) {
	rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
}

这将产生如下结果:

[2 3 1]
[3 1 2]
[2 1 3]
[2 3 1]
[1 2 3]
[1 3 2]
[1 2 3]
[3 1 2]
[3 2 1]
[2 3 1]
英文:

Move random.Seed from your shuffle function to the main. Seeding of a PRNG should only be done once per program, the successful mimicry of randomness is done by the state transitions of the generator rather than by the seed. Don't re-seed unless you really understand how PRNGs work and are trying to explicitly control the process for reasons such as reproducibility.

The following straightforward modification of your code should meet your needs:

package main

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

func main() {
	rand.Seed(time.Now().UnixNano())

	a := []int{1, 2, 3}
	for i := 0; i &lt; 10; i++ {
		randShuffle(a)
		fmt.Println(a)
	}
}

func randShuffle(a []int) {
	rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
}

This produces results such as:

[2 3 1]
[3 1 2]
[2 1 3]
[2 3 1]
[1 2 3]
[1 3 2]
[1 2 3]
[3 1 2]
[3 2 1]
[2 3 1]

huangapple
  • 本文由 发表于 2023年3月30日 21:56:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75889198.html
匿名

发表评论

匿名网友

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

确定