确保3的连续堆栈不会出现在4个混洗数组中?

时间:2013-10-04 20:05:06

标签: c# .net arrays vb.net shuffle

我有一个{0,1,2,3}的数组,想要改组它。 This工作得非常好

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个连续项目的堆栈(原始序列永远不会 允许)(或任意数量的连续原始项目)
  3. 阵列中可能有6个项目或10个项目,但我目前正在使用的只有4个项目。 C#或VB.net都没问题。

11 个答案:

答案 0 :(得分: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)时,您会获得更多排列,但是对于每个可能的循环,您可能无法执行任何可能在其原始位置留下数字的交换(取决于序列中的位置和其他交换)。

答案 1 :(得分: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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

包含3个连续项目的堆栈(绝不允许原始序列)

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

Scrambler类:

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

修改过的shuffle依赖于重新洗牌,我知道这不会耗费时间。因此,当Rule1 OrElse Rule2失败时,它只会重新洗牌。 10元素shuffle实际上必须执行28k shuffle才能获得10,000个“好”的shuffle。 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.

答案 4 :(得分:1)

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

此外,您拨打Next的电话正在通过ptr - 1,我认为这是不正确的。只考虑循环的第一次迭代,这是您的原始代码正在做的事情:

  1. ptr = items.Lengthptr设置为4。
  2. ptr -= 1ptr设置为3。
  3. 调用rnd.Next(ptr - 1)将选择0到1之间的整数。
  4. 这是更新后的代码:

    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
    

答案 5 :(得分: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;
}

答案 6 :(得分: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)之间的数字。 the Link表示rnd.Next(lowerLimit,upperLimit)会产生一个随机数,包括lowerLimit和排除upperLimit

根据生成的随机数生成即将生成的序列,因为它不会产生0,不会生成序列0,1,2,3

希望答案足够清楚

答案 7 :(得分: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

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

答案 8 :(得分:1)

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

注意**如果你制作相同的元素(例如在阵列中的2个不同位置出现9),那么就可以将9a拖入9b的插槽中,同样,因为shuffle功能不考虑什么是洗牌的价值,它只是由数组索引进行洗牌。

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 

答案 9 :(得分:1)

如果你提出像你这样的标准,那么随机播放会失去其随机特征。这里是一些带有测试程序的Knuth shuffle算法的实现。我要做的两个主要想法是确保Random是一个全局变量并从i和N中选择一个元素,知道我是循环的索引,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;
      }
    }


  }  
  }

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

答案 10 :(得分:-1)

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

中的Ticks数

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