【高频考点】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;
}
相关推荐
郝亚军2 小时前
Visual Studio 2022项目中的.sln是什么?
c++·c#·visual studio
下午写HelloWorld2 小时前
后量子密码算法:协同签名研究综述
算法·密码学·后量子·协同签名
小蒋学算法2 小时前
算法-计算右侧小于当前元素的个数-分治&归并思想
java·数据结构·算法
lqqjuly2 小时前
FlashAttention 深度解析
人工智能·深度学习·算法
满怀冰雪2 小时前
第05篇-滑动窗口算法-一套模板解决子串与子数组问题
java·算法
apcipot_rain2 小时前
计科八股20260609——10分钟速通《线性代数》,知识点极简版
人工智能·线性代数·机器学习
SilentSamsara2 小时前
模型评估与超参调优:交叉验证、Optuna 与模型选择策略
人工智能·python·深度学习·机器学习·青少年编程
叫我:松哥2 小时前
基于LSTM与ARIMA的城市空气质量分析与预测系统
人工智能·python·rnn·算法·机器学习·flask·lstm
j7~2 小时前
【C++】模板初阶--函数模板,类模板详解
数据结构·c++·算法·函数模板·类模板·函数模板实例化