我有arraylist,其中包含具有以下顺序的数组索引的数字:
request.execute
这里的逻辑是,起始数字在20个间隔后发生变化。因此,我希望从5组20组中至少选择1个数字以进行任意选择,而无需重复数字。
例如,如果我随机选择6个数字,则数字可以是
0 - 10000
1 - 10500
2 - 11000
3 - 11500
.
.
99 - 59500
在这里,我得到了选择中出现的所有起始数字,而无需重复 号码。如果选择的数目为10,则所选的数字必须每5组包含2个数字,这意味着将有2个数字从1开始,2个数字从2开始,2个数字从3开始.....全部选中数字不能重复。
任何人都可以帮助我使用VB.NET来实现这一目标。 这是我的代码,它可以正常工作,直到达到50左右,然后再进入无限循环。请帮我修复它。
10500
20000
30500
40500
50000
40000
答案 0 :(得分:0)
While selected.Contains(randomIndex) ... choose another randomIndex
之类的结构是程序的配方,可能无法在合理的时间内终止。
首先,请参见arraylist索引映射到(10000 + 500 *索引)。因此我们可以忽略它,直到涉及到演示时间为止。
按照您所写的方式使用间隔通常称为 binning 数字。所以你想要五个垃圾箱。
您知道需要多少个数字,以及有多少个垃圾箱,因此您需要在垃圾箱中分配选定的号码。有时不可能将选定的数量以相等的数量分布在各个垃圾箱中,因此某些“幸运”垃圾箱将有更多可供选择的垃圾箱。为此,假设我们有五个垃圾箱和十二个数字。因此,每个垃圾箱有两个(12 \ 5),还有两个剩余(12 mod 5)。我们需要随机选择两个幸运箱以拥有三个数字,因此从0、1、2、3、4的列表中我们随机需要两个,如果该列表按随机顺序排列,则选择前两个即可。然后,当我们处理垃圾箱时,我们只需要检查它是否在幸运箱的列表中即可。
然后,您需要一个随机范围内的数字范围来进行选择;最好将其创建为单独的函数。
要创建选择,请遍历垃圾箱并从每个垃圾箱中选择适当数量的随机数。
需要一些改进,这表明了我的意思:
Option Infer On
Option Strict On
Module Module1
Dim rand As New Random()
''' <summary>
''' Create an unordered list of integers in the range [0, n).
''' </summary>
''' <param name="n">Upper limit, exclusive.</param>
''' <param name="rand">An instance of the Random class.</param>
''' <returns>List(Of Integer) from 0..n-1 in a random order.</returns>
<DebuggerStepThrough>
Function RandomList(n As Integer, rand As Random) As List(Of Integer)
Dim r As New List(Of Integer)(n)
For i = 0 To n - 1
r.Insert(rand.Next(0, i + 1), i)
Next
Return r
End Function
Function PickRandomValues(nValues As Integer) As List(Of Integer)
'TODO: Refactor nMin, nMax, nBins, rand as parameters.
'TODO: Detect impossible requirements.
Dim selection As New List(Of Integer)
Dim nMin = 0
Dim nMax = 99
Dim nBins = 5
Dim binSize = (nMax - nMin + 1) \ nBins
Dim numbersPerBin = nValues \ nBins
' the remainder of the items will be distributed randomly amongst the bins...
Dim extraNumbers = nValues Mod nBins
Dim luckyBins = RandomList(nBins, rand).Take(extraNumbers).ToList()
For bin = 1 To nBins
Dim numbersFromThisBin = numbersPerBin + If(luckyBins.Contains(bin - 1), 1, 0)
Dim picks = RandomList(binSize, rand).Take(numbersFromThisBin)
For Each p In picks
selection.Add((bin - 1) * binSize + p)
Next
Next
Return selection
End Function
Sub Main()
' Show example results...
For i = 1 To 10
Console.WriteLine(String.Join(", ", PickRandomValues(11).Select(Function(x) 10000 + 500 * x)))
Next
Console.ReadLine()
End Sub
End Module
示例输出:
10000、17500、21500、26500、20000、32000、35500、43500、49000、53000、57000
12000、14000、29000、25000、31500、30000、49000、45000、48000、56500、57000
15500、12500、22500、23000、31000、38000、36000、45500、46000、59000、58500
10000、19000、16500、25500、24000、37500、31500、44500、40000、50000、52500
16000、11500、26500、24000、38500、39500、36500、44000、43500、53500、57500
18500、17000、24500、29000、33000、37000、45000、41000、51000、53500、51500
10000、16500、12500、27500、24000、34500、33000、43000、45500、55000、53000
17000、17500、12000、20500、24000、39000、36500、44000、47000、53000、55000
10000、17500、24500、27000、30500、32500、49000、46500、48000、57000、50500
13000、11500、20000、29500、24000、32500、39500、45500、46500、59000、58500
数组列表已被列表取代。