I've got a directed graph (N, A), where each node n[i] has a value v[i] and a threshold t[i]. For each arrow (n[i], n[j]), the invariant v[i] <= v[j] holds. I need to efficiently implement the following operations:
increaseThreshold(i, x): Sett[i] = max(t[i], x). That's trivial and only for completeness here.increaseValue(i, x): Setv[i] = max(v[i], x)and increase other values as needed so that the above invariant holds.evaluate(i): return true ifv[i] < t[i]
The most straightforward implementation would store v[i], t[i], and the outgoing arrows with each node. On increaseValue(i, x), it'd propagate the value along all outgoing arrows (using a set of "open" nodes like many other graph algorithms do). With v[i] stored with each node, evaluate(i) is trivial.
As increaseValue is much more frequent than the other operations, this eager approach seems to be wasteful. So I wonder, if some lazy propagation where v[i] is recomputed as needed could be more efficient. For this, I'd maintain w[i] as the maximum of all x from increaseValue(i, x) and compute v[j] on the fly when evaluate(j) needs it. It can be computed as the maximum of w[i] over all nodes n[i] from which there's a path to n[j]. Actually, once I know that v[j] >= t[j],
the exact value v[j] doesn't matter and I can stop the computation.
Unfortunately, this lazy algorithm is very inefficient, so it doesn't pay off even with increaseValue being orders of magnitude more frequent than evaluate.
I imagine, some "partially lazy" algorithm could be better, but that's just my intuition and I can't make any progress with it.
Is this somehow a well-known problem? Any other idea?
increaseThresholdhas to propagate? It may update t[i] but why it influences other nodes?