Optimize Nearest-Center Assignment Without Materializing NxKxD Distances
Mistral AIMachine Learning Engineer · OnsiteLast updated
This problem tests the ability to optimize memory usage in distance computations by leveraging algebraic expansion to avoid creating an intermediate (N, K, D) tensor.
Problem Statement
In a clustering task, you are given a set of $N$ data points $X$ and $K$ cluster centers $C$. Both $X$ and $C$ are represented as matrices of shape $(N, D)$ and $(K, D)$ respectively. Your task is to assign each point to the nearest center by minimizing the Squared Euclidean Distance: $||x_i - c_j||^2$.
Naively, one might compute the $(N, K, D)$ difference tensor, which is prohibitively expensive for large $N$ and $D$. Instead, implement a function that computes the assignment indices using the expanded form of the distance: $||x_i - c_j||^2 = ||x_i||^2 + ||c_j||^2 - 2(x_i \cdot c_j^T)$.
Function Signature
def assign_nearest_centers(X, C):
# X: np.ndarray of shape (N, D)
# C: np.ndarray of shape (K, D)
# returns: np.ndarray of shape (N,) containing indices of the nearest center
Constraints
- $N$ up to $10^6$, $D$ up to $512$, $K$ up to $10^3$.
- Use NumPy broadcasting.
- Avoid any intermediate structures larger than $(N, K)$.
Example
Input:
X = [[1, 2], [5, 5]]
C = [[0, 0], [6, 6]]
- Distance to centers for X[0]: $||[1,2]-[0,0]||^2 = 5$; $||[1,2]-[6,6]||^2 = 41$. Assign index 0.
- Distance to centers for X[1]: $||[5,5]-[0,0]||^2 = 50$; $||[5,5]-[6,6]||^2 = 2$. Assign index 1.
Output:
[0, 1]
Hints
Hint 1
Recall the algebraic expansion of the squared Euclidean distance: the distance is the sum of the squared norms of the vectors minus twice their dot product.
Hint 2
Compute the norms squared for X as an (N, 1) vector and the norms squared for C as a (1, K) vector to utilize broadcasting.
Hint 3
The matrix multiplication `np.dot(X, C.T)` will yield an (N, K) matrix, which is memory-efficient and sufficient to find the minimum for each row.
Follow-up questions
- How would you modify this implementation if N and D are so large that the (N, K) distance matrix itself exceeds memory capacity?
- What are the numerical stability implications of the expanded form $||x||^2 + ||c||^2 - 2(x \cdot c^T)$ compared to calculating $(x-c)^2$ directly?
- If we were performing this in a distributed setting (e.g., across multiple GPUs), how would you partition X and C to minimize communication overhead?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.