/*
* 分类器*/
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))