【KNN算法】谁能把串行改为并行

学生类Student.java

import lombok.Data;
public class Student {
    private String name;
    private int height;
    private String rank;
    public Student(){}
    public Student(String n,int h){
        name=n;
        height=h;
    }
    public Student(String n,int h,String r){
        name=n;
        height=h;
        rank=r;
    }
    public void setRank(String rank) {
        this.rank=rank;
    }
    public int getHeight() {
        return height;
    }
    public String getRank() {
        return rank;
    }
    public String toString() {   //以文本方式表示
        return "Student(name="+name+",height="+height+",rank="+rank+")";
    }
}

主程序Knn01.java

import java.util.ArrayList;
import java.util.List;

public class Knn01 {
    public static List<Student> dataList =new ArrayList<>();    //定义初始数据集
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        initData();
        Student a=new Student("姐姐",175);
        int k=6;
        Student student=Knn(a,k);
        System.out.println("输入的学生数据: "+student);
        long endTime = System.currentTimeMillis();
        System.out.println("此次运行共耗时: " +(endTime-startTime)/1000.0+"s");
    }

    /*找出同等级占比最多的学生等级*/
    public static String getCategoryStudent(List<Student> categoryList){
        int tallCount = 0;
        int midCount = 0;
        int smallCount = 0;
        for (Student b : categoryList) {
            if (b.getRank().equals("高")) tallCount++;
            else if (b.getRank().equals("中等")) midCount++;
            else smallCount++;
        }
        int max;
        max = Math.max(tallCount, midCount);
        max = Math.max(smallCount, max);
        if (smallCount == max) return "矮";
        else if (tallCount == max) return "高";
        else return "中等";
    }

    /*计算出a距离categoryList集合中最远的学生对象*/
    public static Student getCalculate(Student a, List<Student> categoryList) {
        int maxHeight = 0; //存放a与类别集合categoryList的最远距离
        Student resultStu = new Student(); //存放要返回的学生,即a与类别集合categoryList距离最远的学生
        for (Student b : categoryList) {
            int ab = Math.abs(a.getHeight() - b.getHeight()); //a与b的距离
            if (ab > maxHeight){ //a与b的距离大于maxHeight,则对maxHeight和resultStu进行更新
                maxHeight = ab;
                resultStu = b;
            }
        }
        return resultStu;
    }

    /*对输入学生类进行Knn算法实例化该学生的等级后,将该学生返回*/
    public static Student Knn(Student a,int k){
        ArrayList<Student> categoryList = new ArrayList<>(); //存放距离a最近的k个学生,最初存放数据集的前k项
        for (int i = 0; i < dataList.size(); i++) {
            if (i < k) categoryList.add(dataList.get(i));
            else {
                //遍历数据集dataList,计算a距离从数据集的第6项开始的每一项的距离ad
                int ad = Math.abs(a.getHeight() - dataList.get(i).getHeight());
                //另外调用getCalculate()方法计算出a距离categoryList集合中最远的学生对象b
                Student b =  getCalculate(a, categoryList); //存放a距离类别集合中最远的学生
                int c = Math.abs(b.getHeight() - a.getHeight());
                if (c > ad){//若b距离a的身高距离c大于ad,则在categoryList中去除掉b
                    categoryList.remove(b); //在集合列表中去除b
                    categoryList.add(dataList.get(i));//将数据集中的该项加入到categoryList集合中来
                }
            }
        }
        System.out.println("最近的"+k+"位学生:");
        for(Student temp:categoryList){
            System.out.println(temp);
        }
        String rank = getCategoryStudent(categoryList);
        a.setRank(rank);
        return a;
    }

    /*初始化数据*/
    public static void initData(){
        Student s1 = new Student("李丽", 150, "矮");
        Student s2 = new Student("吉米", 192, "高");
        Student s3 = new Student("马大华", 170, "中等");
        Student s4 = new Student("王晓华", 173, "中等");
        Student s5 = new Student("刘敏", 160, "矮");
        Student s6 = new Student("张强", 175, "中等");
        Student s7 = new Student("李秦", 160, "矮");
        Student s8 = new Student("王壮", 190, "高");
        Student s9 = new Student("刘冰", 168, "中等");
        Student s10 = new Student("张喆", 178, "中等");
        Student s11 = new Student("杨毅", 170, "中等");
        Student s12 = new Student("徐田", 168, "中等");
        Student s13 = new Student("高杰", 165, "矮");
        Student s14 = new Student("张晓", 178, "中等");
        Student s15 = new Student("德一", 191, "高");
        dataList.add(s1);
        dataList.add(s2);
        dataList.add(s3);
        dataList.add(s4);
        dataList.add(s5);
        dataList.add(s6);
        dataList.add(s7);
        dataList.add(s8);
        dataList.add(s9);
        dataList.add(s10);
        dataList.add(s11);
        dataList.add(s12);
        dataList.add(s13);
        dataList.add(s14);
        dataList.add(s15);
    }
}

实在没有什么头绪,主要是把主函数的方法Knn内部的“遍历数据集dataList,计算a距离从数据集的第k项开始的每一项的距离ad”改成同时执行

    /*对输入学生类进行Knn算法实例化该学生的等级后,将该学生返回*/
    public static Student Knn(Student a,int k){
        ArrayList<Student> categoryList = new ArrayList<>(); //存放距离a最近的k个学生,最初存放数据集的前k项
        for (int i = 0; i < dataList.size(); i++) {
            if (i < k) categoryList.add(dataList.get(i));
            else {
                //遍历数据集dataList,计算a距离从数据集的第6项开始的每一项的距离ad
                int ad = Math.abs(a.getHeight() - dataList.get(i).getHeight());
                //另外调用getCalculate()方法计算出a距离categoryList集合中最远的学生对象b
                Student b =  getCalculate(a, categoryList); //存放a距离类别集合中最远的学生
                int c = Math.abs(b.getHeight() - a.getHeight());
                if (c > ad){//若b距离a的身高距离c大于ad,则在categoryList中去除掉b
                    categoryList.remove(b); //在集合列表中去除b
                    categoryList.add(dataList.get(i));//将数据集中的该项加入到categoryList集合中来
                }
            }
        }
        System.out.println("最近的"+k+"位学生:");
        for(Student temp:categoryList){
            System.out.println(temp);
        }
        String rank = getCategoryStudent(categoryList);
        a.setRank(rank);
        return a;
    }

你需要的是掌握Java并行计算的例子:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ParallelCount {
    public static void main(String[] args) throws InterruptedException {
        int[] nums = {1, 3, 5, 7, 9};
        int threads = 3;

        ExecutorService executor = Executors.newFixedThreadPool(threads);
        CountDownLatch latch = new CountDownLatch(threads);

        int blockSize = nums.length / threads;
        for (int i = 0; i < threads; i++) {
            int start = i * blockSize;
            int end = (i == threads - 1) ? nums.length : (i + 1) * blockSize;
            executor.submit(new SumTask(nums, start, end, latch));
        }

        latch.await();

        System.out.println("Done!");
        executor.shutdown();
    }

    static class SumTask implements Runnable {
        private int[] nums;
        private int start;
        private int end;
        private CountDownLatch latch;

        public SumTask(int[] nums, int start, int end, CountDownLatch latch) {
            this.nums = nums;
            this.start = start;
            this.end = end;
            this.latch = latch;
        }

        @Override
        public void run() {
            int sum = 0;
            for (int i = start; i < end; i++) {
                sum += nums[i];
            }
            System.out.println(Thread.currentThread().getName() + ": " + sum);
            latch.countDown();
        }
    }
}