Hedged Requests Expected Completion Time
Problem Statement
To cut tail latency, an agent can hedge: send a backup request if the first has not returned by a delay d. Given each replica's response time, compute when the overall result arrives under a hedging policy.
Background
There are n replicas with known latencies lat[i]. The policy: launch replica 0 at time 0. If it has not completed by time d, launch replica 1 at time d; if neither has completed by 2d, launch replica 2 at 2d; and so on (one new hedge every d until all launched). Replica i (0-indexed) is launched at time i*d and completes at i*d + lat[i]. The overall result is the minimum completion time across all launched replicas. All replicas end up launched eventually (over an unbounded deadline), so consider every replica's i*d + lat[i].
Your Task
def hedged_completion(lat, d):
Return the earliest overall completion time (float), rounded to 4 decimals.
Input Format
- lat (list of floats), d (float).
Output Format
- A float rounded to 4 decimals.
Sample
print(hedged_completion([10.0, 2.0], 1.0))
Output:
3.0
Example:
print(hedged_completion([10.0, 2.0], 1.0))
3.0
- Identify the launch and completion times for each replica based on the hedging policy where replica i starts at i⋅d.
- For replica 0, the launch time is 0⋅1.0=0.0, so its completion time is 0.0+10.0=10.0.
- For replica 1, the launch time is 1⋅1.0=1.0, so its completion time is 1.0+2.0=3.0.
- The overall result is the minimum completion time among all replicas, which is min(10.0,3.0)=3.0.
- The final output is 3.0
Constraints:
- Replica
ilaunches ati*dand finishes ati*d + lat[i]. - Overall completion is the min over all replicas.
- Round to 4 decimals;
latis non-empty.
1. Background Knowledge
Request hedging is a latency-reduction technique used in distributed systems. Instead of waiting indefinitely for a single slow replica, the client issues a duplicate (or "hedge") request to a second replica after a timeout. The first response to arrive is accepted, and the others are cancelled. This trades a small amount of extra compute for a significant reduction in tail latency, because the worst-case wait is bounded by the faster of the two replicas rather than the slower one.
In this problem the hedging policy is staggered: replica i is not launched at time 0 but at time i⋅d, where d is the hedge interval. This models a system that adds one more backup per interval until all replicas have been tried. Each replica i therefore completes at:
ti=i⋅d+lat[i]The overall result is delivered as soon as any replica finishes, so the completion time is miniti. Because the deadline is unbounded, every replica is eventually launched, and we must consider all n candidates.
A useful mental model: think of each replica as a "race" that starts at a different time. The winner is the one whose start time plus its own latency is smallest.
2. Algorithm Approach
This is a brute-force minimization over n candidates. There is no sorting, binary search, or dynamic programming required. For each index i from 0 to n−1, compute the completion time i⋅d+lat[i] and track the minimum. The problem reduces to a single linear scan.
The key insight is that the launch schedule is deterministic and independent of the latencies, so there is no need to simulate events in chronological order. You can evaluate every replica's finish time directly and take the minimum.
3. Step-by-Step Strategy
- Validate inputs: Ensure lat is a non-empty list and d is a non-negative float.
- Initialize a variable best to a large value (e.g., float('inf')).
- Loop over each index i in range(len(lat)):
- Compute finish = i * d + lat[i].
- If finish < best, update best = finish.
- Round the result to 4 decimal places using round(best, 4).
- Return the rounded float.
Pseudocode sketch:
def hedged_completion(lat, d):
best = float('inf')
for i in range(len(lat)):
finish = i * d + lat[i]
if finish < best:
best = finish
return round(best, 4)
4. Common Pitfalls
- Off-by-one in launch time: Replica i launches at i⋅d, not (i+1)⋅d. Replica 0 launches at time 0.
- Forgetting to consider all replicas: Even if an early replica finishes quickly, a later replica with a very small latency could finish even earlier. You must scan all n entries.
- Rounding errors: Use round(value, 4) at the very end, not during intermediate comparisons. Rounding mid-loop can cause incorrect minimum selection.
- Integer vs. float division: In Python 3, / always produces a float, but if d or lat[i] are integers, ensure the multiplication i * d is treated as float arithmetic. This is usually automatic, but be cautious if mixing types.
- Empty list: If lat is empty, the problem is undefined. Decide on a sensible default (e.g., return 0.0 or raise an error) and document it.
- Negative latencies: While physically meaningless, the formula still works mathematically. If the problem guarantees non-negative latencies, no extra check is needed.
5. Time & Space Complexity
- Time complexity: O(n), where n=len(lat). A single pass computes n finish times and tracks the minimum.
- Space complexity: O(1) auxiliary space. Only a constant number of variables (best, loop index) are used regardless of input size. The input list itself is not modified.