我有一个2d数组,我想对数组中的每个元素进行计算,然后返回导致最小值的索引。
我尝试迭代2d数组中的每个元素并运行计算。如果计算结果小于当前存储的最小值,则将其设置为最小值。
这样可行,但运行速度很慢,使解决方案成为非首发。它快速执行每个计算,但由于数组中元素的数量,整个数组的计算是愚蠢的长。
任何建议都会有所帮助。
答案 0 :(得分:1)
考虑使用扁平的1D数组,如下所示:
Public Class FlatMatrix
Private m_elems As Double()
Private m_rows, m_cols As Integer
Public Sub New(ByVal rows As Integer, ByVal cols As Integer)
Me.m_cols = cols
Me.m_rows = rows
Me.m_elems = New Double(Me.m_rows * Me.m_cols - 1) {}
End Sub
Public Sub New(ByVal other As Double(,))
Me.m_cols = other.GetLength(0)
Me.m_rows = other.GetLength(1)
Me.m_elems = New Double(Me.m_rows * Me.m_cols - 1) {}
For i As Integer = 0 To Me.m_rows - 1
For j As Integer = 0 To Me.m_cols - 1
Me.m_elems(i * m_cols + j) = other(i, j)
Next
Next
End Sub
Default Public Property Item(ByVal index As Long) As Double
Get
Return Me.m_elems(index)
End Get
Set(ByVal value As Double)
Me.m_elems(index) = value
End Set
End Property
Default Public Property Item(ByVal row As Integer, ByVal col As Integer) As Double
Get
Return Me.m_elems(Me.m_cols * row + col)
End Get
Set(ByVal value As Double)
Me.m_elems(Me.m_cols * row + col) = value
End Set
End Property
Public Function Que(ByVal row As Integer, ByVal col As Integer) As Long
Return Me.m_cols * row + col
End Function
Public Sub DeQue(ByVal index As Long, ByRef row As Integer, ByRef col As Integer)
col = index Mod m_cols
row = index / m_cols
End Sub
Public ReadOnly Property Size() As Long
Get
Return m_elems.LongLength
End Get
End Property
Public ReadOnly Property RowCount() As Integer
Get
Return m_rows
End Get
End Property
Public ReadOnly Property ColumnCount() As Integer
Get
Return m_cols
End Get
End Property
Public ReadOnly Property InnerArray()
Get
Return m_elems
End Get
End Property
End Class
然后使用一些测试代码调用,如:
Sub Main()
Dim sw As New Stopwatch()
Dim rnd As New Random()
Const N As Integer = 10000
' Initialize with random numbers
Dim A As Double(,) = New Double(N, N) {}
For i As Integer = 0 To N - 1
For j As Integer = 0 To N - 1
A(i, j) = 10 * rnd.NextDouble() - 5
Next
Next
' Measure finding min through all the elements
Dim i_min As Integer = -1, j_min As Integer = -1
Dim x_min As Double = Double.MaxValue
sw.Start()
For i As Integer = 0 To N - 1
For j As Integer = 0 To N - 1
Dim x As Double = A(i, j)
If x_min > x Then
x_min = x
i_min = i
j_min = j
End If
Next
Next
sw.Stop()
Dim t_A As Long = sw.ElapsedTicks
Console.WriteLine("xmin={0} at ({1},{2})", x_min, i_min, j_min)
' Measure finding min thorugh flatten matrix
sw.Reset()
Dim B As New FlatMatrix(A)
x_min = Double.MaxValue
sw.Start()
Dim vals As Double() = B.InnerArray
For k As Long = 0 To N * N - 1
'Dim x As Double = B(k) ' This is slower
Dim x As Double = vals(k) ' This is faster
If x_min > x Then
x_min = x
B.DeQue(k, i_min, j_min)
End If
Next
sw.Stop()
Dim t_B As Long = sw.ElapsedTicks
Console.WriteLine("xmin={0} at ({1},{2})", x_min, i_min, j_min)
End Sub
我将10000x10000矩阵的时间缩短了25%。