3

我正在研究一种优化算法,需要将一些数据(由算法生成)存储在一个名为 的二维数组matrix中,其中 row(i) 包含优化向量(i) 的适应度得分和参数值。

Dim matrix(vectorCount() - 1, parameterCount()) As Double
Dim params(parameterCount() - 1) As Double

For i As Integer = 0 To vectorCount() - 1
    matrix(i, 0) = vectorScore(i)
    params = vectorValues(i)
    For j As Integer = 0 To params.Length - 1
        matrix(i, j+1) = params(j)
    Next
Next

intvectorCount()返回向量的数量。
intparameterCount()返回每个向量中的参数数量。
double vectorScore(intvectorIndex)返回指定向量的适应度分数。
double[] vectorValues(intvectorIndex)返回指定向量的参数值。

我的问题:
是否有更快(即更有效)的插入params方式matrix

4

4 回答 4

4

如果你想要效率,依靠“普通”数组无疑是最好的选择。它们相对于其他替代方案(集合、列表等)如此高效的原因是它们包含所需的最少信息量。如果您想要能够轻松/快速地对信息进行排序或编写复杂查询来检索数据的花哨功能,则不应依赖数组。

我总是依赖于您编写的代码,并且从未遇到过速度问题(这真的很快)。我进行了快速研究以确保没有其他选择,但找不到任何选择。您拥有的最接近的是Array.Copy,尽管它仅在数组具有相同尺寸时才有效(我个人仅将其与一维数组一起使用)。无论如何,我发现了一个关于 Array.Copy() 与 2D 数组的循环性能的有趣链接(它在 C# 中,但一切都适用于 VB.NET)。

摘要:您的代码非常快,不需要改进。如果有一个有效的替代方案(Array.Copy 适用于 2D 和 1D,不存在的),结果性能会好一点(并且仅适用于小数组大小)。

于 2013-07-30T11:42:42.127 回答
1

如果要使用多个线程,可以使用并行 for 循环。

http://msdn.microsoft.com/en-us/library/dd460713.aspx

Dim matrix(vectorCount() - 1, parameterCount()) As Double
Dim params(parameterCount() - 1) As Double

Parallel.For(0, vectorCount() - 1, Sub(i)
                                      matrix(i, 0) = vectorScore(i)
                                      params = vectorValues(i)
                                      For j As Integer = 0 To params.Length - 1
                                          matrix(i, j+1) = params(j)
                                      Next
                                   End Sub)
于 2013-07-30T12:52:20.980 回答
1

它在很大程度上取决于数组的大小,for 循环非常有效,但是对于非常大的数组,您可以看到使用 array.copy 或 buffer.blockcopy 的改进。

Sub Main()

    Const ARR_SIZE_X As Integer = 9999999
    Const ARR_SIZE_y As Integer = 5
    Const DBL_SIZE As Integer = 8

    Dim watch As New Stopwatch

    Dim a1(ARR_SIZE_X) As Double
    Dim a2(ARR_SIZE_y, ARR_SIZE_X) As Double

    For x = 0 To ARR_SIZE_X
        a1(ARR_SIZE_X) = x
    Next

    watch.Start()

    For t = 0 To 10
        For y = 0 To ARR_SIZE_y
            For x = 0 To ARR_SIZE_X
                a2(y, x) = a1(x)
            Next
        Next
    Next

    watch.Stop()
    Console.WriteLine(watch.ElapsedTicks)

    watch.Reset()

    watch.Start()

    For t = 0 To 10
        For y = 0 To ARR_SIZE_y
            System.Buffer.BlockCopy(a1, 0, a2, (ARR_SIZE_X + 1) * DBL_SIZE * y, DBL_SIZE * ARR_SIZE_X)
        Next
    Next

    watch.Stop()
    Console.WriteLine(watch.ElapsedTicks)

    'For y = 0 To 4
    '    For x = 0 To 4
    '        Console.Write(a2(y, x))
    '    Next

    '    Console.WriteLine()
    'Next

    Console.ReadLine()

End Sub
于 2013-07-30T13:26:21.693 回答
1
Function OneD2TwoD(ByVal xLen As Integer, ByVal yLen As Integer)
    ' (1) populate 1d array
    Dim TwoD(xLen, yLen) As Integer
    Dim OneD((xLen + 1) * (yLen + 1) - 1) As Integer
    For i As Integer = 0 To OneD.GetUpperBound(0)
        OneD(i) = i
    Next
    PrintValues(OneD, "|")
    Console.WriteLine()
    ' (2) Convert 1d array to 2d array/
    Dim z, Row(yLen) As Integer
    For x As Integer = 0 To xLen
        For y As Integer = 0 To yLen
            z = x * (yLen + 1) + y
            TwoD(x, y) = OneD(z)
            Row(y) = TwoD(x, y)
        Next
        PrintValues(Row, "|")
    Next
    Console.WriteLine()
    ' (3) Convert 2d array to 1d array/
    Erase OneD
    ReDim OneD((xLen + 1) * (yLen + 1) - 1)
    For x As Integer = 0 To xLen
        For y As Integer = 0 To yLen
            z = y + x * (yLen + 1)
            OneD(z) = TwoD(x, y)
        Next
    Next
    PrintValues(OneD, "|")
End Function

Public Sub PrintValues(ByVal myList As IEnumerable, ByVal mySeparator As Char)
    ' source: https://msdn.microsoft.com/en-us/library/system.collections.arraylist.add(v=vs.110).aspx
    Dim obj As [Object]
    For Each obj In myList
        Console.Write("{0}{1}", mySeparator, obj)
    Next obj
    Console.WriteLine()
End Sub 'PrintValues

示例: OneD2TwoD(0, 10)

(1) 填充一维数组

|0|1|2|3|4|5|6|7|8|9|10

(2) 将一维数组转换为二维数组

|0|1|2|3|4|5|6|7|8|9|10

(3) 将二维数组转换为一维数组

|0|1|2|3|4|5|6|7|8|9|10

示例: OneD2TwoD(5, 0)

(1) 填充一维数组

|0|1|2|3|4|5

(2) 将一维数组转换为二维数组

|0

|1

|2

|3

|4

|5

(3) 将二维数组转换为一维数组

|0|1|2|3|4|5

示例: OneD2TwoD(2, 5)

(1) 填充一维数组

|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17

(2) 将一维数组转换为二维数组

| 0| 1| 2| 3| 4| 5

| 6| 7| 8| 9|10|11

|12|13|14|15|16|17

(3) 将二维数组转换为一维数组

|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17

感谢您的关注

于 2016-09-20T10:57:42.177 回答