Random.Sample 方法

定義

傳回 0.0 和 1.0 之間的隨機浮點數。

protected:
 virtual double Sample();
protected virtual double Sample ();
abstract member Sample : unit -> double
override this.Sample : unit -> double
Protected Overridable Function Sample () As Double

傳回

雙精確度浮點數大於或等於 0.0,且小於 1.0。

範例

下列範例衍生類別, Random 並覆寫 Sample 方法來產生亂數的分佈。 此分佈與基類方法所產生的 Sample 統一分佈不同。

using namespace System;

// This derived class converts the uniformly distributed random 
// numbers generated by base.Sample() to another distribution.
public ref class RandomProportional : Random
{
    // The Sample method generates a distribution proportional to the value 
    // of the random numbers, in the range [0.0, 1.0].
protected:
   virtual double Sample() override
   {
       return Math::Sqrt(Random::Sample());
   }

public:
   RandomProportional()
   {}
   
   virtual int Next() override
   {
      return (int) (Sample() * Int32::MaxValue);
   }   
};

int main(array<System::String ^> ^args)
{
      const int rows = 4, cols = 6;
      const int runCount = 1000000;
      const int distGroupCount = 10;
      const double intGroupSize = 
         ((double) Int32::MaxValue + 1.0) / (double)distGroupCount;

      RandomProportional ^randObj = gcnew RandomProportional();

      array<int>^ intCounts = gcnew array<int>(distGroupCount);
      array<int>^ realCounts = gcnew array<int>(distGroupCount);

      Console::WriteLine(
         "\nThe derived RandomProportional class overrides " +
         "the Sample method to \ngenerate random numbers " +
         "in the range [0.0, 1.0]. The distribution \nof " +
         "the numbers is proportional to their numeric values. " +
         "For example, \nnumbers are generated in the " +
         "vicinity of 0.75 with three times the \n" +
         "probability of those generated near 0.25.");
      Console::WriteLine(
         "\nRandom doubles generated with the NextDouble() " +
         "method:\n");

      // Generate and display [rows * cols] random doubles.
      for (int i = 0; i < rows; i++)
      {
         for (int j = 0; j < cols; j++) 
               Console::Write("{0,12:F8}", randObj->NextDouble());
         Console::WriteLine();
      }

      Console::WriteLine(
         "\nRandom integers generated with the Next() " +
         "method:\n");

      // Generate and display [rows * cols] random integers.
      for (int i = 0; i < rows; i++)
      {
         for (int j = 0; j < cols; j++)
               Console::Write("{0,12}", randObj->Next());
         Console::WriteLine();
      }

      Console::WriteLine(
         "\nTo demonstrate the proportional distribution, " +
         "{0:N0} random \nintegers and doubles are grouped " +
         "into {1} equal value ranges. This \n" +
         "is the count of values in each range:\n",
         runCount, distGroupCount);
      Console::WriteLine(
         "{0,21}{1,10}{2,20}{3,10}", "Integer Range",
         "Count", "Double Range", "Count");
      Console::WriteLine(
         "{0,21}{1,10}{2,20}{3,10}", "-------------",
         "-----", "------------", "-----");

      // Generate random integers and doubles, and then count 
      // them by group.
      for (int i = 0; i < runCount; i++)
      {
         intCounts[ (int)((double)randObj->Next() / 
               intGroupSize) ]++;
         realCounts[ (int)(randObj->NextDouble() * 
               (double)distGroupCount) ]++;
      }

      // Display the count of each group.
      for (int i = 0; i < distGroupCount; i++)
         Console::WriteLine(
               "{0,10}-{1,10}{2,10:N0}{3,12:N5}-{4,7:N5}{5,10:N0}",
               (int)((double)i * intGroupSize),
               (int)((double)(i + 1) * intGroupSize - 1.0),
               intCounts[ i ],
               ((double)i) / (double)distGroupCount,
               ((double)(i + 1)) / (double)distGroupCount,
               realCounts[ i ]);
      return 0;
}

