Skip to content

Commit

Permalink
feat(cluster): use a heap to group clusters
Browse files Browse the repository at this point in the history
  • Loading branch information
targos committed Sep 5, 2016
1 parent 4dc10a3 commit 8c70c9e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 28 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"should": "^11.1.0"
},
"dependencies": {
"heap": "^0.2.6",
"ml-distance-euclidean": "^1.0.0"
}
}
47 changes: 20 additions & 27 deletions src/Cluster.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const Heap = require('heap');

function Cluster () {
this.children = [];
this.distance = -1;
Expand Down Expand Up @@ -35,35 +37,26 @@ Cluster.prototype.cut = function (threshold) {
* @return {Cluster}
*/
Cluster.prototype.group = function (minGroups) {
if (minGroups < 1) throw new RangeError('Number of groups too small');
if (!Number.isInteger(minGroups) || minGroups < 1) throw new RangeError('Number of groups must be a positive integer');

const heap = new Heap(function (a, b) {
return b.distance - a.distance;
});

heap.push(this);

while (heap.size() < minGroups) {
var first = heap.pop();
if (first.children.length === 0) {
break;
}
first.children.forEach(child => heap.push(child));
}

var root = new Cluster();
root.children = this.children;
root.children = heap.toArray();
root.distance = this.distance;
root.index = this.index;
if (minGroups === 1)
return root;
var list = [root];
var aux;
var listLeafs = [];
while ((list.length + listLeafs.length) < minGroups && list.length !== 0) {
aux = list.shift();
if (aux.children)
list = list.concat(aux.children);
else
listLeafs.push(aux);
}
if (list.length === 0) throw new RangeError('Number of groups too big');
list = list.concat(listLeafs);
for (var i = 0; i < list.length; i++)
if (list[i].distance === aux.distance) {
list.concat(list[i].children.slice(1));
list[i] = list[i].children[0];
}
for (var j = 0; j < list.length; j++)
if (list[j].distance !== 0) {
var obj = list[j];
obj.children = obj.index;
}

return root;
};

Expand Down
2 changes: 1 addition & 1 deletion src/ClusterLeaf.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function ClusterLeaf (index) {
Cluster.call(this);
this.index = index;
this.distance = 0;
this.children = undefined;
this.children = [];
}

util.inherits(ClusterLeaf, Cluster);
Expand Down

0 comments on commit 8c70c9e

Please sign in to comment.