【高频考点】K-Means聚类算法

2025年9月28日 Yolo检测器中的anchor聚类(通过率100%)

cpp 复制代码
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;

double compute_d(pair<double,double> a, pair<double,double> b){
    return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
}

int main(){
    int n,k;
    cin>>n>>k;
    vector<pair<double,double>> sample(n);
    vector<pair<double,double>> center(k);

    for(int i=0;i<n;i++){
        cin>>sample[i].first>>sample[i].second;
        if(i<k) {
            center[i].first=sample[i].first;
            center[i].second=sample[i].second;
        }
    }
    int iter=100;
    vector<vector<pair<double,double>>> final_clus(k);
    for(int i=0;i<iter;i++){
    vector<pair<double,double>> new_center(k);
    vector<vector<pair<double,double>>> clus(k);
        for(int j=0;j<n;j++){
            double min_d=1e9;
            int clu_idx=0;
            for(int l=0;l<k;l++){
                double d=compute_d(sample[j],center[l]);
                if(d<min_d){
                    min_d=d;
                    clu_idx=l;}
            }
            clus[clu_idx].push_back(sample[j]);
        }
        for(int j=0;j<k;j++){
            double sum_1=0,sum_2=0;
            for(int l=0;l<clus[j].size();l++){
                sum_1+=clus[j][l].first;
                sum_2+=clus[j][l].second;
            }
            if(clus[j].size()!=0){
                new_center[j].first=sum_1/clus[j].size();
                new_center[j].second=sum_2/clus[j].size();
            }else{
                new_center[j]=center[j];
            }
        }
        int flag=0;
        for(int j=0;j<k;j++){
            if(compute_d(new_center[j], center[j])>1e-6) flag=1;
        }
        center=new_center;
        final_clus=clus;
        if(flag==0) break;
        
    }
    
    
    vector<double> ave_si_clus(k);
    for(int i=0;i<k;i++){
        double si_clus =0;
        if(final_clus[i].size()<1) {si_clus=1; continue;}
        for(int j=0;j<final_clus[i].size();j++){ 
            double si=0;
            if(final_clus[i].size()<=1) {si=1;}
            else{ 
            double d=0;
            for(int l=0;l<final_clus[i].size();l++){
                if(j!=l)  d+=compute_d(final_clus[i][j],final_clus[i][l]);
            }
            double ai=d/(final_clus[i].size()-1);
            vector<double> b;
            for(int m=0;m<k;m++){
                double d=0;
                if(m==i) continue;    
                for(int z=0;z<final_clus[m].size();z++)
                   d+=compute_d(final_clus[i][j],final_clus[m][z]); 
                b.push_back(d/(final_clus[m].size()));
            }
            double bi=b[0];
            for(int l=1;l<b.size();l++){
                if(b[l]<bi) bi=b[l];
            }
            
            si=(bi-ai)/max(ai,bi);
            }
            si_clus+=si;
        }
        if(final_clus[i].size()>0) 
            ave_si_clus[i]=si_clus/final_clus[i].size();
        else ave_si_clus[i]=0;
    }
    double min_si=ave_si_clus[0];
    int min_idx=0;
    for(int i=1;i<k;i++){
        if(ave_si_clus[i]<min_si){
            min_si=ave_si_clus[i];
            min_idx=i;
        }
    }
    cout << fixed << setprecision(2);//#include<iomanip>
    double x = center[min_idx].first;
    double y = center[min_idx].second;
    cout << round(x*100)/100.0 << "," << round(y*100)/100.0 << endl;

    return 0;
}

2026年3月4日 网络流量分析(通过率100%)

cpp 复制代码
#include<iostream>
#include<vector>
#include<cmath>
#include<iomanip>  // 必须加
using namespace std;

struct Box{
    double x,y,z;
};

double compute_d(Box A, Box B){
    //return sqrt(pow(A.x-B.x,2)+pow(A.y-B.y,2)+pow(A.z-B.z,2));
    return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z);
}

