K-Means聚类算法java代码

《关于为了一杯果茶所以7点半起床给舍友写java作业这档事》

import java.util.Scanner;

class MyPoint {
    private double x, y;
    public MyPoint(){
        x = y = 0;
    }
    public MyPoint(double x, double y){
        this.x = x;
        this.y = y;
    }
    public double getX() {
        return x;
    }
    public double getY() {
        return y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }
    public double distance(MyPoint myPoint){
        return distance(myPoint.x, myPoint.y);
    }
    public double distance(double x, double y){
        return Math.sqrt((this.x - x) * (this.x - x) + (this.y - y) * (this.y - y));
    }
}

public class Shit {
    public static void main(String[] args) {
        int n, k;
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        k = input.nextInt();
        MyPoint[] point = new MyPoint[n];//存点
        for(int i = 0; i < n; ++i){
            point[i] = new MyPoint(Math.random() * 100, Math.random() * 100);//生成随机点
        }
        MyPoint[] centre = new MyPoint[k];//中心点
        boolean[] vis = new boolean[n];//标记数组,用于防止初始质心选重
        for(int i = 0; i < k; ++i){
            int id = (int)(Math.random() * n);//随机选取k个质心
            while(vis[id]){//直到找到新的没有被使用过的点,才作为质心
                id = (int)(Math.random() * n);
            }
            vis[id] = true;//更新标记
            centre[i] = new MyPoint(point[id].getX(), point[id].getY());
        }
        int[] id = new int[n];//记录n个点属于哪个簇
        while(true){
            int[] num = new int[k];//记录簇中的点的数量
            boolean p = true;//用于判断什么时候结束循环,当每个点的id都不变的时候就结束
            for(int i = 0; i < n; ++i){
                int idd = 0;//记录属于哪个簇
                double minx = point[i].distance(centre[0]);//最小距离
                for(int j = 1; j < k; ++j){//计算该点到所有点的距离,找到最小距离对应的下标idd
                    if(minx > point[i].distance(centre[j])){
                        idd = j;
                        minx = point[i].distance(centre[j]);
                    }
                }
                if(id[i] != idd){//如果不属于上次的簇,则说明和上次的分类不同,则不能退出循环,更新标记p
                    id[i] = idd;//更新id
                    p = false;
                }
                ++num[idd];//更新簇的点的数量
            }
            if(p)break;//如果所有的簇不变,则退出循环
            for(int i = 0; i < k; ++i){//初始化中心点的值
                centre[i].setX(0);
                centre[i].setY(0);
            }
            for(int i = 0; i < n; ++i){//求和,便于求质心
                centre[id[i]].setX(centre[id[i]].getX() + point[i].getX());
                centre[id[i]].setY(centre[id[i]].getY() + point[i].getY());
            }
            for(int i = 0; i < k; ++i){//计算每个簇的点的质心
                centre[i].setX(centre[i].getX() / num[i]);
                centre[i].setY(centre[i].getY() / num[i]);
            }
        }
        for(int i = 0; i < k; ++i){
            System.out.printf("第%d个簇的质心: (%f, %f)\n", i+1, centre[i].getX(), centre[i].getY());
            for(int j = 0; j < n; ++j){
                if(id[j] == i)System.out.printf("(%f, %f) ", point[j].getX(), point[j].getY());
            }
            System.out.println();
        }
    }

}


博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