DGIM

@ Aaron Aug. 1, 2023

**DGIM Algorithm Explanation**

The DGIM (Datar-Gionis-Indyk-Motwani) Algorithm is designed for estimating the number of '1's in the last \(N\) bits of a binary stream, especially when \(N\) is large. It provides an approximation with bounded error while using limited memory.

---

**Basic Idea**:

  • **Exponential Bucketing**:

Instead of maintaining a count of every '1' in the window, DGIM maintains "buckets" where each bucket summarizes a segment of the stream. Notably:

- Each bucket records the count of consecutive '1's seen.

- Buckets have sizes (or counts of '1's) that are powers of 2. This means we might have buckets of size 1, 2, 4, 8, 16, etc.

- To limit memory, DGIM ensures at most two buckets of the same size. If a third bucket of a given size is created, the oldest two are merged to form a bucket of the next larger size.

  • **Timestamping**:

Each '1' in the stream has an associated timestamp, indicating when it appeared. Instead of recording the exact timestamp, which can be large, DGIM records the timestamp modulo \(N\) (the window size). This ensures that any relevant timestamp can be represented using \(O(\log_2 N)\) bits.

---

**Example Visualization**:

Given the stream segment: `1001010110001011010101010101011010101010101110101010111010100010110010`

And the window size \(N\):

As '1's appear in the stream, we record them as individual buckets. But as more '1's appear, we start combining buckets:

  1. If two size-1 buckets are adjacent and a new '1' appears, we merge the oldest two size-1 buckets into a size-2 bucket, and the new '1' becomes a new size-1 bucket.
  2. If three size-2 buckets exist and another size-2 bucket is about to be formed due to merging two size-1 buckets, we merge the two oldest size-2 buckets into a size-4 bucket.

**Timestamping**:

Using our example and assuming a window size of 40:

- When the timestamp is 123 for a '1', instead of recording 123, we record the timestamp modulo 40. So, \(123 \mod 40 = 3\). Hence, we record the timestamp as 3.

---

**Use Case**:

DGIM is particularly useful for sliding window queries over infinite data streams. For example, if you wanted to know how many '1's appeared in the last million bits, but the stream itself is billions of bits long and still growing, DGIM provides an efficient way to answer this with bounded error without remembering the entire stream.

---

**Conclusion**:

The DGIM algorithm allows us to estimate the count of '1's in a sliding window over a binary stream using limited memory. It does this by maintaining exponential-sized buckets and using a modulo-based timestamping system, making it efficient and effective for large streaming data.

**Key Concepts**:

  1. **Buckets**: DGIM uses "buckets" to keep track of sequences of '1's. Each bucket represents a segment of the stream containing a certain number of consecutive '1's.
  2. **Exponential Bucket Sizes**: Buckets can be of sizes that are powers of 2: 1, 2, 4, 8, etc. This means, for example, that a size-2 bucket represents a segment with two consecutive '1's.
  3. **Bucket Limit**: At most, there can be two buckets of the same size. If adding a new '1' causes a third bucket of the same size, the oldest two are merged.

**Detailed Example**:

Let's break down the given stream: `10010101100010110101`

  1. **Initialization**: Our buckets are empty.

  1. **Processing the stream**:

* Reading `1`: Add a bucket of size 1. **Buckets**: [1]

* Reading `0`: Continue.

* Reading `01`: Add a bucket of size 1. **Buckets**: [1, 1]

* Reading `01`: Add a bucket of size 1. Now we have three size-1 buckets. Merge the oldest two to create a size-2 bucket. **Buckets**: [2, 1]

* Reading `01`: Add another bucket of size 1. **Buckets**: [2, 1, 1]

* Reading `1000`: Continue until next '1'.

* Reading `1`: Add a bucket of size 1. Now again, we have three size-1 buckets. Merge the oldest two. **Buckets**: [2, 2, 1]

* Reading `011`: For the two '1's, add two size-1 buckets. After adding the first, we must merge the existing two size-1 buckets into a size-2 bucket. After adding the second, we again merge to form another size-2 bucket. **Buckets**: [2, 2, 2, 1]

* And so on...

**Timestamping**:

Instead of storing the exact position of each '1' in the bucket, DGIM stores a compressed version: the position modulo \(N\), where \(N\) is the window size we're considering. If \(N=20\) and the '1' was at position 23 in the stream, then we'd store the timestamp as \(23 \mod 20 = 3\).

