C++ 如何最大限度地降低更新收集数据的节点序列的成本?

C++ 如何最大限度地降低更新收集数据的节点序列的成本?,c++,algorithm,graph,C++,Algorithm,Graph,我有一个k节点序列N1,N2,N3Nk每一个都会连续命中(可能会跳过) 每次访问其中一个节点时,我需要+=从上一个节点到达该节点所需的时间。棘手的是,如果我回到N1而没有到达Nk,那么这些+=更新应该被删除 一种方法是在每个节点中保留两个量:x和y。当我们跳转节点时,我们将+=值转换为y。如果我们到达N1我们将y重置为0。然而,如果我们到达Nk,我们会对每个节点执行x+=y 问题是,每次我们点击Nk时,它都需要一个O(n)操作——即使序列在不点击Nk的情况下返回到N1可能不是常见的情况。是否有一

我有一个k节点序列
N1
N2
N3
<代码>Nk每一个都会连续命中(可能会跳过)

每次访问其中一个节点时,我需要+=从上一个节点到达该节点所需的时间。棘手的是,如果我回到
N1
而没有到达
Nk
,那么这些+=更新应该被删除

一种方法是在每个节点中保留两个量:x和y。当我们跳转节点时,我们将+=值转换为y。如果我们到达
N1
我们将y重置为0。然而,如果我们到达
Nk
,我们会对每个节点执行
x+=y

问题是,每次我们点击
Nk
时,它都需要一个O(n)操作——即使序列在不点击
Nk
的情况下返回到
N1
可能不是常见的情况。是否有一种更聪明的方法可以更有效地做到这一点,而不必在每次迭代结束时都执行O(n)“提交”

考虑这个有3个节点的示例:
N_1
N_2
N_3

左边显示迭代中命中的节点的子序列,右边显示什么 累积计数器应包含:

(N_1, 2)(N_2, 3)(N_3, 7) ---> (N_1, 2)(N_2, 3)(N_3, 7)
(N_1, 4)(N_3, 2)         ---> (N_1, 6)(N_2, 3)(N_3, 9)
(N_1, 6)(N_2, 3)         ---> (N_1, 4)(N_2, 3)(N_3, 2) //nothing changes as this was an "invalid" op because we never hit the end node
etc...

您可以在每个节点中维护两个累加器(
accum_[2]
),以及一个全局1位计数器(
k_计数器
),该计数器在到达第k个节点时递增。然后保持不变,即
accum_u[k_counter]
对每个节点始终具有正确的累积值。在这个方案中,如果您跳过节点,您将被迫访问它们,并对它们执行
node[i]+=0
。这个需求可以通过访问计数器优化,我将把它作为练习留作讨论:-)


我不认为这与我所说的相符。我用一个示例过程编辑了我的问题,但只有在不包括结束节点的子序列上发生的增量必须被忽略,而所有其他节点都必须被忽略。不过,上述内容将在每次到达最后一个节点时切换累加器。@PalaceChan:您的示例显示了一个奇怪的要求。为什么N_1从6过渡到4,而N_2保持在3?在任何情况下,我认为用一个全局标志来选择你的反行为的想法可以适应你的具体问题。如果你愿意的话,我可以把我的答案简化为这个暗示。
enum { K = 100 };
struct Node *node;
struct Node {
    static bool k_counter;
    unsigned accum_[2];
    unsigned id_;
    Node () : accum_(), id_(this - node + 1) {}
    void operator += (unsigned time_data) {
        accum_[!k_counter] = accum_[k_counter] + time_data;
        if (id_ == K) k_counter = !k_counter;
    }
    operator unsigned () const { return accum_[k_counter]; }
};
bool Node::k_counter;

node = new Node[K];