# Visualizing HNSW layer structure
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
fig, ax = plt.subplots(figsize=(12, 8))
# Define layers
layers = [
{"name": "Layer 2 (Top)", "y": 7, "nodes": 3, "color": "#e74c3c"},
{"name": "Layer 1", "y": 4.5, "nodes": 10, "color": "#3498db"},
{"name": "Layer 0 (Bottom)", "y": 2, "nodes": 25, "color": "#2ecc71"}
]
# Draw layers
for layer in layers:
# Draw nodes
x_positions = np.linspace(1, 11, layer["nodes"])
y_pos = layer["y"]
for x in x_positions:
circle = plt.Circle((x, y_pos), 0.15, color=layer["color"], alpha=0.7)
ax.add_patch(circle)
# Draw some connections (simplified)
if layer["nodes"] > 1:
for i in range(len(x_positions) - 1):
if i % 2 == 0 and i + 1 < len(x_positions):
ax.plot([x_positions[i], x_positions[i+1]], [y_pos, y_pos],
'k-', alpha=0.3, linewidth=1)
# Label layer
ax.text(-0.5, y_pos, layer["name"], fontsize=11, fontweight='bold',
va='center', ha='right')
# Draw vertical connections between layers
ax.annotate('', xy=(6, 4.5), xytext=(6, 7),
arrowprops=dict(arrowstyle='->', color='gray', lw=2, alpha=0.5))
ax.annotate('', xy=(6, 2), xytext=(6, 4.5),
arrowprops=dict(arrowstyle='->', color='gray', lw=2, alpha=0.5))
# Add annotations
ax.text(6, 8.5, 'Sparse Layer\n(Fast Navigation)', ha='center', fontsize=10,
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
ax.text(6, 0.5, 'Dense Layer\n(Precise Search)', ha='center', fontsize=10,
bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.5))
# Add search path illustration
search_path_x = [2, 3, 5.5, 6, 6.2]
search_path_y = [7, 4.5, 4.5, 2, 2]
ax.plot(search_path_x, search_path_y, 'r--', linewidth=2.5, alpha=0.7,
marker='o', markersize=8, label='Example Search Path')
ax.set_xlim(-1, 12)
ax.set_ylim(0, 9)
ax.set_aspect('equal')
ax.axis('off')
ax.legend(loc='upper right', fontsize=11)
ax.set_title('HNSW Hierarchical Structure', fontsize=14, fontweight='bold', pad=20)
plt.tight_layout()
plt.savefig('hnsw_structure.png', dpi=100, bbox_inches='tight')
plt.show()
print("\n🏗️ HNSW Structure Explained:")
print("=" * 60)
print("• Top layers: Few nodes, long-distance hops (coarse search)")
print("• Bottom layer: All nodes, short hops (fine-grained search)")
print("• Search starts at top and descends layer by layer")
print("• Each layer acts as a 'highway' to quickly reach the target region")
print("=" * 60)