9

我有一个数组{0,1,2,3}并且想要洗牌。工作得很好

Public Function ShuffleArray(ByVal items() As Integer) As Integer()
    Dim ptr As Integer
    Dim alt As Integer
    Dim tmp As Integer
    Dim rnd As New Random()

    ptr = items.Length

    Do While ptr > 1
        ptr -= 1
        alt = rnd.Next(ptr - 1)
        tmp = items(alt)
        items(alt) = items(ptr)
        items(ptr) = tmp
    Loop
    Return items
End Function

一些时间。但是,我发现它经常会产生一堆放在堆栈后面的位置{1,2,3,0}0事实上,这通常足以使这看起来根本不是随机的。不需要“新随机数组中的 3 的原始序列”。

有没有办法改进这一点,以便:

  1. 一个项目永远不会在它的原始位置
  2. 3 个连续项目的堆栈(绝不允许来自原始序列)(或任意数量的连续原始项目)

它可能是数组中的 6 个项目或 10 个项目,但我目前正在使用的只是 4 个项目。C# 或 VB.net 都可以。

4

11 回答 11

2

看起来您正在尝试进行 Fisher-Yates 洗牌,但调用Next不正确。调用Next应该是rnd.Next(ptr + 1). 当您调用它时,ptr - 1您只会为 4 个项目的序列产生两个排列。起始序列为 [0 1 2 3],其中一个序列是 [1 2 3 0]。有关说明,请参见下表。

ptr  ptr - 1    alt     Permutations            Remarks
---  -------    ---     ------------            -------
4                       [0 1 2 3]               Starting condition
3    2          1 or 0  [0 3 2 1] or [3 1 2 0]  First pass 
2    1          0       [2 3 0 1] or [2 1 3 0]  Second pass
1    0          0       [3 2 0 1] or [1 2 3 0]  Final pass

原因alt是 0 两次是Random.Next(0)返回0

编辑:rnd.Next(ptr)正如 CoderDennis 所指出的,使用而不是rnd.Next(ptr + 1)可能更接近您的要求,因为它将数字移动到新位置会做得更好。当您使用时,rnd.Next(ptr + 1)您会获得更多排列,但对于每个可能的循环,您可能不会执行任何可能将数字留在其原始位置的交换(取决于序列中的位置和其他交换)。

于 2014-10-23T21:39:53.013 回答
2

3 个连续项目的堆栈(不允许来自原始序列)

我假设 shuffle(n) 的结果用作 shuffle(n+1) 的起始序列。这不是微不足道的,因为使用相同的起始序列只会导致 7 个有效组合{0, 1, 2, 3}。在应用程序启动时使用固定的启动顺序意味着第一次 shuffle 只能是这 7 个中的一个(可能足够多)。

加扰器类:

Public Class Scrambler
    Private rand As Random

    Public Sub New()
        rand = New Random
    End Sub

    ' FY In-Place integer array shuffle 
    Public Sub Shuffle(items() As Integer)
        Dim tmp As Integer
        Dim j As Integer

        ' hi to low, so the rand result is meaningful
        For i As Integer = items.Length - 1 To 0 Step -1
            j = rand.Next(0, i + 1)        ' NB max param is EXCLUSIVE

            tmp = items(j)
            ' swap j and i 
            items(j) = items(i)
            items(i) = tmp
        Next

    End Sub

    ' build a list of bad sequences

    ' fullfils the "stack of 3 sequential items (from the original sequence..." requirement
    ' nsize - allows for the "(or any number ..." portion though scanning for
    '   a series-of-5 may be fruitless
    Public Function GetBadList(source As Integer(),
                               nSize As Integer) As List(Of String)
        Dim BList As New List(Of String)
        Dim badNums(nSize - 1) As Integer

        For n As Integer = 0 To source.Length - nSize
            Array.Copy(source, n, badNums, 0, badNums.Length)
            BList.Add(String.Join(",", badNums))

            Array.Clear(badNums, 0, badNums.Length)
        Next
        Return BList
    End Function


    Public Function ScrambleArray(items() As Integer, badSize As Integer) As Integer()
        ' FY is an inplace shuffler, make a copy
        Dim newItems(items.Length - 1) As Integer
        Array.Copy(items, newItems, items.Length)

        ' flags
        Dim OrderOk As Boolean = True
        Dim AllDiffPositions As Boolean = True

        Dim BadList As List(Of String) = GetBadList(items, badSize)
        ' build the bad list

        Do
            Shuffle(newItems)

            ' check if they all moved
            AllDiffPositions = True
            For n As Integer = 0 To items.Length - 1
                If newItems(n) = items(n) Then
                    AllDiffPositions = False
                    Exit For
                End If
            Next

            ' check for forbidden sequences
            If AllDiffPositions Then
                Dim thisVersion As String = String.Join(",", newItems)

                OrderOk = True
                For Each s As String In BadList
                    If thisVersion.Contains(s) Then
                        OrderOk = False
                        Exit For
                    End If
                Next

            End If
        Loop Until (OrderOk) And (AllDiffPositions)

        Return newItems
    End Function

