JSFiddle - React, Tailwind, and code Playground

by ZhongluShi

JavaScript

exports = module.exports = kmeans;
 
//随机取k个中心
function randomCentroids(points, k, weightFun) {
    var centroids = new Array(k);
    var weights = new Array(k);
    var idxs = [];
    for (var i = 0; i < k; i++) {
        while (true) {
            var idx = parseInt(Math.random() * points.length);
            //下标不能重复 
            if (idxs.indexOf(idx) !== -1) continue;
            //权值不能相等 
            if (weights.indexOf(weightFun(points[idx])) !== -1) continue;
            break;
        }
 
        centroids[i] = points[idx];
        weights[i] = weightFun(points[idx]);
        idxs.push(idx);
    }
    return centroids;
}
 
//k-means++第一次选取中心 
function firstCentroids(points, k, weightFun) {
    var centroids = [];
    var m = k;
 
    //随机选出第一个中心 
    var first = points[parseInt(Math.random() * points.length)];
    centroids.push(first);
    m--;
 
    //选取剩下的中心 
    while (m > 0) {
        //每个点到最近中心的距离
        var dists = points.map(function(point) {
            var dists = centroids.map(function(centroid) {
                return Math.abs(weightFun(centroid) - weightFun(point))
            }) return Math.min.apply(null, dists);
        })
        //取上面的距离中最大者
        var max_dist = Math.max.apply(null, dists);
        var max_idx = dists.indexOf(max_dist);
 
        centroids.push(points[max_idx]);
        m--;
    }
 
    return centroids;
}
 
//新的k个中心
//计算每个中心的平均权值,取聚集中权值与平均权值最接近的为中心
function newCentroids(clusters, weightFun) {
    return clusters.map(function(cluster) {
        var sum = cluster.reduce(function(a, b) {
            return a + weightFun(b);
        },
        0) var mean = sum / cluster.length;
 
        var dists = cluster.map(function(point) {
            return Math.abs(weightFun(point) - mean);
        }) var min_dist = Math.min.apply(null, dists);
        return cluster[dists.indexOf(min_dist)];
    })
}
 
//聚类,返回k个聚集
function classify(points, centroids, weightFun) {
    var clusters = centroids.map(function() {
        return...