我必须生成一系列数字为[0, 1, ..., 9]
且长度为6位的组合。
我需要100万个组合,这需要花费大量时间。
我尝试使用2个线程来查看它是否会更快,但我得到exception
。
代码:
Try
'again:
For i = 0 To 9
For c = 0 To 9
For d = 0 To 9
For b = 0 To 9
For a = 0 To 9
For f = 0 To 9
If ListBox2.Items.Contains(i & c & d & b & a & f) Then
Continue For
Else
ListBox2.Items.Add(i & c & d & b & a & f)
Label2.Text = ListBox2.Items.Count
End If
Next
Next
Next
Next
Next
Next
Catch ex As Exception
'GoTo again
End Try
现在,如果我使用 1个帖子运行它,它会确定,但需要花费很多时间。
如果我尝试使用 2个帖子,它会更快,但在某些时候它会在If ListBox2.Items.Contains(...) then
处引发异常
例外:
对象引用未设置为对象的实例。
我认为因为两个线程同时检查listbox2
而被抓住了,会发生这种情况吗?
答案 0 :(得分:1)
组合学有一些非常好的库。不需要重新发明轮子,只需使用它们。
Combinatorics Library for Microsoft .NET
KwCombinatorics: K-Combination, Permutation, Cartesian Product classes in C#
如果您认为自己足够好,可以使用Alea GPU或CUDAfy.NET直接在GPU上计算所有内容,这比在CPU上快几千倍。
答案 1 :(得分:0)
生成900,000种组合的代码,运行时间不到一秒。
Private Function Combinations() As List(Of String)
Static prng As New Random
Dim a() As Integer = Enumerable.Range(0, 10).Select(Function(n) n * 1).OrderBy(Function(y) prng.Next()).ToArray
Dim b() As Integer = Enumerable.Range(0, 10).Select(Function(n) n * 10).OrderBy(Function(y) prng.Next()).ToArray
Dim c() As Integer = Enumerable.Range(0, 10).Select(Function(n) n * 100).OrderBy(Function(y) prng.Next()).ToArray
Dim d() As Integer = Enumerable.Range(0, 10).Select(Function(n) n * 1000).OrderBy(Function(y) prng.Next()).ToArray
Dim e() As Integer = Enumerable.Range(0, 10).Select(Function(n) n * 10000).OrderBy(Function(y) prng.Next()).ToArray
Dim f() As Integer = Enumerable.Range(1, 9).Select(Function(n) n * 100000).OrderBy(Function(y) prng.Next()).ToArray
Dim rv As New List(Of String)
Dim ts As New List(Of Task(Of List(Of String)))
For Each a1 As Integer In a
Dim t As Task(Of List(Of String)) = Task.Run(Function()
Dim i As New List(Of Integer)
For Each b1 As Integer In b
For Each c1 As Integer In c
For Each d1 As Integer In d
For Each e1 As Integer In e
For Each f1 As Integer In f
Dim x As Integer = a1 + b1 + c1 + d1 + e1 + f1
i.Add(x)
Next
Next
Next
Next
Next
Return i.Select(Function(s) s.ToString()).ToList
End Function)
ts.Add(t)
Next
Task.WaitAll(ts.ToArray)
For Each t As Task(Of List(Of String)) In ts
rv.AddRange(t.Result)
Next
Return rv
End Function
添加到列表框需要更长的时间
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.BeginUpdate()
ListBox1.DataSource = Combinations()
ListBox1.EndUpdate()
End Sub