C# 随机数中的唯一数?

C# 随机数中的唯一数?,c#,C#,我知道网上有很多关于它的问题,但我想知道为什么我的方法失败了 我做错了什么 public class Generator { private static readonly Random random = new Random(); private static readonly object SyncLock = new object(); public static int GetRandomNumber(int min, int max) {

我知道网上有很多关于它的问题,但我想知道为什么我的方法失败了 我做错了什么

public class Generator
{

    private static readonly Random random = new Random();

    private static readonly object SyncLock = new object();

    public static int GetRandomNumber(int min, int max)
    {
        lock (SyncLock)
        { 
            return random.Next(min, max);
        }
    }

}


[TestFixture]
public class Class1
{
    [Test]
    public void SimpleTest()
    {

        var numbers=new List<int>();
        for (int i = 1; i < 10000; i++)
        {
            var random = Generator.GetRandomNumber(1,10000);
            numbers.Add(random);
        }

        CollectionAssert.AllItemsAreUnique(numbers);

    }
}
公共类生成器
{
私有静态只读随机=新随机();
私有静态只读对象SyncLock=新对象();
公共静态整数GetRandomNumber(整数最小值,整数最大值)
{
锁定(同步锁定)
{ 
返回random.Next(最小值、最大值);
}
}
}
[测试夹具]
公共班级1
{
[测试]
public-void-SimpleTest()
{
变量编号=新列表();
对于(int i=1;i<10000;i++)
{
var random=生成器。GetRandomNumber(110000);
数字。添加(随机);
}
收集资产联合资产(数字);
}
}
编辑 测试方法失败!!对不起,没提


感谢您的时间和建议

除非您非常幸运,否则您怎么可能期望一组10000个可能值中的10000个随机数序列都是唯一的?你所期待的是错误的

掷硬币两次。你真的认为TH和HT是唯一可能的序列吗

是什么让你认为随机数的工作方式应该有所不同

随机数生成器的此输出是可能的:

1, 1, 1, 1, 1, 1, ..., 1
这就是:

1, 2, 3, 4, 5, 6, ..., 10000
事实上,这两个序列的可能性相同

随机!=独特的

这里的要点是,您的代码应该为您的问题建模,而您的代码实际上并没有。随机不等于唯一。如果您想要唯一,您需要获取您的值集并将其洗牌


如果你真的想要随机数,你不能期望它们是唯一的。如果您的(P)RNG提供了一个均匀分布,那么在许多试验中,您应该会看到每个值的类似计数(请参阅)。案例可能会显示为“错误”,但您不能忽视您偶然碰到的案例。

您似乎误解了
Random
类生成了一系列唯一但显然是随机的数字。事实并非如此;随机性意味着下一个数字可能是任何可能的选择,而不仅仅是我以前见过的任何一个


在这种情况下,您的测试失败也就不足为奇了:10000个随机生成的整数(介于1和10000之间)唯一的概率很小。

我想您没有提到您的
测试方法失败了

它失败是因为您的随机生成器没有生成唯一的数字。我不确定它在当前条件下会是什么样子。

公共静态void FisherYatesShuffle(T[]数组)
public static void FisherYatesShuffle<T>(T[] array)
{
    Random r = new Random();
    for (int i = array.Length - 1; i > 0; i--)
    {
        int j = r.Next(0, i + 1);
        T temp = array[j];
        array[j] = array[i];
        array[i] = temp;
    }
}

int[] array = new int[10000];

for (int i = 0; i < array.Length; i++) array[i] = i;
FisherYatesShuffle(array);
{ 随机r=新随机(); 对于(int i=array.Length-1;i>0;i--) { int j=r.Next(0,i+1); T温度=阵列[j]; 数组[j]=数组[i]; 数组[i]=温度; } } int[]数组=新int[10000]; 对于(inti=0;i
@Boo当你的评论突然出现时,我吓了一跳…:最近涌入的大量漫不经心的问题。你是在寻找某种洗牌算法,让你随机重新分配1-10000个数字吗?@TimSchmelter:Whah?他发布了代码,并说基本上“它不起作用”。正是这些令人敬畏的人费心解释和回答“问题”,才使得答案如此之好。这与这个问题的质量无关。@TimSchmelter:OP声称“方法失败”,但没有具体说明失败的方法和方式。如果他们说测试失败或者断言被触发,或者是一些准确描述失败的东西,那么我会同意你的说法。但是除了“方法”之外,没有对失败的描述,我统计了OP拥有的两个和他们不拥有的6个-其中任何一个都可能是“失败的”。行
1..10000
包含10k唯一数字。为什么不可能?我说“除非你非常幸运。”@zerkms-同意。并非不可能。但是你可以相当自信,如果你在整个宇宙的生命周期中每秒运行一次这个程序,你就永远不会得到一个没有副本的集合。这是一个关于生日问题的变体:@完美主义者,杰森:哦,我错过了“除非你非常幸运”part@Jason.你是对的,我不能详细介绍项目的所有细节,但我需要生成1到10000之间的唯一数字。-可以在O(N)中生成1n个唯一数字。OrderBy将在O(n*log(n))
Guid
s中运行,保证是唯一的,但不能保证它们生成的值足以洗牌序列。如果是你想要的洗牌,使用洗牌算法。讽刺的是,你的答案违反了你第一句话中陈述的原则。杰森是对的。guid是唯一性的来源,而不是随机性的来源。没有任何保证你不会得到一万个已经按顺序排序的guid;事实上,有一些版本的guid生成算法正是这样做的。是的,测试失败了,我想让它通过,以证明我可以唯一地生成随机数。然后,您需要更新代码以生成该结果。现在看来,测试失败是一个正确的结果。好的。我想更新代码以产生结果,但我似乎找不到方法。尝试搜索@user231465只是为了能够洗牌任何类型的数组,而不仅仅是整数数组