int main(){
    int k;
    cin>>k;
    vector<Box> center(k);
    for(int i=0;i<k;i++){
        cin>>center[i].x>>center[i].y>>center[i].z;
    }
    int iter;
    cin>>iter;
    int m;
    cin>>m;
    vector<Box> sample(m);
    for(int i=0;i<m;i++){
        cin>>sample[i].x>>sample[i].y>>sample[i].z;
    }
    for(int i=0;i<iter;i++){
        vector<Box> new_center(k);
        vector<vector<Box>> clus(k);
        for(int j=0;j<m;j++){//遍历所有样本
            double d_min=1e9;
            int center_idx=0;
            for(int l=0;l<k;l++){
                double d = compute_d(sample[j], center[l]);
                if(d<d_min){
                    d_min=d;
                    center_idx=l;
                }
            }
            clus[center_idx].push_back(sample[j]);
        }
        for(int j=0;j<k;j++){
            double sum_x=0,sum_y=0,sum_z=0;
            for(int l=0;l<clus[j].size();l++){
                sum_x+=clus[j][l].x;
                sum_y+=clus[j][l].y;
                sum_z+=clus[j][l].z;
            }
            if(clus[j].size()!=0){
                new_center[j].x=round((sum_x/clus[j].size())*100)/100.0;
                new_center[j].y=round((sum_y/clus[j].size())*100)/100.0;
                new_center[j].z=round((sum_z/clus[j].size())*100)/100.0;
            }else{
                new_center[j]=center[j];
            }
        }
        center = new_center;
    }
    // 只加这一行,就能全部显示两位小数
    cout << fixed << setprecision(2);
    for(int i=0;i<k;i++){
        cout<<center[i].x<<" "<<center[i].y<<" "<<center[i].z<<endl;
    }

    return 0;
}

2025年9月24日 无线网络优化中的基站聚类分析(通过率100%)

cpp 复制代码
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;

double compute_d(pair<double,double> a, pair<double,double> b){
    return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
}

int main(){
    int n,k;
    cin>>n>>k;
    vector<pair<double,double>> sample(n);
    vector<pair<double,double>> center(k);

    for(int i=0;i<n;i++){
        cin>>sample[i].first>>sample[i].second;
        if(i<k) {
            center[i].first=sample[i].first;
            center[i].second=sample[i].second;
        }
    }
    int iter=100;
    vector<vector<pair<double,double>>> final_clus(k);
    for(int i=0;i<iter;i++){
    vector<pair<double,double>> new_center(k);
    vector<vector<pair<double,double>>> clus(k);
        for(int j=0;j<n;j++){
            double min_d=1e9;
            int clu_idx=0;
            for(int l=0;l<k;l++){
                double d=compute_d(sample[j],center[l]);
                if(d<min_d){
                    min_d=d;
                    clu_idx=l;}
            }
            clus[clu_idx].push_back(sample[j]);
        }
        for(int j=0;j<k;j++){
            double sum_1=0,sum_2=0;
            for(int l=0;l<clus[j].size();l++){
                sum_1+=clus[j][l].first;
                sum_2+=clus[j][l].second;
            }
            if(clus[j].size()!=0){
                new_center[j].first=sum_1/clus[j].size();
                new_center[j].second=sum_2/clus[j].size();
            }else{
                new_center[j]=center[j];
            }
        }
        int flag=0;
        for(int j=0;j<k;j++){
            if(compute_d(new_center[j], center[j])>1e-6) flag=1;
        }
        center=new_center;
        final_clus=clus;
        if(flag==0) break;
        
    }
    
    
    vector<double> ave_si_clus(k);
    for(int i=0;i<k;i++){
        double si_clus =0;
        if(final_clus[i].size()<1) {si_clus=1; continue;}
        for(int j=0;j<final_clus[i].size();j++){ 
            double si=0;
            if(final_clus[i].size()<=1) {si=1;}
            else{ 
            double d=0;
            for(int l=0;l<final_clus[i].size();l++){
                if(j!=l)  d+=compute_d(final_clus[i][j],final_clus[i][l]);
            }
            double ai=d/(final_clus[i].size()-1);
            vector<double> b;
            for(int m=0;m<k;m++){
                double d=0;
                if(m==i) continue;    
                for(int z=0;z<final_clus[m].size();z++)
                   d+=compute_d(final_clus[i][j],final_clus[m][z]); 
                b.push_back(d/(final_clus[m].size()));
            }
            double bi=b[0];
            for(int l=1;l<b.size();l++){
                if(b[l]<bi) bi=b[l];
            }
            
            si=(bi-ai)/max(ai,bi);
            }
            si_clus+=si;
        }
        if(final_clus[i].size()>0) 
            ave_si_clus[i]=si_clus/final_clus[i].size();
        else ave_si_clus[i]=0;
    }
    double min_si=ave_si_clus[0];
    int min_idx=0;
    for(int i=1;i<k;i++){
        if(ave_si_clus[i]<min_si){
            min_si=ave_si_clus[i];
            min_idx=i;
        }
    }
    cout << fixed << setprecision(2);//#include<iomanip>
    double x = center[min_idx].first;
    double y = center[min_idx].second;
    cout << round(x*100)/100.0 << "," << round(y*100)/100.0 << endl;

    return 0;
}
相关推荐
AI小老六3 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术4 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize5 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考18 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
ShallWeL20 小时前
【机器学习】(3)—— 线性回归:梯度下降
人工智能·机器学习
美团技术团队21 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
ShallWeL1 天前
【机器学习】(2)—— 线性回归:损失函数
人工智能·机器学习
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode