【问题标题】:Is binary search "commutative"?二进制搜索是“可交换的”吗?
【发布时间】:2021-06-07 06:09:24
【问题描述】:

背景

我有两个仪器,然后调用12,它们接收附近的第三个发射器产生的信号。这个发射器有一个已知的周期,T。这些仪器产生时间序列,其中每个时间戳是根据检测到信号时仪器时钟的当前时间。

我知道仪器3 中的时钟相对于仪器1 有一些缓慢的漂移,这导致了时间偏移。我的目标是确定这种漂移的大小。

我编写了下面的代码来实现这一点。我所做的只是遍历一个站产生的时间戳,并搜索其余站产生的最近的时间戳。由于脉冲发生器的周期为秒级,并且偏移量最多为几分之一秒,这应该给出正确的“匹配”。我写了一个非常简单的二分查找函数 (search()) 来找到最接近的匹配项。

奇怪的是,偏移量是通过迭代工具1 的时间戳确定的,搜索工具2 给出的偏移量与相反的偏移量不同(分别为循环#1 和#2)。如果我在向量A 中搜索与B 中某个值最接近的匹配项,那么不应该在B 中搜索与该匹配项最接近的匹配项吗?

我很可能会犯一些愚蠢的错误,但我可能无法确定我做错了什么。

我的代码

double search(std::vector<double> &vec, double value){
    
    auto it = lower_bound(vec.begin(), vec.end(), value);
    if(it == vec.end()) return vec.back();

    auto found = *it;

    if(it != vec.begin()){

        if(std::abs(value - *(--it)) <  std::abs(value - found)){
            found = *(--it);
        }

    }

    return found;

}

int main(){

    /*****GET DATA*****/
    ROOT::RDataFrame data1("/path/to/file");
    ROOT::RDataFrame data2("/path/to/file");

    auto timestamps1 = *(data1.Take<double>("timestamps"));
    auto timestamps2 = *(data2.Take<double>("timestamps"));

    TH1 *histo1 = new TH1D("histo","histo1",1000,-5,5);
    TH1 *histo2 = new TH1D("histo","histo2",1000,-5,5);

    /*****PERFORM SEARCH*****/
    for(auto& t: timestamps1){ // LOOP # 1
 
        histo1->Fill(search(timestamps2, t) - t); 

    }

    for(auto& t: timestamps2){ // LOOP # 2
 
        histo2->Fill(search(timestamps1, t) - t); 

    }

    /*****DRAW HISTOGRAMS*****/
    histo1->Draw();
    histo2->Draw();

}

【问题讨论】:

  • search 可以将it 递减两次,这似乎是无意的。此外,两个搜索循环在您迭代时搜索同一时间戳数组中的值。
  • @1201ProgramAlarm 感谢您的意见。不幸的是,我看不出search 如何将it 递减两次。你能详细说明一下吗?
  • if(std::abs(value - *(--it)) 语句中,递减一次。然后 if (found = *(--it);) 的主体第二次递减 it。所以found 的值与比较中使用的值不同,您可能会取消引用无效的迭代器。

标签: c++ algorithm binary-search


【解决方案1】:

如果我在向量 A 中搜索与 B 中某个值最接近的匹配项,那么在 B 中搜索与该匹配项最接近的匹配项不应该给出原始值吗?

不一定,不。

考虑以下两个向量:

A: 0 3 8 9 10
B: 2 5 6 9 11

然后,如果我在 A 中搜索与(比如说)5 最接近的匹配项,我会得到 3。

如果我在 B 中搜索与 3 最接近的匹配项,我会得到 2。

因此,如果您依赖于此,则必须寻找替代解决方案。

【讨论】:

    猜你喜欢
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2014-07-10
    • 2014-03-22
    相关资源
    最近更新 更多