Trình tạo số ngẫu nhiên chỉ tạo ra một số ngẫu nhiên

779
Ivan Prodanov 2009-04-21 02:11.

Tôi có chức năng sau:

//Function to get random number
public static int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

Cách tôi gọi nó:

byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
    mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

Nếu tôi bước vòng lặp đó với trình gỡ lỗi trong thời gian chạy, tôi nhận được các giá trị khác nhau (đó là những gì tôi muốn). Tuy nhiên, nếu tôi đặt một điểm ngắt hai dòng bên dưới mã đó, tất cả các thành viên của macmảng có giá trị bằng nhau.

Tại sao điều đó xảy ra?

9 answers

1067
Marc Gravell 2009-04-21 02:12.

Mỗi lần bạn làm điều new Random()đó được khởi tạo bằng đồng hồ. Điều này có nghĩa là trong một vòng lặp chặt chẽ, bạn sẽ nhận được cùng một giá trị nhiều lần. Bạn nên giữ một phiên bản Ngẫu nhiên duy nhất và tiếp tục sử dụng Next trên cùng một phiên bản.

//Function to get a random number 
private static readonly Random random = new Random(); 
private static readonly object syncLock = new object(); 
public static int RandomNumber(int min, int max)
{
    lock(syncLock) { // synchronize
        return random.Next(min, max);
    }
}

Chỉnh sửa (xem bình luận): tại sao chúng ta cần một lockở đây?

Về cơ bản, Nextsẽ thay đổi trạng thái bên trong của Randomphiên bản. Nếu chúng tôi làm điều đó cùng một lúc từ nhiều chuỗi, bạn có thể tranh luận "chúng tôi vừa làm cho kết quả trở nên ngẫu nhiên hơn", nhưng những gì chúng tôi đang làm thực sự có khả năng phá vỡ việc triển khai nội bộ và chúng tôi cũng có thể bắt đầu nhận được những con số tương tự từ các chủ đề khác nhau, có thể là một vấn đề - và có thể không. Tuy nhiên, việc đảm bảo những gì xảy ra bên trong là vấn đề lớn hơn; kể từ khi Randomnào không thực hiện bất kỳ sự bảo đảm của thread-an toàn. Do đó, có hai cách tiếp cận hợp lệ:

  • Đồng bộ hóa để chúng tôi không truy cập nó cùng lúc từ các chuỗi khác nhau
  • Sử dụng các Randomphiên bản khác nhau cho mỗi chuỗi

Hoặc có thể là tốt; nhưng việc tắt tiếng một trường hợp đơn lẻ từ nhiều người gọi cùng một lúc chỉ gây rắc rối.

Phương pháp lockđạt được kết quả đầu tiên (và đơn giản hơn) trong các cách tiếp cận này; tuy nhiên, một cách tiếp cận khác có thể là:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

đây là mỗi luồng, vì vậy bạn không cần phải đồng bộ hóa.

122
Phil 2012-07-14 05:25.

Để dễ dàng sử dụng lại trong ứng dụng của bạn, một lớp tĩnh có thể hữu ích.

public static class StaticRandom
{
    private static int seed;

    private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random>
        (() => new Random(Interlocked.Increment(ref seed)));

    static StaticRandom()
    {
        seed = Environment.TickCount;
    }

    public static Random Instance { get { return threadLocal.Value; } }
}

Bạn có thể sử dụng sau đó sử dụng phiên bản ngẫu nhiên tĩnh với mã như

StaticRandom.Instance.Next(1, 100);
64
Hans Malherbe 2009-06-24 01:26.

Giải pháp của Mark có thể khá tốn kém vì nó cần phải đồng bộ hóa mọi lúc.

Chúng ta có thể giải quyết nhu cầu đồng bộ hóa bằng cách sử dụng mẫu lưu trữ dành riêng cho chuỗi:


public class RandomNumber : IRandomNumber
{
    private static readonly Random Global = new Random();
    [ThreadStatic] private static Random _local;

