k-mean均值聚类-JavaScript

逻辑思路

1、选举第一位大哥DG1,大哥离每个小弟的平均距离最短

2、选举第二位大哥DG2,大哥离每个小弟的平均距离最短,DG2与老大哥们DG1的距离大于平均距离,则是新大哥,否则分到已存在的大哥类别中

3、重复所有过程,选举出所有大哥

const arr=[
  [10,2,3,4],
  [11,2,3,4],
  [12,2,3,4],
  [2,2,3,4],
  [3,2,3,4],
  [4,2,3,4],
  [5,2,3,4],
]
//选举第一位大哥DG1,大哥离每个小弟的平均距离最短
//选举第二位大哥DG2,大哥离每个小弟的平均距离最短,DG2与老大哥们DG1的距离大于平均距离,则是新大哥,否则分到已存在的大哥类别中
//重复所有过程,选举出所有大哥
function findTag(item,tagArr) {
  let index=-1;
  for(let i=0;i<tagArr.length;i++){
    const dis=getDis(item,tagArr[i].item);
    if(dis*tagArr[i].fm<=tagArr[i].fz){
      index=i;
      break;
    }
  }
  return index;
}
function getDis(item1,item2) {
  return Math.abs(item1[0]-item2[0])
}
function getTag(arr) {
  const tagArr=[]
  const farArr=[]
  while(arr.length>2){
    let fm=arr.length;
    let fz=-1;
    let fzi=-1;
    for(let i=0;i<fm;i++){
      let dis=0;
      for(let j=0;j<fm;j++){
        if(i!==j){
          dis=dis+getDis(arr[i],arr[j])
        }
      }
      if(i===0){
        fz=dis
        fzi=0;
      }else if(fz>dis){
        fz=dis;
        fzi=i;
      }
    }
    const tag={
      item:arr.splice(fzi,1)[0],
      fz:fz,
      fm:fm,
      child:[]
    }
    const index=findTag(tag.item,tagArr);
    if(index===-1){
      tagArr.push(tag);
    }else{
      tagArr[index].child.push(tag.item)
    }
  }
  for(let i=0;i<arr.length;i++){
    const index=findTag(arr[i],tagArr);
    if(index===-1){
      farArr.push(arr[i])
    }else{
      tagArr[index].child.push(arr[i])
    }
  }
  return {
    tagArr,
    farArr
  };
}

const tag=getTag(arr)
console.log(JSON.stringify(tag))

{"tagArr":[{"item":[5,2,3,4],"fz":24,"fm":7,"child":[[4,2,3,4],[3,2,3,4],[2,2,3,4]]},{"item":[10,2,3,4],"fz":24,"fm":6,"child":[[11,2,3,4],[12,2,3,4]]}],"farArr":[]}

原文地址:https://www.cnblogs.com/caoke/p/13372415.html