/*
This example of Random.Sample() displays output similar to the following:

   The derived RandomProportional class overrides the Sample method to
   generate random numbers in the range [0.0, 1.0). The distribution
   of the numbers is proportional to the number values. For example,
   numbers are generated in the vicinity of 0.75 with three times the
   probability of those generated near 0.25.

   Random doubles generated with the NextDouble() method:

     0.59455719  0.17589882  0.83134398  0.35795862  0.91467727  0.54022658
     0.93716947  0.54817519  0.94685080  0.93705478  0.18582318  0.71272428
     0.77708682  0.95386216  0.70412393  0.86099417  0.08275804  0.79108316
     0.71019941  0.84205103  0.41685082  0.58186880  0.89492302  0.73067715

   Random integers generated with the Next() method:

     1570755704  1279192549  1747627711  1705700211  1372759203  1849655615
     2046235980  1210843924  1554274149  1307936697  1480207570  1057595022
      337854215   844109928  2028310798  1386669369  2073517658  1291729809
     1537248240  1454198019  1934863511  1640004334  2032620207   534654791

   To demonstrate the proportional distribution, 1,000,000 random
   integers and doubles are grouped into 10 equal value ranges. This
   is the count of values in each range:

           Integer Range     Count        Double Range     Count
           -------------     -----        ------------     -----
            0- 214748363    10,079     0.00000-0.10000    10,148
    214748364- 429496728    29,835     0.10000-0.20000    29,849
    429496729- 644245093    49,753     0.20000-0.30000    49,948
    644245094- 858993458    70,325     0.30000-0.40000    69,656
    858993459-1073741823    89,906     0.40000-0.50000    90,337
   1073741824-1288490187   109,868     0.50000-0.60000   110,225
   1288490188-1503238552   130,388     0.60000-0.70000   129,986
   1503238553-1717986917   149,231     0.70000-0.80000   150,428
   1717986918-1932735282   170,234     0.80000-0.90000   169,610
   1932735283-2147483647   190,381     0.90000-1.00000   189,813
*/
using System;

// This derived class converts the uniformly distributed random
// numbers generated by base.Sample() to another distribution.
public class RandomProportional : Random
{
    // The Sample method generates a distribution proportional to the value
    // of the random numbers, in the range [0.0, 1.0].
    protected override double Sample()
    {
        return Math.Sqrt(base.Sample());
    }

    public override int Next()
    {
       return (int) (Sample() * int.MaxValue);
    }
}

public class RandomSampleDemo
{
    static void Main()
    {	
        const int rows = 4, cols = 6;
        const int runCount = 1000000;
        const int distGroupCount = 10;
        const double intGroupSize =
            ((double)int.MaxValue + 1.0) / (double)distGroupCount;

        RandomProportional randObj = new RandomProportional();

        int[ ]      intCounts = new int[ distGroupCount ];
        int[ ]      realCounts = new int[ distGroupCount ];

        Console.WriteLine(
            "\nThe derived RandomProportional class overrides " +
            "the Sample method to \ngenerate random numbers " +
            "in the range [0.0, 1.0]. The distribution \nof " +
            "the numbers is proportional to their numeric values. " +
            "For example, \nnumbers are generated in the " +
            "vicinity of 0.75 with three times the \n" +
            "probability of those generated near 0.25.");
        Console.WriteLine(
            "\nRandom doubles generated with the NextDouble() " +
            "method:\n");

        // Generate and display [rows * cols] random doubles.
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
                Console.Write("{0,12:F8}", randObj.NextDouble());
            Console.WriteLine();
        }

        Console.WriteLine(
            "\nRandom integers generated with the Next() " +
            "method:\n");

        // Generate and display [rows * cols] random integers.
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
                Console.Write("{0,12}", randObj.Next());
            Console.WriteLine();
        }

        Console.WriteLine(
            "\nTo demonstrate the proportional distribution, " +
            "{0:N0} random \nintegers and doubles are grouped " +
            "into {1} equal value ranges. This \n" +
            "is the count of values in each range:\n",
            runCount, distGroupCount);
        Console.WriteLine(
            "{0,21}{1,10}{2,20}{3,10}", "Integer Range",
            "Count", "Double Range", "Count");
        Console.WriteLine(
            "{0,21}{1,10}{2,20}{3,10}", "-------------",
            "-----", "------------", "-----");

        // Generate random integers and doubles, and then count
        // them by group.
        for (int i = 0; i < runCount; i++)
        {
            intCounts[ (int)((double)randObj.Next() /
                intGroupSize) ]++;
            realCounts[ (int)(randObj.NextDouble() *
                (double)distGroupCount) ]++;
        }

        // Display the count of each group.
        for (int i = 0; i < distGroupCount; i++)
            Console.WriteLine(
                "{0,10}-{1,10}{2,10:N0}{3,12:N5}-{4,7:N5}{5,10:N0}",
                (int)((double)i * intGroupSize),
                (int)((double)(i + 1) * intGroupSize - 1.0),
                intCounts[ i ],
                ((double)i) / (double)distGroupCount,
                ((double)(i + 1)) / (double)distGroupCount,
                realCounts[ i ]);
    }
}