    public int Next(int max)
    {
        var localBuffer = _local;
        if (localBuffer == null) 
        {
            int seed;
            lock(Global) seed = Global.Next();
            localBuffer = new Random(seed);
            _local = localBuffer;
        }
        return localBuffer.Next(max);
    }
}

Đo lường hai cách triển khai và bạn sẽ thấy sự khác biệt đáng kể.

41
nawfal 2013-04-01 02:34.

Câu trả lời của tôi từ đây :

Chỉ cần nhắc lại giải pháp phù hợp :

namespace mySpace
{
    public static class Util
    {
        private static rnd = new Random();
        public static int GetRandom()
        {
            return rnd.Next();
        }
    }
}

Vì vậy, bạn có thể gọi:

var i = Util.GetRandom();

tất cả đã qua.

Nếu bạn thực sự cần một phương thức tĩnh không trạng thái thực sự để tạo số ngẫu nhiên, bạn có thể dựa vào a Guid.

public static class Util
{
    public static int GetRandom()
    {
        return Guid.NewGuid().GetHashCode();
    }
}

Nó sẽ chậm hơn một chút, nhưng có thể ngẫu nhiên hơn nhiều so với Random.Nextkinh nghiệm của tôi.

Nhưng không phải :

new Random(Guid.NewGuid().GetHashCode()).Next();

Việc tạo đối tượng không cần thiết sẽ làm cho nó chậm hơn, đặc biệt là trong vòng lặp.

không bao giờ :

new Random().Next();

Không chỉ chậm hơn (bên trong một vòng lặp), tính ngẫu nhiên của nó ... theo tôi cũng không thực sự tốt ..

29
fARcRY 2009-04-21 02:25.

Tôi muốn sử dụng lớp sau để tạo số ngẫu nhiên:

byte[] random;
System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
prov.GetBytes(random);
18
sabiland 2009-04-21 02:37.

1) Như Marc Gravell đã nói, hãy thử sử dụng MỘT trình tạo ngẫu nhiên. Thật tuyệt khi thêm cái này vào hàm tạo: System.Enosystem.TickCount.

2) Một mẹo. Giả sử bạn muốn tạo 100 đối tượng và giả sử mỗi đối tượng phải có bộ tạo ngẫu nhiên của riêng nó (tiện dụng nếu bạn tính toán TẢI của các số ngẫu nhiên trong một khoảng thời gian rất ngắn). Nếu bạn làm điều này trong một vòng lặp (tạo 100 đối tượng), bạn có thể làm như vậy (để đảm bảo hoàn toàn ngẫu nhiên):

int inMyRandSeed;

for(int i=0;i<100;i++)
{
   inMyRandSeed = System.Environment.TickCount + i;
   .
   .
   .
   myNewObject = new MyNewObject(inMyRandSeed);  
   .
   .
   .
}

// Usage: Random m_rndGen = new Random(inMyRandSeed);

Chúc mừng.

7
Joma 2018-10-20 06:06.

Mỗi khi bạn thực hiện

Random random = new Random (15);

Không quan trọng nếu bạn thực hiện nó hàng triệu lần, bạn sẽ luôn sử dụng cùng một hạt giống.

Nếu bạn dùng

Random random = new Random ();

Bạn nhận được dãy số ngẫu nhiên khác nhau, nếu một hacker đoán được hạt giống và thuật toán của bạn có liên quan đến bảo mật của hệ thống - thì thuật toán của bạn đã bị hỏng. Tôi bạn thực hiện mult. Trong hàm tạo này, hạt giống được chỉ định bởi đồng hồ hệ thống và nếu một số trường hợp được tạo trong một khoảng thời gian rất ngắn (mili giây) thì có thể chúng có cùng một hạt giống.

Nếu bạn cần số ngẫu nhiên an toàn, bạn phải sử dụng lớp

System.Security.Cryptography.RNGCryptoServiceProvider

public static int Next(int min, int max)
{
    if(min >= max)
    {
        throw new ArgumentException("Min value is greater or equals than Max value.");
    }
    byte[] intBytes = new byte[4];
    using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
    {
        rng.GetNonZeroBytes(intBytes);
    }
    return  min +  Math.Abs(BitConverter.ToInt32(intBytes, 0)) % (max - min + 1);
}

