3

私は最適化アルゴリズムに取り組んでおり、(アルゴリズムによって生成された) データの一部を という 2 次元配列に格納する必要があります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)は、指定されたベクトルのパラメーター値を返します。

私の質問:に挿入する
より高速な (つまり、より効率的な) 方法はありますか? paramsmatrix

4

4 に答える 4

4

効率が必要な場合は、「プレーンな」配列に頼ることが間違いなく最良の選択肢です。他の選択肢 (コレクション、リストなど) と比較して非常に効率的である理由は、必要な最小限の情報が含まれているためです。情報を簡単/迅速にソートしたり、データを取得するための複雑なクエリを作成したりできる高度な関数が必要な場合は、配列に頼るべきではありません。

私はいつもあなたが書いたようなコードに頼っていますが、速度の問題は一度もありません (これは本当に速いです)。他に選択肢がないことを確認するために簡単な調査を行いましたが、何も見つかりませんでした。最も近いのは ですがArray.Copy、配列が同じ次元の場合にのみ機能します (個人的には、1D 配列でのみ使用します)。いずれにせよ、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 に答える