End Class

测试代码/使用方法:

' this series is only used once in the test loop
Dim theseItems() As Integer = {0, 1, 2, 3}

Dim SeqMaker As New Scrambler         ' allows one RNG used
Dim newItems() As Integer

' reporting
Dim rpt As String = "{0}   Before: {1}   After: {2}  time:{3}"

ListBox1.Items.Clear()

For n As Integer = 0 To 1000
    sw.Restart()
    newItems = SeqMaker.ScrambleArray(theseItems, 3)  ' bad series size==3
    sw.Stop()

    ListBox1.Items.Add(String.Format(rpt, n.ToString("0000"), String.Join(",", theseItems),
                    String.Join(",", newItems), sw.ElapsedTicks.ToString))

    Console.WriteLine(rpt, n.ToString("0000"), String.Join(",", theseItems),
                      String.Join(",", newItems), sw.ElapsedTicks.ToString)

    ' rollover to use this result as next start
    Array.Copy(newItems, theseItems, newItems.Length)

Next

一个项目永远不会在它的原始位置上,这在小集合上是有意义的。但对于较大的集合,它排除了大量的合法洗牌(>60%);在某些情况下,仅仅因为 1 个项目在同一个位置。

 Start:   {1,2,8,4,5,7,6,3,9,0}
Result:   {4,8,2,0,7,1,6,9,5,3}

由于'6'而失败,但它真的是无效的洗牌吗?三个系列规则很少出现在较大的集合中(<1%),这可能是浪费时间。


如果没有列表框和控制台报告(以及一些未显示的分发集合),它会非常快。

Std Shuffle, 10k iterations, 10 elements: 12ms  (baseline)
   Modified, 10k iterations, 10 elements: 91ms
   Modified, 10k iterations, 04 elements: 48ms

修改后的洗牌依赖于重新洗牌,我知道这不会很耗时。因此,当 Rule1 OrElse Rule2 失败时,它只是重新洗牌。10 个元素的 shuffle 必须实际执行 28k shuffle 才能获得 10,000 个“好”的。4 元素 shuffle 实际上具有更高的拒绝率,因为很少的项目(34,000 次拒绝)更容易打破规则。

这不像随机分布那样让我感兴趣,因为如果这些“改进”引入了偏差,那就不好了。10k 4 元素分布:

seq: 3,2,1,0  count: 425
seq: 1,0,2,3  count: 406
seq: 3,2,0,1  count: 449
seq: 2,3,1,0  count: 424
seq: 0,1,3,2  count: 394
seq: 3,0,2,1  count: 371
seq: 1,2,3,0  count: 411
seq: 0,3,1,2  count: 405
seq: 2,1,3,0  count: 388
seq: 0,3,2,1  count: 375
seq: 2,0,1,3  count: 420
seq: 2,1,0,3  count: 362
seq: 3,0,1,2  count: 396
seq: 1,2,0,3  count: 379
seq: 0,1,2,3  count: 463
seq: 1,3,0,2  count: 398
seq: 2,3,0,1  count: 443
seq: 1,0,3,2  count: 451
seq: 3,1,2,0  count: 421
seq: 2,0,3,1  count: 487
seq: 0,2,3,1  count: 394
seq: 3,1,0,2  count: 480
seq: 0,2,1,3  count: 444
seq: 1,3,2,0  count: 414

通过较小的迭代(1K),您可以看到与修改后的形式相比更均匀的分布。但是,如果您拒绝某些合法的洗牌,这是可以预料的。

十个元素的分布是不确定的,因为有太多的可能性(360 万次洗牌)。也就是说,在 10k 次迭代中,往往会有大约 9980 个系列,其中 12-18 的计数为 2。

于 2014-10-28T19:22:57.683 回答
2

