| Algorithm 1: HNSW graph generation and search overview. | |
| ▷ Global Variables: | |
| 1: trainingDataset; | {Complete KNN training dataset} |
| 2: hnswGraph; | {HNSW multilayer graph} |
| 3: topLayer; | {Maximum, top layer of the hnswGraph} |
| 4: entryPoint; | {Entry point for the hnswGraph} |
| 5: mL; | {Normalization factor for level definition} |
| 6: ef; | {Number of nearest neighbors to use} |
| ▷ Function: | |
| 7: hnswGraphGeneration() | {Generate hnswGraph from trainingDataset} |
| Action: | |
| 8: for each element newElement from trainingDataset do | |
| 9: maxLayer ← ⌊−ln(uniform(0 ... 1)) × mL⌋; | {Compute the maximum layer of the element} |
| 10: if entryPoint = = nil then | {First inserted element.} |
| 11: topLayer ← maxLayer; | |
| 12: entryPoint ← newElement; | {Sets the entry point for the hnswGraph} |
| 13: next; | |
| 14: end if | |
| {Search the nearestNode already in hnswGraph starting from the topLayer until maxLayer} | |
| 15: nearestNodes = entryPoint; | |
| 16: for currentLayer ← topLayer ... maxLayer do | |
| 17: nearestNodes ← searchLayer(newElement, nearestNodes, currentLayer); | |
| 18: end for | |
| {Insert the newElement in all of the layers from maxLayer to layer 0} | |
| 19: for currentLayer ← maxLayer ... 0 do | |
| 20: nearestNodes ← searchLayer(newElement, nearestNodes, currentLayer); | |
| 21: neighbors ← selecNeighbors(newElement, nearestNodes, currentLayer); | |
| 22: insertElement(newElement, currentLayer, neighbors); | |
| 23: end for | |
| 24: if maxLayer > topLayer then | |
| 25: topLayer ← maxLayer; | |
| 26: entryPoint ← newElement; | {Set entry point for hnswGraph to newElement} |
| 27: end if | |
| 28: end for | |
| ▷ Function: | |
| 29: hnswSearch(element) | {Search nearest nodes for element from trainingDataset} |
| Action: | |
| 30: {Search the element in hnswGraph starting from the topLayer until 0} | |
| 31: nearestNodes = entryPoint; | |
| 32: for currentLayer ← topLayer . . . 0 do | |
| 33: nearestNodes ← searchLayer(newElement, currentLayer, nearestNodes); | |
| 34: end for | |
| 35: return nearestNodes; | |
| ▷ Function: | |
| 36: searchLayer(element, nearestNodes, layer) | {Search the ef nearest nodes for element in layer} |
| 37: | {using nearestNodes as enter points.} |
| Action: | |
| 38: nearestNodes ← {Greedy graph search algorithm as described in [16]} | |
| 39: return nearestNodes; | |