/*
This example of Random.Sample() displays output similar to the following:

   The derived RandomProportional class overrides the Sample method to
   generate random numbers in the range [0.0, 1.0). The distribution
   of the numbers is proportional to the number values. For example,
   numbers are generated in the vicinity of 0.75 with three times the
   probability of those generated near 0.25.

   Random doubles generated with the NextDouble() method:

     0.59455719  0.17589882  0.83134398  0.35795862  0.91467727  0.54022658
     0.93716947  0.54817519  0.94685080  0.93705478  0.18582318  0.71272428
     0.77708682  0.95386216  0.70412393  0.86099417  0.08275804  0.79108316
     0.71019941  0.84205103  0.41685082  0.58186880  0.89492302  0.73067715

   Random integers generated with the Next() method:

     1570755704  1279192549  1747627711  1705700211  1372759203  1849655615
     2046235980  1210843924  1554274149  1307936697  1480207570  1057595022
      337854215   844109928  2028310798  1386669369  2073517658  1291729809
     1537248240  1454198019  1934863511  1640004334  2032620207   534654791

   To demonstrate the proportional distribution, 1,000,000 random
   integers and doubles are grouped into 10 equal value ranges. This
   is the count of values in each range:

           Integer Range     Count        Double Range     Count
           -------------     -----        ------------     -----
            0- 214748363    10,079     0.00000-0.10000    10,148
    214748364- 429496728    29,835     0.10000-0.20000    29,849
    429496729- 644245093    49,753     0.20000-0.30000    49,948
    644245094- 858993458    70,325     0.30000-0.40000    69,656
    858993459-1073741823    89,906     0.40000-0.50000    90,337
   1073741824-1288490187   109,868     0.50000-0.60000   110,225
   1288490188-1503238552   130,388     0.60000-0.70000   129,986
   1503238553-1717986917   149,231     0.70000-0.80000   150,428
   1717986918-1932735282   170,234     0.80000-0.90000   169,610
   1932735283-2147483647   190,381     0.90000-1.00000   189,813
*/
open System

// This derived class converts the uniformly distributed random
// numbers generated by base.Sample() to another distribution.

type RandomProportional() =
    inherit Random()

    // The Sample method generates a distribution proportional to the value
    // of the random numbers, in the range [0.0, 1.0].
    override _.Sample() =
        sqrt (base.Sample())

    override this.Next() =
        this.Sample() * float Int32.MaxValue
        |> int

let [<Literal>] rows = 4
let [<Literal>] cols = 6
let [<Literal>] runCount = 1000000
let [<Literal>] distGroupCount = 10

let intGroupSize =
    (float Int32.MaxValue + 1.0) / float distGroupCount

let randObj = RandomProportional()

printfn """
The derived RandomProportional class overrides the Sample method to 
generate random numbers in the range [0.0, 1.0]. The distribution 
of the numbers is proportional to their numeric values. For example, 
numbers are generated in the vicinity of 0.75 with three times the 
probability of those generated near 0.25."""

printfn "\nRandom doubles generated with the NextDouble() method:\n"

// Generate and display [rows * cols] random doubles.
for _ = 1 to rows do 
    for _ = 1 to cols do
        printf $"{randObj.NextDouble(),12:F8}"
    printfn ""

printfn "\nRandom integers generated with the Next() method:\n"
// Generate and display [rows * cols] random integers.
for _ = 1 to rows do 
    for _ = 1 to cols do
        printf $"{randObj.Next(),12}"
    printfn ""

printfn $"""
To demonstrate the proportional distribution, {runCount:N0} random 
integers and doubles are grouped into {distGroupCount} equal value ranges. This 
is the count of values in each range:
"""

printfn $"""{"Integer Range",21}{"Count",10}{"Double Range",20}{"Count",10}"""
printfn $"""{"-------------",21}{"-----",10}{"------------",20}{"-----",10}"""

// Generate random integers and doubles, and then count them by group.
let intCounts = 
    Array.init runCount (fun _ -> 
        (randObj.Next() |> float) / float intGroupSize
        |> int )
    |> Array.countBy id
    |> Array.map snd

let realCounts = 
    Array.init runCount (fun _ -> 
        randObj.NextDouble() * float distGroupCount
        |> int )
    |> Array.countBy id
    |> Array.map snd

// Display the count of each group.
for i = 0 to distGroupCount - 1 do 
    Console.WriteLine(
        "{0,10}-{1,10}{2,10:N0}{3,12:N5}-{4,7:N5}{5,10:N0}",
        int(float i * intGroupSize),
        int(float (i + 1) * intGroupSize - 1.0),
        intCounts.[i],
        (float i) / float distGroupCount,
        float (i + 1) / float distGroupCount,
        realCounts.[i])