我相信以下将满足给定的要求。我合并了@CoderDennis 对初始随机值的修复,以及传入随机值。我的 VB 技能在 C# 和 JavaScript 中已经被玷污了太多年,所以对于任何明显的语法错误,我深表歉意。

它只过滤掉三个连续项目的序列,而不是“(或任意数量的连续原始项目)”。

Public Function ShuffleArray(ByVal items() As Integer, ByVal rnd As Random) As Integer()
    Dim original as Integer() = items.ToArray()
    Dim ptr As Integer
    Dim alt As Integer
    Dim tmp As Integer
    Dim stacksOfThree = new List(Of Integer())
    Dim isGood As Boolean = True

    ptr = items.Length

    Do While ptr > 2
        ptr -= 1
        stacksOfThree.Add(new Integer() { items(ptr - 2), items(ptr - 1), items(ptr) })
    Loop

    ptr = items.Length

    Do While ptr > 1
        ptr -= 1
        alt = rnd.Next(ptr)
        tmp = items(alt)
        While items(alt).Equals(items(ptr)) Or items(ptr).Equals(tmp)
            alt = rnd.Next(ptr)
            tmp = items(alt)
        End While
        items(alt) = items(ptr)
        items(ptr) = tmp
    Loop

    ptr = items.Length
    Do While ptr > 1
        ptr -= 1
        If items(ptr).Equals(original(ptr)) Then
            isGood = False
            Exit Do
        End If
    Loop

    If isGood Then
        ptr = items.Length
        Do While ptr > 2
            ptr -= 1
            For Each stack In stacksOfThree
                If stack(2).Equals(items(ptr)) And stack(1).Equals(items(ptr - 1)) And stack(0).Equals(items(ptr - 2)) Then
                    isGood = False
                    Exit For
                End If
            Next 
            If Not isGood Then
                Exit Do
            End If
        Loop
    End If

    If isGood Then
        Return items
    Else
        Return ShuffleArray(original, new Random())
    End If
End Function
于 2014-10-23T21:49:59.733 回答
2

每个人都在解决你的洗牌并错过了实际问题。

有了这样的约束,我会简单地洗牌,然后测试结果是否符合标准,如果不符合标准,则再次洗牌。不幸的是,这具有不确定的运行时间,但只要约束不太可能拒绝它,现实世界的性能通常是可以接受的。

但是,在这种特殊情况下,我会采取完全不同的方法。列表中有 4 项,只有 24 种可能的排列,其中 4 种绝对无效。(我不确定你是否想要 [0, 1, 3, 2] 之类的东西。)因此我会存储列表的所有有效排列,对列表进行排序,从预先计算的列表中选择一个随机排列并相应地“洗牌”列表。

于 2014-10-23T21:53:34.257 回答
1

我没有实施您关于结果永远不会处于其原始位置或结果序列的规则。一个真正随机的序列无论如何都不会符合这些规则。但是,我确实发现您的实施存在一些问题。我ShuffleArray在测试中循环运行了 100 次。下面的代码在产生随机结果方面似乎要好得多。确保Random在循环调用之前创建一次实例以ShuffleArray消除种子问题。

此外,您的电话Next正在传递ptr - 1,我认为这是不正确的。想想循环的第一次迭代,这就是你的原始代码在做什么:

  1. ptr = items.Length设置ptr为 4。
  2. ptr -= 1设置ptr为 3。
  3. 调用rnd.Next(ptr - 1)将选择 0 到 1 之间的整数。

这是更新的代码:

Public Function ShuffleArray(ByVal items() As Integer, ByVal rnd As Random) As Integer()
    Dim ptr As Integer
    Dim alt As Integer
    Dim tmp As Integer

    ptr = items.Length

    Do While ptr > 1
        ptr -= 1
        alt = rnd.Next(ptr)
        tmp = items(alt)
        items(alt) = items(ptr)
        items(ptr) = tmp
    Loop
    Return items
End Function

这是一个更简单的版本,使用For而不是While

Public Function ShuffleArray(ByVal items() As Integer, ByVal rnd As Random) As Integer()
    Dim alt As Integer
    Dim tmp As Integer

    For ptr = items.Length - 1 To 0 Step -1
        alt = rnd.Next(ptr)
        tmp = items(alt)
        items(alt) = items(ptr)
        items(ptr) = tmp
    Next
    Return items
End Function
于 2014-10-23T20:52:39.750 回答
1

