package flare.analytics.cluster {
import flare.animate.Transitioner;
import flare.util.math.IMatrix;
import flare.vis.data.Data;
import flare.vis.data.DataList;
/**
* Hierarchically clusters a set of items using agglomerative clustering.
* This approach continually merges the most similar items (those with the
* minimum distance between them) into clusters, until all items have been
* merged into a final resulting cluster tree. Clients must provide a
* distance function that takes as input two DataSprite
* instances and returns a Number
.
*
This class supports both minimum-link clustering, in which the * distance between clusters is measured as the distance between the two * nearest items in each cluster, and maximum-link clustering, in * which distance is measured using the two furthest items in each cluster. *
*For a richer description, see * * the Wikipedia article on Cluster Analysis. *
*/ public class AgglomerativeCluster extends HierarchicalCluster { /** A function defining distances between items. */ public var distance:Function = null; /** If true, minimum-link distances are computed between clusters. * If false, maximum-link distances are computed between clusters. */ public var minLink:Boolean = true; // -------------------------------------------------------------------- /** * Creates a new agglomerative cluster instance */ public function AgglomerativeCluster(group:String=Data.NODES) { this.group = group; } /** @inheritDoc */ public override function operate(t:Transitioner=null):void { calculate(visualization.data.group(group), distance); } /** * Calculates the community structure clustering. As a result of this * method, a cluster tree will be computed and graph nodes will be * annotated with both community and sequence indices. * @param list a data list to cluster * @param d a distance function */ public function calculate(list:DataList, d:Function):void { compute(list.distanceMatrix(d)); _tree = buildTree(list); labelNodes(); } /** Computes the clustering */ private function compute(Z:IMatrix):void { _merges = new MergeEdge(-1, -1); _qvals = []; _size = Z.rows; var m:MergeEdge = _merges; var i:uint, j:uint, k:int, s:int, t:int, ii:uint, jj:uint; var min:Number, a:uint, b:uint, bb:uint, imax:int; var v:Number, sum:Number=0, Q:Number=0, Qmax:Number=0, dQ:Number; // initialize matrix var N:int = Z.rows; var idx:/*int*/Array = new Array(N); for (i=0; i