xueweigang 2017-05-03 07:57 采纳率: 0%
浏览 806
已采纳

C++程序崩了,大神们能不能帮我看一下

我自己调试过了,没问题,为啥运行的时候就崩了呢,求教

 #include <iostream>
#include <fstream>
#include <cmath> 
#include <time.h> 
using namespace std;

int K;    //聚类的类数
int datanum;   //数据组数
int dimnum;   //每组数据的维数

double *data = new double[datanum*dimnum];  //样本数据存储
int *center = new int[K];   //存储每个中心的第一维数据的下标
int *flag = new int[datanum];  //标志位,标志每组数据属于哪个中心

//计算两组数据之间的距离
double GetdistXY(int m, int n) //传入样本数据数组,m,n为两个数据组的首地址  

{
    double sum = 0;
    for (int i = 0; i<dimnum; i++)
    {
        sum += (data[m] - data[n]) * (data[m] - data[n]);
        m++;
        n++;
    }
    return sqrt(sum);
}

//数据选择属于哪个中心(一次只能选择一组数据进行归类)
int Choosecenter(int m)  //m传入需要归类的数据组的首地址
{
    double dist = GetdistXY(m, center[0]);
    double tmp;
    int label = 0;//标示属于哪一个中心
    for (int i = 1; i<K; i++){
        tmp = GetdistXY(m, center[i]);
        if (tmp<dist) { dist = tmp; label = center[i]; }
    }
    return label;  //返回类中心的首地址   
}

//选择中心    //调用一次计算所有类中心的值
void Getpoint()
{
    double *dist = new double[datanum];
    int i;
    unsigned int sum = 0;
    for (i = 0; i < datanum; i++)
    {
        dist[i] = GetdistXY(i*dimnum, flag[i]);
        sum += dist[i];
    }
    for (int k = 0; k < K; k++)
    {
        srand((unsigned int )time(0));
        double p = rand() % sum;
        for (i = 0; i < datanum; i++)
        if ((p -= dist[i]) <= 0)
            break;
        center[k] = i*dimnum;
    }
}

//计算误差
double Getvar(){
    double var = 0;
    int i;
    for (i = 0; i < datanum; i++){
        var += GetdistXY(i*dimnum, flag[i]);
    }
    //cout<<var<<endl;
    return var;
}

void print()
{
    int max = datanum*dimnum;
    for (int lable = 0; lable<K; lable++)
    {
        cout << "第" << lable + 1 << "个类:" << endl;
        for (int z = 0; z < K; z++)
            cout << center[z] << endl;
        for (int i = 0; i<datanum; i++)
        {
            if (flag[i] == center[lable]){
                for (int j = 0; j < dimnum; j++){
                    cout << i*dimnum + j << endl;
                    cout << data[(i*dimnum + j)] << ", ";
                }
            }
        }
        cout << endl;
    }
}

void KMeans(){
    int i;
    //一开始随机选取k条记录的值作为k个簇的质心(均值) 
    srand((unsigned int)time(NULL));
    for (i = 0; i < K; i++)
    {
        int iToSelect = rand() % datanum;
        center[i] = iToSelect * dimnum;
    }
    //根据默认的质心数据进行归类 
    for (i = 0; i< datanum; i++){
        flag[i] = Choosecenter(i*dimnum);
    }
    double Oldvar = -1;
    double Newvar = Getvar();
    cout << "初始的整体误差平方和为:" << Newvar << endl;
    int t = 0;
    while (abs(Newvar - Oldvar) >= 1) //当新旧误差相差不到1时,算法终止 
    {
        cout << "第 " << ++t << " 次迭代开始:" << endl;
        Getpoint();//更新每个类的中心点  
        //重新为每组数据分配类
        for (i = 0; i < datanum; i++){
            flag[i] = Choosecenter(i*dimnum);
        }
        Oldvar = Newvar;
        Newvar = Getvar(); //计算新的误差 
        cout << "此次迭代之后的整体误差平方和为:" << Newvar << endl;
    }

    cout << "The result is:" << endl;
    print();
}

int main()
{

    cout << endl << " 请依次输入: 聚类中心数 样本数目 维数" << endl;
    cout << endl << " 聚类中心数K:";
    cin >> K;
    cout << endl << " 样本数目datanum: ";
    cin >> datanum;
    cout << endl << " 维数dimnum: ";
    cin >> dimnum;
    ifstream in("test.txt");
    if (!in){
        cout << "不能打开输入的文件" << endl;
        return 0;
    }
    //从文件流中读入数据 
    for (int i = 0; i<datanum*dimnum; i++)
    {
        in >> data[i];
    }
    in.close();
    cout << endl << "开始聚类" << endl;
    KMeans();
    return 0;

}

图片说明

图片说明

  • 写回答