(*
This example of Random.Sample() displays output similar to the following:
    
    The derived RandomProportional class overrides the Sample method to
    generate random numbers in the range [0.0, 1.0). The distribution
    of the numbers is proportional to the number values. For example,
    numbers are generated in the vicinity of 0.75 with three times the
    probability of those generated near 0.25.
    
    Random doubles generated with the NextDouble() method:
    
        0.59455719  0.17589882  0.83134398  0.35795862  0.91467727  0.54022658
        0.93716947  0.54817519  0.94685080  0.93705478  0.18582318  0.71272428
        0.77708682  0.95386216  0.70412393  0.86099417  0.08275804  0.79108316
        0.71019941  0.84205103  0.41685082  0.58186880  0.89492302  0.73067715
    
    Random integers generated with the Next() method:
    
        1570755704  1279192549  1747627711  1705700211  1372759203  1849655615
        2046235980  1210843924  1554274149  1307936697  1480207570  1057595022
        337854215   844109928  2028310798  1386669369  2073517658  1291729809
        1537248240  1454198019  1934863511  1640004334  2032620207   534654791
    
    To demonstrate the proportional distribution, 1,000,000 random
    integers and doubles are grouped into 10 equal value ranges. This
    is the count of values in each range:
    
            Integer Range     Count        Double Range     Count
            -------------     -----        ------------     -----
            0- 214748363    10,079     0.00000-0.10000    10,148
    214748364- 429496728    29,835     0.10000-0.20000    29,849
    429496729- 644245093    49,753     0.20000-0.30000    49,948
    644245094- 858993458    70,325     0.30000-0.40000    69,656
    858993459-1073741823    89,906     0.40000-0.50000    90,337
    1073741824-1288490187   109,868     0.50000-0.60000   110,225
    1288490188-1503238552   130,388     0.60000-0.70000   129,986
    1503238553-1717986917   149,231     0.70000-0.80000   150,428
    1717986918-1932735282   170,234     0.80000-0.90000   169,610
    1932735283-2147483647   190,381     0.90000-1.00000   189,813
*)
' This derived class converts the uniformly distributed random 
' numbers generated by base.Sample() to another distribution.
Public Class RandomProportional
   Inherits Random

   ' The Sample method generates a distribution proportional to the value 
   ' of the random numbers, in the range [0.0, 1.0].
   Protected Overrides Function Sample() As Double
      Return Math.Sqrt(MyBase.Sample())
   End Function
   
   Public Overrides Function [Next]() As Integer
      Return Sample() * Integer.MaxValue
   End Function 
End Class 

Module RandomSampleDemo
    Sub Main()
        Const rows As Integer = 4, cols As Integer = 6
        Const runCount As Integer = 1000000
        Const distGroupCount As Integer = 10
        Const intGroupSize As Double = _
            (CDbl(Integer.MaxValue) + 1.0) / _
            CDbl(distGroupCount)
            
        Dim randObj As New RandomProportional()
            
        Dim intCounts(distGroupCount) As Integer
        Dim realCounts(distGroupCount) As Integer
        Dim i As Integer, j As Integer 
            
        Console.WriteLine(vbCrLf & _
            "The derived RandomProportional class overrides " & _ 
            "the Sample method to " & vbCrLf & _
            "generate random numbers in the range " & _ 
            "[0.0, 1.0]. The distribution " & vbCrLf & _
            "of the numbers is proportional to their numeric " & _
            "values. For example, " & vbCrLf & _ 
            "numbers are generated in the vicinity of 0.75 " & _
            "with three times " & vbCrLf & "the " & _
            "probability of those generated near 0.25.")
        Console.WriteLine(vbCrLf & _
            "Random doubles generated with the NextDouble() " & _ 
            "method:" & vbCrLf)
            
        ' Generate and display [rows * cols] random doubles.
        For i = 0 To rows - 1
            For j = 0 To cols - 1
                Console.Write("{0,12:F8}", randObj.NextDouble())
            Next j
            Console.WriteLine()
        Next i
            
        Console.WriteLine(vbCrLf & _
            "Random integers generated with the Next() " & _ 
            "method:" & vbCrLf)
            
        ' Generate and display [rows * cols] random integers.
        For i = 0 To rows - 1
            For j = 0 To cols - 1
                Console.Write("{0,12}", randObj.Next())
            Next j
            Console.WriteLine()
        Next i
            
        Console.WriteLine(vbCrLf & _
            "To demonstrate the proportional distribution, " & _ 
            "{0:N0} random " & vbCrLf & _
            "integers and doubles are grouped into {1} " & _ 
            "equal value ranges. This " & vbCrLf & _
            "is the count of values in each range:" & vbCrLf, _
            runCount, distGroupCount)
        Console.WriteLine("{0,21}{1,10}{2,20}{3,10}", _
            "Integer Range", "Count", "Double Range", "Count")
        Console.WriteLine("{0,21}{1,10}{2,20}{3,10}", _
            "-------------", "-----", "------------", "-----")
            
        ' Generate random integers and doubles, and then count 
        ' them by group.
        For i = 0 To runCount - 1
            intCounts(Fix(CDbl(randObj.Next()) / _
                intGroupSize)) += 1
            realCounts(Fix(randObj.NextDouble() * _
                CDbl(distGroupCount))) += 1
        Next i
            
        ' Display the count of each group.
        For i = 0 To distGroupCount - 1
            Console.WriteLine( _
                "{0,10}-{1,10}{2,10:N0}{3,12:N5}-{4,7:N5}{5,10:N0}", _
                Fix(CDbl(i) * intGroupSize), _
                Fix(CDbl(i + 1) * intGroupSize - 1.0), _
                intCounts(i), _
                CDbl(i) / CDbl(distGroupCount), _
                CDbl(i + 1) / CDbl(distGroupCount), _
                realCounts(i))
        Next i
    End Sub