For our stream (`10010101100010110101`), if we assume \(N=20\), the timestamp for the first '1' would be 1, for the second '1' it would be 3, for the third '1' it would be 5, and so on.

**Why is DGIM Useful?**

Let's say you suddenly want to know: "How many '1's were in the last 10 bits?" Instead of counting from the raw stream, you can approximate by summing the sizes of the buckets that fall within the last 10 bits using the stored timestamps.

**Conclusion**:

DGIM provides an efficient way to estimate the number of '1's in a sliding window over a binary stream. By using exponential bucket sizes and a modulo-based timestamping system, it ensures that the memory used doesn't grow with the size of the stream. Instead, the memory used grows logarithmically with the window size \(N\), making it suitable for real-time applications with massive streaming data.

  1. At most two buckets of the same size.
  2. Merge the oldest two buckets of the same size when a third one of that size is created.
  3. Buckets represent counts of '1's, so a 0 in the stream will not create a new bucket but will increment the timestamp.

Given:

- Current time: 200

- Window size (N): 60

- Current Buckets: (16, 148) (8, 162) (8, 177) (4, 183) (2, 192) (1, 197) (1, 200)

- Input for clocks 201-210: 0101010101

**Processing the Input**:

- **At Time 201**:

- Input = 0, no change in buckets, just increase the time.

- Drop any bucket outside the window of 60. Currently, all buckets are within 141 to 200, so all are relevant.

(16, 148) (8, 162) (8, 177) (4, 183) (2, 192) (1, 197) (1, 200)

- **At Time 202**:

- Input = 1, add a new bucket (1, 202).

- Now, we have three size-1 buckets: (1,197), (1,200), and (1,202).

- Merge the oldest two to form a size-2 bucket: (2,200).

- Buckets: (16, 148) (8, 162) (8, 177) (4, 183) (2, 192) (2, 200) (1, 202)

- **At Time 203**:

- Input = 0, no change in buckets other than time.

- Drop buckets outside the window of 60. Drop (16, 148) as it's outside the window 143-203.

- Buckets: (8, 162) (8, 177) (4, 183) (2, 192) (2, 200) (1, 202)

- **At Time 204**:

- Input = 1, add a new bucket (1, 204).

- Merge oldest two size-1 buckets (2,202) and (1,204) to get a size-2 bucket (2,204).

- Buckets: (16, 148)(8, 162)(8, 177)(4, 183)(2, 192)(2, 200), (1, 202), (1, 204)

- **At Time 205**:

- Input = 0, no change in buckets other than time.

- **At Time 206**:

- Input = 1, add a new bucket (1, 206).

- Merge oldest two size-1 buckets (2,204) and (1,206) to get a size-2 bucket (2,206).

- However, now we have three size-2 buckets: (2,192), (2,200), and (2,206).

- Merge the oldest two size-2 buckets (2,192) and (2,200) to get a size-4 bucket (4,200).

- Buckets: (16, 148)(8, 162)(8, 177)(4, 183)(4, 200), (2, 204), (1, 206)

- **At Time 207**:

- Input = 0, no change in buckets other than time.

- **At Time 208**:

- Input = 1, add a new bucket (1, 208).

- Merge oldest two size-1 buckets (2,206) and (1,208) to get a size-2 bucket (2,208).

- Buckets: (8, 162) (8, 177) (4, 183) (4, 200) (2, 208)

- **At Time 209**:

- Input = 0, no change in buckets other than time.

- **At Time 210**:

- Input = 1, add a new bucket (1, 210).

- Merge oldest two size-1 buckets (2,208) and (1,210) to get a size-2 bucket (2,210).

- However, now we have three size-2 buckets: (2,208), (2,210), and a previously existing one.

- But remember that we've already merged (2,208) and (1,210) to create (2,210). Thus, we do not have three size-2 buckets.

- Buckets: (8, 162) (8, 177) (4, 183) (4, 200) (2, 210)

**Final Sequence of Buckets at Time 210**:

(8, 162) (8, 177) (4, 183) (4, 200) (2, 210)

>

评论 · Comments (0)

需要 MetaMask 等以太坊钱包,签名不花 gas。