function findPivots(dataSet, sampleSet, remainderSet) { var distance = calculateDistancePoker; // Initialize var numBuckets = Math.floor(Math.sqrt(sampleSet.length)), numPivots = Math.floor(Math.sqrt(sampleSet.length)), parents = [], maxDists = [], bucketWidths = [], pivotsBuckets = []; var pivots = createRandomSample(dataSet, sampleSet.length, numPivots); for (var i = 0; i < numPivots; i++) { pivotsBuckets[i] = []; for (var j = 0; j < numBuckets; j++) { pivotsBuckets[i][j] = []; } } // Pre-processing var fullDists = [] for (var i = 0; i < sampleSet.length; i++) { fullDists[i] = []; } for (var j = 0, maxDist = -1; j < numPivots; j++) { var c1 = pivots[j]; for (var i = 0; i < sampleSet.length; i++) { var c2 = sampleSet[i]; if (c1 !== c2) { var dist = distance(c1, c2); // console.log(dist, c1, c2); if (dist > maxDist) { maxDist = dist; } fullDists[i][j] = dist; } else { fullDists[i][j] = 0.0001; } } maxDists.push(maxDist); bucketWidths.push(maxDist / numBuckets); } // console.log(fullDists); for (var j = 0; j < numPivots; j++) { var bucketWidth = bucketWidths[j]; for (var i = 0; i < sampleSet.length; i++) { var tmp = pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)]; // pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)].push(sampleSet[i]); // console.log(tmp, i, j, bucketWidth, Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)); tmp.push(sampleSet[i]); } } // Find parents for (var r = 0, bNum, minIndex; r < remainderSet.length; r++) { var node = remainderSet[r]; var clDist = Number.MAX_VALUE; for (var p = 0; p < numPivots; p++) { var comp = pivots[p]; var bucketWidth = bucketWidths[p]; if (node !== comp) { var dist = distance(node, comp); bNum = Math.floor((dist - 0.0001) / bucketWidth); if (bNum >= numBuckets) { bNum = numBuckets - 1; } else if (bNum < 0) { bNum = 0; } var bucketContents = pivotsBuckets[p][bNum]; for (var w = 0; w < bucketContents.length; w++) { var c1 = bucketContents[w]; if (c1 != node) { dist = distance(c1, node); if (dist <= clDist) { clDist = dist; minIndex = bucketContents[w]; } } } } } parents.push(minIndex); } return parents; } function createRandomSample(nodes, max, size) { var randElements = []; for (var i = 0; i < size; ++i) { // Stop when no new elements can be found. if (randElements.size >= nodes.length) { break; } var rand = Math.floor((Math.random() * max)); // If the rand is already in random list or in exclude list // ignore it and get a new value. while (randElements.includes(rand)) { rand = Math.floor((Math.random() * max)); } randElements.push(nodes[rand]); } return randElements; }