数据自动分类器,分成2类
/* * 分类器*/ class ArraySplit { constructor(getDis) { this.getDis=getDis; } //计算元素key的最大长度dis、最大长度对应的元素arr getMaxKey(key1,indexArr,sArr) { const getDis=this.getDis let maxDis=0; let allDis=0; let arr=[] indexArr.forEach(function (key2) { const dis=getDis(sArr[key1],sArr[key2]) allDis=allDis+dis; if(dis>maxDis){ arr=[key2] maxDis=dis }else if(dis===maxDis){ arr.push(key2) } }) return { key:key1, dis:maxDis, allDis:allDis, arr } } //获取数据分割线(两个风格点) getSplitLine(indexArr,sArr) { const rNum=0|Math.random()*indexArr.length; //找到对边的点 let line=this.getMaxKey(indexArr[rNum],indexArr,sArr) let isMax=false; let moreKey; let maxDis=0; while (!isMax){ taskArr.push(line.key) isMax=true; maxDis=0; for(let i=0;i<line.arr.length;i++){ const key=line.arr[i] if(key!==line.key){ const m2=this.getMaxKey(key,indexArr,sArr) const dis=m2.allDis; if(m2.dis>line.dis||m2.dis===line.dis&&m2.arr.length>line.arr.length||m2.dis===line.dis&&m2.arr.length===line.arr.length&&m2.allDis>line.allDis){ line=m2 isMax=false; break }else if(dis>maxDis){ maxDis=dis moreKey=key } } } } let lessKey=line.key; return [lessKey,moreKey,line.dis] } splitByIndex(indexArr,sArr){ if(indexArr.length<10){return indexArr;} const getDis=this.getDis const line=this.getSplitLine(indexArr,sArr) const arr1=[] const arr2=[] const arr3=[] let isLeft=0 let isRight=0 indexArr.forEach(function (key) { const left=getDis(sArr[line[0]],sArr[key]); const right=getDis(sArr[line[1]],sArr[key]); if(left*2<line[2]){ arr1.push(key) if(left*8>3*line[2]){ arr3.push(key) isLeft=1 } }else if(right*2<line[2]){ arr2.push(key) if(right*8>3*line[2]){ arr3.push(key) isRight=1 } }else{ arr3.push(key) } }) const data=[arr1,arr2,arr3] if(arr1.length>100||isLeft){ data[0]=this.splitByIndex(arr1,sArr) } if(arr2.length>100||isRight){ data[1]=this.splitByIndex(arr2,sArr) } if(arr3.length>100||isLeft||isRight){ data[2]=this.splitByIndex(arr3,sArr) } return { line, data } } //对数组分类,成2部分 split(sArr){ const indexArr=sArr.map(function (item,i) { return i; }) return this.splitByIndex(indexArr,sArr) } }
//分类器demo const sArr=[] for(let i=0;i<100;i++){ sArr.push({x:0|Math.random()*1000,y:0|Math.random()*1000}) } function getDis(key1,key2) { return Math.abs(key1.x-key2.x)+Math.abs(key1.y-key2.y); } const asplit=new ArraySplit(getDis) const tag=asplit.split(sArr) console.log(JSON.stringify(tag))