将计算应用于vb.net中的2d数组

时间:2012-03-23 14:16:37

标签: vb.net arrays

我有一个2d数组,我想对数组中的每个元素进行计算,然后返回导致最小值的索引。

我尝试迭代2d数组中的每个元素并运行计算。如果计算结果小于当前存储的最小值,则将其设置为最小值。

这样可行,但运行速度很慢,使解决方案成为非首发。它快速执行每个计算,但由于数组中元素的数量,整个数组的计算是愚蠢的长。

任何建议都会有所帮助。

1 个答案:

答案 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%。