我正在研究一种优化算法,需要将一些数据(由算法生成)存储在名为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
int vectorCount()
返回向量的数量
int parameterCount()
返回每个向量中的参数数量
double vectorScore(
int vectorIndex)
返回指定向量的适应度分数
double [] vectorValues(
int vectorIndex)
返回指定向量的参数值。
我的问题:
是否有更快(即更有效)的方式将params
插入matrix
?
答案 0 :(得分:4)
如果你想要效率,依靠“普通”阵列无疑是最好的选择。它们在其他替代方案(集合,列表等)方面如此高效的原因是因为它们包含所需的最少量信息。如果您希望花哨的函数允许轻松/快速地对信息进行排序,或者编写复杂的查询以检索数据,则不应该依赖数组。
我总是依赖于你编写的代码,并且没有速度问题(这非常快)。我做了一个快速的研究,以确保没有其他选择,但找不到任何选项。最接近的是Array.Copy
,虽然它只是在数组具有相同尺寸时才有效(我个人认为,只使用1D数组)。在任何情况下,我都发现interesting link关于2D阵列的Array.Copy()与循环性能(它在C#中,但一切都适用于VB.NET)。
总结:您的代码非常快,无需进行改进。如果有一个有效的替代方案(Array.Copy适用于2D和1D,不存在的东西),结果性能会更好一点(并且仅适用于小数组大小)。
答案 1 :(得分: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)
答案 2 :(得分:1)
这在很大程度上取决于数组的大小,因为循环非常有效,但是对于非常大的数组,你可以看到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
答案 3 :(得分: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)将1D数组转换为2D数组
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
(3)将2D数组转换为1D数组
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
示例: OneD2TwoD(5,0)
(1)填充一维数组
| 0 | 1 | 2 | 3 | 4 | 5
(2)将1D数组转换为2D数组
| 0
| 1
| 2
| 3
| 4
| 5
(3)将2D数组转换为1D数组
| 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)将1D数组转换为2D数组
| 0 | 1 | 2 | 3 | 4 | 5
| 6 | 7 | 8 | 9 | 10 | 11
| 12 | 13 | 14 | 15 | 16 | 17
(3)将2D数组转换为1D数组
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17
感谢您的关注