Sử dụng:

int randomNumber = Next(1,100);
0
Paolo Barone 2020-08-31 19:06.

Tôi đã giải quyết vấn đề bằng cách sử dụng hàm Rnd ():

Function RollD6() As UInteger
        RollD6 = (Math.Floor(6 * Rnd())) + 1
        Return RollD6
End Function

Khi biểu mẫu tải, tôi sử dụng phương thức Randomize () để đảm bảo rằng tôi không phải lúc nào cũng nhận được cùng một dãy số ngẫu nhiên từ lần chạy này đến lần chạy khác.

0
Deependra Kushwah 2020-10-01 16:16.

Luôn nhận được một số ngẫu nhiên dương.

 var nexnumber = Guid.NewGuid().GetHashCode();
        if (nexnumber < 0)
        {
            nexnumber *= -1;
        }

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Tận dụng lợi thế của việc bán hàng nhân Ngày của Cha này

Tận dụng lợi thế của việc bán hàng nhân Ngày của Cha này

Màn hình Samsung Galaxy S9 Plus. Chủ nhật này là Ngày của Cha⁠ — trong trường hợp nó khiến bạn suy nghĩ — và thay vì mua cho anh ấy một chiếc cà vạt trong năm nay, có lẽ đã đến lúc bạn mua cho anh ấy thứ mà anh ấy sẽ thực sự sử dụng.

Assassin's Creed Snuck Into Monster Hunter: World Last Night

Assassin's Creed Snuck Into Monster Hunter: World Last Night

Monster Hunter: World yêu thích các sự kiện chéo. Dù có nghĩa là hóa trang thành Dante của Devil May Cry, giả dạng Horizon: Zero Dawn's Aloy, hay chiến đấu với quái vật Final Fantasy, các nhiệm vụ sự kiện khác nhau của Thế giới được nâng cấp tự do so với các trò chơi khác.

Ava DuVernay Có Quà Tặng Ngày Của Mẹ cho Tất Cả Chúng Ta: Nếp Nhăn Thời Gian Sẽ Được Viết Lại Vào Cuối Tuần Ngày Của Mẹ!

Ava DuVernay Có Quà Tặng Ngày Của Mẹ cho Tất Cả Chúng Ta: Nếp Nhăn Thời Gian Sẽ Được Viết Lại Vào Cuối Tuần Ngày Của Mẹ!

Storm Reid, Oprah Winfrey, Mindy Kaling, Reese Witherspoon và Ava DuVernay tại buổi chiếu đặc biệt của A Wrinkle in Time tại Nhà hát Walter Reade ở Thành phố New York vào ngày 7 tháng 3 năm 2018 “Ava rất mong được nói chuyện với bạn,” một trong những người của Array dư luận viên nói qua điện thoại. (Array là tập thể phân phối, nghệ thuật và vận động chính sách của Ava DuVernay tập trung vào các bộ phim của người da màu và phụ nữ.

Nhiệm vụ bất khả thi 5 sẽ khôi phục niềm tin của bạn trong phim hành động Tentpole

Nhiệm vụ bất khả thi 5 sẽ khôi phục niềm tin của bạn trong phim hành động Tentpole

Mission Impossible: Rogue Nation bắt đầu ở một cấp độ khác. Theo nghĩa đen.

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

McCain, người đang làm việc cho một album mới, lần đầu tiên bước vào vòng kết nối vào tối thứ Sáu ở Nashville

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Tôi viết như thế nào

Tôi viết như thế nào

Đối với tôi, mọi thứ là về dòng đầu tiên đó và nó sẽ đưa bạn đến đâu. Một số nhà văn bị điều khiển bởi cốt truyện, sự sắp xếp tinh tế của các quân cờ, trong khi những người khác bị lôi cuốn bởi một nhân vật và khả năng thực hiện một cuộc hành trình với một người bạn hư cấu mới.

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Language