End Module 
' This example of Random.Sample() generates output similar to the following:
'
'    The derived RandomProportional class overrides the Sample method to
'    generate random numbers in the range [0.0, 1.0]. The distribution
'    of the numbers is proportional to their numeric values. For example,
'    numbers are generated in the vicinity of 0.75 with three times
'    the probability of those generated near 0.25.
'    
'    Random doubles generated with the NextDouble() method:
'    
'      0.28377004  0.75920598  0.33430371  0.66720626  0.97080243  0.27353772
'      0.17787962  0.54618410  0.08145080  0.56286100  0.99002910  0.64898614
'      0.27673277  0.99455281  0.93778966  0.76162002  0.70533771  0.44375798
'      0.55939883  0.87383136  0.66465779  0.77392566  0.42393411  0.82409159
'    
'    Random integers generated with the Next() method:
'    
'      1364479914  1230312341  1657373812  1526222928   988564704   700078020
'      1801013705  1541517421  1146312560   338318389  1558995993  2027260859
'       884520932  1320070465   570200106  1027684711   943035246  2088689333
'       630809089  1705728475  2140787648  2097858166  1863010875  1386804198
'    
'    To demonstrate the proportional distribution, 1,000,000 random
'    integers and doubles are grouped into 10 equal value ranges. This
'    is the count of values in each range:
'    
'            Integer Range     Count        Double Range     Count
'            -------------     -----        ------------     -----
'             0- 214748363     9,892     0.00000-0.10000     9,928
'     214748364- 429496728    30,341     0.10000-0.20000    30,101
'     429496729- 644245093    49,958     0.20000-0.30000    49,964
'     644245094- 858993458    70,099     0.30000-0.40000    70,213
'     858993459-1073741823    90,801     0.40000-0.50000    89,553
'    1073741824-1288490187   109,699     0.50000-0.60000   109,427
'    1288490188-1503238552   129,438     0.60000-0.70000   130,339
'    1503238553-1717986917   149,886     0.70000-0.80000   150,000
'    1717986918-1932735282   170,338     0.80000-0.90000   170,128
'    1932735283-2147483647   189,548     0.90000-1.00000   190,347

備註

若要產生不同的隨機分佈或不同的亂數產生器準則,請從 Random 類別衍生類別並覆寫 Sample 方法。

重要

方法是 Sampleprotected ,這表示它只能在 類別及其衍生類別中 Random 存取。 若要從 Random 實例產生介於 0 到 1 之間的亂數字,請呼叫 NextDouble 方法。

給繼承者的注意事項

從 .NET Framework 2.0 版開始,如果您從 衍生類別 Random 並覆寫 Sample() 方法,則方法的衍生類別實作所提供的散發不會用於呼叫下列方法的基類實 Sample() 作:

相反地,會使用基 Random 類所提供的統一分佈。 此行為可改善 類別的整體效能 Random 。 若要修改此行為以呼叫衍生類別中方法的 Sample() 實作,您也必須覆寫這三個成員的行為。 這個範例將提供說明。

適用於

另請參閱