如果您将问题简化为对索引数组进行洗牌,然后使用此数组对项目数组进行排序,则会容易得多。我创建了一个GuardedShuffle类,它演示了如何做到这一点。它目前将顺序元素定义为一个,在原始序列中提到附近的值,升序或降序。

该代码是人类对您的洗牌规则的解释,即我将如何手动解决它,用 VB.NET 编写。我没有尝试优化它,但对于合理大小的集合来说,它应该足够快。

如果您对代码有任何疑问 - 请在评论中告诉我,我会尽力解释 - 尽管我试图保持它的整洁,但不会对重构和编码标准过于疯狂。

在将其作为真实应用程序的一部分之前,您可能需要添加一些错误检查。

Module Module1

  Sub Main()
    Dim items() As Integer = {0, 11, 22, 33, 44, 55, 66, 77, 88, 99}
    Dim gs As New GuardedShuffle(maxSequentialItems:=1)
    Dim shuffledItems() As Integer = gs.ShuffleArray(items)
  End Sub

  Public Class GuardedShuffle

    Private _maxSequentialItems As Integer

    Public Sub New(maxSequentialItems As Integer)
      _maxSequentialItems = maxSequentialItems
    End Sub

    Public Function ShuffleArray(items() As Integer) As Integer()
      Dim indicesSequential As New List(Of Integer)
      For i = 0 To items.Count - 1
        indicesSequential.Add(i)
      Next

      Dim indicesShuffled() As Integer = ShuffleIndices(indicesSequential.ToArray)

      Dim retValue As New List(Of Integer)
      For i = 0 To items.Count - 1
        retValue.Add(items(indicesShuffled(i)))
      Next

      Return retValue.ToArray
    End Function

    Private Function ShuffleIndices(indices() As Integer) As Integer()
      Dim inputList As New List(Of Integer)(indices)
      Dim outputList As New List(Of Integer)

      Dim r As New Random
      While inputList.Count > 0
        Dim seq As New List(Of Integer)
        If _maxSequentialItems = 1 AndAlso outputList.Count > 0 Then
          seq.Add(outputList.Last)
        Else
          For k As Integer = outputList.Count - _maxSequentialItems + 1 To outputList.Count - 1
            If k >= 0 Then
              seq.Add(outputList(k))
            End If
          Next
        End If

        Dim allowedList As New List(Of Integer)
        For Each el In inputList
          If IsAllowed(seq, el, _maxSequentialItems) Then
            allowedList.Add(el)
          End If
        Next
        allowedList.Remove(outputList.Count) 'An item is never in its original position

        Dim randomIndex As Integer = Math.Floor(r.Next(allowedList.Count))
        Dim i As Integer = allowedList.Item(randomIndex)
        inputList.Remove(i)
        outputList.Add(i)
      End While

      Return outputList.ToArray
    End Function

    Private Shared Function IsAllowed(curSeq As List(Of Integer), newValue As Integer, maxSequential As Integer) As Boolean
      Dim seq As New List(Of Integer)(curSeq)
      seq.Add(newValue)
      Return IsAllowed(seq, maxSequential)
    End Function

    Private Shared Function IsAllowed(seq As List(Of Integer), maxSequential As Integer) As Boolean
      Dim curSequential As Integer = 0
      For i = 1 To seq.Count - 1
        If Math.Abs(seq(i) - seq(i - 1)) = 1 Then
          curSequential += 1
        End If
      Next
      Return curSequential < maxSequential
    End Function

  End Class

End Module

性能/可扩展性测试(在 100 毫秒内洗牌 1000 个项目):

Sub Main()
  Dim items() As Integer = Enumerable.Range(0, 1000).ToArray
  Dim gs As New GuardedShuffle(maxSequentialItems:=1)
  Dim t As New Stopwatch
  t.Start()
  Dim shuffledItems() As Integer = gs.ShuffleArray(items)
  t.Stop()
  Console.WriteLine("Elapsed (ms): " & t.ElapsedMilliseconds.ToString("N2"))
  Console.ReadLine()
End Sub

使用相同的代码,10000 个项目在 7-8 秒内排序。

于 2014-10-27T21:03:47.730 回答
1

你考虑过这样的事情吗?这不会显示任何长于 2 的连续整数字符串。这也不会将任何项目放在其原始位置。

