1

私がやっていることよりもこれを簡単にするアルゴリズムがあるに違いありません...

私が持っているのは、それぞれに 2 つの列を持つ 2 つの配列です。両方の 1 つの列はタイムスタンプであり、両方のもう 1 つの列は測定値です。

これを次の 1 つの配列に変換する必要があります: タイムスタンプ、測定値 1、測定値 2

問題は、タイムスタンプが正確に一致しないことが多いことです。ある期間、1 つの配列で値が完全に欠落している場合や、タイムスタンプがわずかな量だけずれている場合があります (両方の測定値を同じタイムスタンプに割り当てても問題ないほど重要ではありません)。

このあいまいなマージ操作を行うよく知られた方法はありますか? シンプルなパブリックドメイン機能??

4

1 に答える 1

1

次の質問を自問することから始めます: 配列の要素数は同じですか? 同じタイムスタンプを持つ 2 つのアイテムをどのように結合しますか? タイムスタンプが異なる 2 つのアイテムをどのように結合しますか?

おそらく、アルゴリズムを自分で作成する必要があります。このようなものは簡単に実装できます。

  1. まず、各配列をタイムスタンプ順で個別に並べ替えます。
  2. 各入力配列の先頭にそれぞれ 2 つの反復子を宣言し、空の出力配列を宣言します。
  3. 次に、タイムスタンプが最も古い配列を確認します。それを EARLY と呼び、もう 1 つは LATE と呼びます。
    • EARLY が LATE に近い (一定の定数より少ない) 場合は、マージ操作を適用し、結果を出力配列の末尾に挿入します。両方の反復子をインクリメントし、3 に戻ります。
    • そうでなければ、EARLY は LATE とはほど遠いものです。おそらく前の値を繰り返すか、何らかの関数を使用して補間することにより、LATE 配列の欠損値を処理する必要があります。出力配列に値を挿入するかどうかを決定します。この場合、EARLY 配列反復子をインクリメントするだけで、3 に戻ります。
  4. どちらか一方の配列の終わりに達した場合、もう一方の配列の残りは LATE です。これを欠損値として解釈し、測定値を繰り返すか内挿することもできます。
  5. 出力配列を返します。

OutputArray merge(InputArray& a, InputArray& b) {
    InputArray::iterator a_it = a.begin();
    InputArray::iterator b_it = b.begin();
    while(a_it != a.end() && b_it != b.end()) {
        InputArray::iterator& early = *a_it.timestamp < *b_it.timestamp ? a_it : b_it;
        InputArray::iterator& late = *a_it.timestamp < *b_it.timestamp ? b_it : a_it;
        if(*late.timestamp - *early.timestamp < TIMESTAMP_CLOSE_ENOUGH) {
            output.timestamp = (*late.timestamp + *early.timestamp) / 2; // mean value
            output.measure1 = *a_it.measure;
            output.measure2 = *b_it.measure;
            outputArray.push_back(output);
            a_it++; b_it++;
        }
        else {
            output.timestamp = *early.timestamp;
            output.measure1 = *a_it.timestamp < *b_it.timestamp ? *a_it.measure : outputArray.back.measure1; // previous value if missing
            output.measure2 = *a_it.timestamp < *b_it.timestamp ? outputArray.back.measure2 : *b_it.measure;
            outputArray.push_back(output);
            early++;
        }
    }

    InputArray::iterator& late = a_it != a.end() ? a_it : b_it;
    InputArray::iterator late_end = a_it != a.end() ? a.end() : b.end();
    while(late != late_end) {
            output.timestamp = *late.timestamp;
            output.measure1 = a_it != a.end() ? *a_it.measure : outputArray.back.measure1; // previous value if missing
            output.measure2 = a_it != a.end() ? outputArray.back.measure2 : *b_it.measure;
            outputArray.push_back(output);
            late++;
    }
    return outputArray;
}
于 2011-04-19T22:40:10.927 に答える