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?