注意**如果您制作相同的元素(例如在数组中的 2 个不同位置出现 9),则可以将 9a 洗牌到 9b 的插槽中,同样,因为洗牌函数不考虑它在洗什么,它只按数组索引洗牌。

Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
    Dim rnd As New Random(Today.Millisecond)
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim originalArray As Integer() = {0, 1, 2, 3, 4, 5, 6, 7, 9}
        Dim sb As New System.Text.StringBuilder
        Dim final As New System.Text.StringBuilder
        Dim msg As String = "Original: {0} Shuffled: {1}"
        Dim msg2 As String = "Original: {0} Shuffled: {1} ◄- Same"
        For i2 As Integer = 1 To 3
            Dim shuffledArray As Integer() = ShuffleArray(originalArray)
            For i As Integer = 0 To shuffledArray.Count - 1
                If originalArray(i) = shuffledArray(i) Then
                    sb.AppendLine(String.Format(msg2, originalArray(i), shuffledArray(i)))
                Else
                    sb.AppendLine(String.Format(msg, originalArray(i), shuffledArray(i)))
                End If
            Next
            Dim result As String = sb.ToString.Substring(0, sb.ToString.Length - 1) & vbCrLf & vbCrLf
            final.AppendLine(result)
            sb.Clear()
        Next
        RichTextBox1.Text = final.ToString
    End Sub
    Public Function ShuffleArray(Of t)(ByVal items() As t) As t()
        Dim results As New List(Of t)
        Dim usedIndexes As New List(Of Integer)
        Do
            Dim nextIndex As Integer = rnd.Next(0, items.Count)
            If usedIndexes.IndexOf(nextIndex) = -1 Then
                If usedIndexes.Count = nextIndex Then
                    If usedIndexes.Count = items.Count - 1 Then
                        usedIndexes.Clear()
                        results.Clear()
                    End If
                    Continue Do
                End If
                If Not last3sequential(usedIndexes, nextIndex) Then
                    usedIndexes.Add(nextIndex)
                    results.Add(items(nextIndex))
                Else
                    If usedIndexes.Count > items.Count - 3 Then
                        usedIndexes.Clear()
                        results.Clear()
                    End If
                End If
            End If
        Loop Until results.Count = items.Count
        Return results.ToArray
    End Function
    Function last3sequential(usedIndexes As List(Of Integer), nextIndex As Integer) As Boolean
        If usedIndexes.Count < 2 Then Return False
        Dim last As Integer = nextIndex
        Dim secondToLast As Integer = usedIndexes(usedIndexes.Count - 1)
        Dim thirdToLast As Integer = usedIndexes(usedIndexes.Count - 2)
        If last - secondToLast = 1 AndAlso secondToLast - thirdToLast = 1 Then
            Return True
        End If
        Return False
    End Function
End Class

5 test cases:
Original: 0 Shuffled: 7
Original: 1 Shuffled: 8
Original: 2 Shuffled: 5
Original: 3 Shuffled: 2
Original: 4 Shuffled: 9
Original: 5 Shuffled: 4
Original: 6 Shuffled: 0
Original: 7 Shuffled: 6
Original: 8 Shuffled: 3
Original: 9 Shuffled: 1 

Original: 0 Shuffled: 4
Original: 1 Shuffled: 2
Original: 2 Shuffled: 9
Original: 3 Shuffled: 6
Original: 4 Shuffled: 7
Original: 5 Shuffled: 0
Original: 6 Shuffled: 3
Original: 7 Shuffled: 5
Original: 8 Shuffled: 1
Original: 9 Shuffled: 8 

Original: 0 Shuffled: 8
Original: 1 Shuffled: 7
Original: 2 Shuffled: 6
Original: 3 Shuffled: 2
Original: 4 Shuffled: 0
Original: 5 Shuffled: 1
Original: 6 Shuffled: 9
Original: 7 Shuffled: 4
Original: 8 Shuffled: 5
Original: 9 Shuffled: 3 

Original: 0 Shuffled: 6
Original: 1 Shuffled: 4
Original: 2 Shuffled: 8
Original: 3 Shuffled: 7
Original: 4 Shuffled: 9
Original: 5 Shuffled: 2
Original: 6 Shuffled: 5
Original: 7 Shuffled: 3
Original: 8 Shuffled: 1
Original: 9 Shuffled: 0 

