我自己调试过了,没问题,为啥运行的时候就崩了呢,求教
#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;
}