func TestRematchPointersToClusters(t *testing.T) { c := RematchPointersToClusters([]*clustering.Cluster{}, []geo.Pointer{}, clustering.CentroidGeoDistance{}, 30) if c == nil { t.Errorf("result should not be nil") } if len(c) != 0 { t.Errorf("zero cluster input should result in zero cluster output") } testClusters := []*clustering.Cluster{ clustering.NewClusterWithCentroid(geo.NewPoint(1, 1)), clustering.NewClusterWithCentroid(geo.NewPoint(2, 2)), } testPointers := []geo.Pointer{ &event{Location: geo.NewPoint(1, 1)}, &event{Location: geo.NewPoint(1, 1)}, &event{Location: geo.NewPoint(2, 2)}, &event{Location: geo.NewPoint(3, 3)}, } c = RematchPointersToClusters(testClusters, testPointers, clustering.CentroidDistance{}, 1) if l := len(c[0].Pointers); l != 2 { t.Errorf("wrong number of pointers, got %d", l) } if l := len(c[1].Pointers); l != 1 { t.Errorf("wrong number of pointers, got %d", l) } c = RematchPointersToClusters(testClusters, testPointers, clustering.CentroidDistance{}, 2) if l := len(c[0].Pointers); l != 2 { t.Errorf("wrong number of pointers, got %d", l) } if l := len(c[1].Pointers); l != 2 { t.Errorf("wrong number of pointers, got %d", l) } }
// RematchPointersToClusters will take a set of pointers and map them to the closest cluster. // Basically creates a new cluster from that one point and does the ClusterDistance between them. // Will return a new list. func RematchPointersToClusters( clusters []*clustering.Cluster, pointers []geo.Pointer, distancer clustering.ClusterDistancer, threshold float64, ) []*clustering.Cluster { if len(clusters) == 0 { return []*clustering.Cluster{} } newClusters := make([]*clustering.Cluster, 0, len(clusters)) // clear the current members for _, c := range clusters { newClusters = append(newClusters, clustering.NewClusterWithCentroid(c.Centroid)) } // remap all the groupers to these new groups for _, pointer := range pointers { minDist := math.MaxFloat64 index := 0 pointerCluster := clustering.NewCluster(pointer) // find the closest group for i, c := range newClusters { if d := distancer.ClusterDistance(c, pointerCluster); d < minDist { minDist = d index = i } } if minDist < threshold { // leaves the center as found by the previous clustering newClusters[index].Pointers = append(newClusters[index].Pointers, pointer) } } return newClusters }