Original: 0 Shuffled: 6
Original: 1 Shuffled: 9
Original: 2 Shuffled: 0
Original: 3 Shuffled: 1
Original: 4 Shuffled: 5
Original: 5 Shuffled: 2
Original: 6 Shuffled: 3
Original: 7 Shuffled: 8
Original: 8 Shuffled: 7
Original: 9 Shuffled: 4 
于 2014-10-28T04:51:28.810 回答
1

小型套装的简单解决方案:

public static List<int> Shuffle(List<int> ints)
{
    var random = new Random();
    var result = ints.ToList();
    var hs = new HashSet<int>(ints);
    for (int i = 0; i < ints.Count; i++)
    {
        result[i] = ints.Where((x, j) => j != i).Intersect(hs).OrderBy(x => random.Next()).First();
        hs.Remove(result[i]);
    }
    return result;
}
于 2014-10-23T21:52:28.163 回答
1

如果您设置像您这样的标准,则洗牌会失去其随机特征。这是 Knuth shuffle 算法与测试程序的一些实现。我正在做的两个主要想法是确保 Random 是一个全局变量并从 i 和 N 中选择一个元素,知道 i 是循环的索引,N 是数组的大小。

using System;
using System.Collections.Generic;
using System.Linq;

public class Solution
{
  private static void Main(String[] args)
  {
    var array = new int[] { 1, 2, 3, 4 };
    Dictionary<string, int> results = new Dictionary<string, int>();
    for (int i = 0; i < 500000; i++)
    {
      var a = array.ToArray();
      Shuffller.Shuffle(a);
      var data = string.Join(" ", a);
      if (results.ContainsKey(data))
      {
        results[data]++;
      }
      else
      {
        results.Add(data, 1);
      }
    }

    foreach (var item in results.OrderBy(e => e.Key))
    {
      Console.WriteLine("{0}  => {1}", item.Key, item.Value);
    }
    Console.ReadKey();
  }

  public class Shuffller
  {
    private static Random random = new Random();
    /// <summary>
    /// * Rearranges an array of objects in uniformly random order
    ///  (under the assumption that Random generates independent
    ///  and uniformly distributed numbers).          
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="a">the array to be shuffled     </param>
    public static void Shuffle<T>(T[] a)
    {
      int N = a.Length;
      for (int i = 0; i < N; i++)
      {
        // choose index uniformly in [i, N-1]        
        int r = i + random.Next(0, N - i);
        T swap = a[r];
        a[r] = a[i];
        a[i] = swap;
      }
    }


  }  
  }

如果要对某些结果进行元素化,为什么不在两个数组之间实现相似度算法,然后定义一个阈值,如果混洗后的数组与原始数组之间的相似度高于阈值,则重新混洗,虽然我不建议触摸结果,特别是如果您需要随机洗牌,如果您的算法基于随机洗牌,您将有很多缺陷。

于 2014-10-28T14:20:10.453 回答
1

在这里,我建议一种方法,通过将一个数字作为随机数并移动其他数字来填充数组,您可以通过该方法实现洗牌目标。考虑以下代码:

Public Function ShuffleArray(ByVal a() As Integer) As Integer()
    Dim ptr As Integer
    Dim alt As Integer
    Dim items(3) As Integer
    Dim rnd As New Random()
    ptr = a.Length
    alt = rnd.Next(1, 4) '<---- change here it now generate a random number between 1 and 3
    Do While ptr <> 0
        ptr -= 1
        items(ptr) = a(alt)
        Select Case alt
            Case 0 To 2
                alt += 1
            Case Else
                alt = 0
        End Select
    Loop
    Return items
End Function 

这些项目将包含洗牌的数组,例如:

1 2 3 0
2 3 0 1
3 0 1 2 etc

更新:

我的回答不会产生输出0,1,2,3,因为alt = rnd.Next(1, 4)会产生一个介于 1(lowerLimit)和 4(upperLimit)之间的数字。链接说这rnd.Next(lowerLimit,upperLimit)将产生一个随机数,包括lowerLimit和排除upperLimit.

基于这个生成的随机数生成即将到来的序列,因为它不会产生0序列 0,1,2,3将不会被生成。

希望答案足够清楚

于 2014-10-24T06:51:41.407 回答
-1

我相信你所看到的是因为你没有为你的 Random 类播种一个值。我建议尝试接受 int 作为种子值的构造函数。一个简单的种子值是DateTime.Now.Ticks

有关 Random 类的更多信息,请参见以下链接:http: //msdn.microsoft.com/en-us/library/system.random.aspx

于 2013-10-04T20:15:24.193 回答