2条回答 默认 最新

  • 小灸舞 2017-05-04 02:05
    关注

    问题在于这这三句:

     double *data = new double[datanum*dimnum];  //样本数据存储
    int *center = new int[K];   //存储每个中心的第一维数据的下标
    int *flag = new int[datanum];  //标志位,标志每组数据属于哪个中心
    

    你的k,datanum,dimnum在编译期是无法确定数值的(运行期输入后才能确定数值)
    所以你应该写成下面这样:

     #include <iostream>
    #include <fstream>
    #include <cmath> 
    #include <time.h> 
    using namespace std;
    
    int K;    //聚类的类数
    int datanum;   //数据组数
    int dimnum;   //每组数据的维数
    
    double *data;
    int *center;
    int *flag;
    
    //计算两组数据之间的距离
    double GetdistXY(int m, int n) //传入样本数据数组,m,n为两个数据组的首地址  
    
    {
        double sum = 0;
        for (int i = 0; i<dimnum; i++)
        {
            sum += (data[m] - data[n]) * (data[m] - data[n]);
            m++;
            n++;
        }
        return sqrt(sum);
    }
    
    //数据选择属于哪个中心(一次只能选择一组数据进行归类)
    int Choosecenter(int m)  //m传入需要归类的数据组的首地址
    {
        double dist = GetdistXY(m, center[0]);
        double tmp;
        int label = 0;//标示属于哪一个中心
        for (int i = 1; i<K; i++){
            tmp = GetdistXY(m, center[i]);
            if (tmp<dist) { dist = tmp; label = center[i]; }
        }
        return label;  //返回类中心的首地址   
    }
    
    //选择中心    //调用一次计算所有类中心的值
    void Getpoint()
    {
        double *dist = new double[datanum];
        int i;
        unsigned int sum = 0;
        for (i = 0; i < datanum; i++)
        {
            dist[i] = GetdistXY(i*dimnum, flag[i]);
            sum += dist[i];
        }
        for (int k = 0; k < K; k++)
        {
            srand((unsigned int )time(0));
            double p = rand() % sum;
            for (i = 0; i < datanum; i++)
            if ((p -= dist[i]) <= 0)
                break;
            center[k] = i*dimnum;
        }
    }
    
    //计算误差
    double Getvar(){
        double var = 0;
        int i;
        for (i = 0; i < datanum; i++){
            var += GetdistXY(i*dimnum, flag[i]);
        }
        //cout<<var<<endl;
        return var;
    }
    
    void print()
    {
        int max = datanum*dimnum;
        for (int lable = 0; lable<K; lable++)
        {
            cout << "第" << lable + 1 << "个类:" << endl;
            for (int z = 0; z < K; z++)
                cout << center[z] << endl;
            for (int i = 0; i<datanum; i++)
            {
                if (flag[i] == center[lable]){
                    for (int j = 0; j < dimnum; j++){
                        cout << i*dimnum + j << endl;
                        cout << data[(i*dimnum + j)] << ", ";
                    }
                }
            }
            cout << endl;
        }
    }
    
    void KMeans(){
        int i;
        //一开始随机选取k条记录的值作为k个簇的质心(均值) 
        srand((unsigned int)time(NULL));
        for (i = 0; i < K; i++)
        {
            int iToSelect = rand() % datanum;
            center[i] = iToSelect * dimnum;
        }
        //根据默认的质心数据进行归类 
        for (i = 0; i< datanum; i++){
            flag[i] = Choosecenter(i*dimnum);
        }
        double Oldvar = -1;
        double Newvar = Getvar();
        cout << "初始的整体误差平方和为:" << Newvar << endl;
        int t = 0;
        while (abs(Newvar - Oldvar) >= 1) //当新旧误差相差不到1时,算法终止 
        {
            cout << "第 " << ++t << " 次迭代开始:" << endl;
            Getpoint();//更新每个类的中心点  
            //重新为每组数据分配类
            for (i = 0; i < datanum; i++){
                flag[i] = Choosecenter(i*dimnum);
            }
            Oldvar = Newvar;
            Newvar = Getvar(); //计算新的误差 
            cout << "此次迭代之后的整体误差平方和为:" << Newvar << endl;
        }
    
        cout << "The result is:" << endl;
        print();
    }
    
    int main()
    {
    
        cout << endl << " 请依次输入: 聚类中心数 样本数目 维数" << endl;
        cout << endl << " 聚类中心数K:";
        cin >> K;
        cout << endl << " 样本数目datanum: ";
        cin >> datanum;
        cout << endl << " 维数dimnum: ";
        cin >> dimnum;
    
        data = new double[datanum*dimnum];  //样本数据存储
        center = new int[K];   //存储每个中心的第一维数据的下标
        flag = new int[datanum];  //标志位,标志每组数据属于哪个中心
    
        ifstream in("test.txt");
        if (!in){
            cout << "不能打开输入的文件" << endl;
            return 0;
        }
        //从文件流中读入数据 
        for (int i = 0; i<datanum*dimnum; i++)
        {
            in >> data[i];
        }
        in.close();
        cout << endl << "开始聚类" << endl;
        KMeans();
        return 0;
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog