以最快的方式生成所有可能的组合

时间:2017-05-01 22:48:40

标签: vb.net

我必须生成一系列数字为[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而被抓住了,会发生这种情况吗?

2 个答案:

答案 0 :(得分:1)

组合学有一些非常好的库。不需要重新发明轮子,只需使用它们。

Combinatorics Library for Microsoft .NET

KwCombinatorics: K-Combination, Permutation, Cartesian Product classes in C#

如果您认为自己足够好,可以使用Alea GPUCUDAfy.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