需要把控制台的程序变成MFC对话框程序,希望能按个BUTTON 让输出的结果显示在EDIT中,(能不用数组吗?)下附KMEANS.CPP MAIN.CPP
望达人帮助。kmeans.cpp
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "point.h"
#include "kmeans.h"
#include "cluster.h"
#include <time.h>const int KMeans::maxIters = 250;
const float KMeans::convergenceThreshold = 0.00001;
const int KMeans::numKMeans = 10;
const long KMeans::seed = 123454321;
KMeans::KMeans(char* s ) : s(s) {
DataFp = NULL;
srand(seed);
numIters = 0;
numPoints = 0;
// 读文件S的第一行,这里声明了所有点的维度。
if ((DataFp = fopen( s, "r")) == NULL) {
perror("Unable to open data file ");
std::cout << s << std::endl;
exit(1);
}
fscanf(DataFp, "%i", &dimensions);
//数据的首要信息就是数据点的ID!!!
data = new float[dimensions];
means = new float[dimensions];
stdev = new float[dimensions];
for(int i = 0; i < dimensions; i++) {
means[i] = 0;
stdev[i] = 0;
}
readPoints();
}/**
* 在向量中选择预置点
*/
void KMeans::initClusters (void) {
//选择任意点
clusters.clear();
int *randNums = new int[numClusters];
for(int i = 0; i < numClusters; i++) {
int random = rand()%numPoints;
for (int j = 0; j < i; j++) {
if (random == randNums[j]) {
i--;
continue;
}
randNums[i] = random;
}
Point* randpoint = points[random];
Cluster *c = new Cluster(dimensions, randpoint->copy(), i);
clusters.push_back(c);
}
}/**
* 读取文本文件中的点,预置S向量'points'
*/
void KMeans::readPoints (void) {
Point *p;
while ((p = getPoint()) != NULL) {
numPoints++;
points.push_back(p);
}
if (numPoints == 0) {
printf("No points in %s\n", s);
exit(0);
}
standardizePoints();
}/**
* 读取文件数据
*/
Point* KMeans::getPoint(void) {
float tmp;
float ID; //标记点
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
ID = tmp;
} for (int i = 0; i < dimensions; i++) {
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
means[i] += tmp;
data[i] = tmp;
}
} Point *p = new Point(dimensions);
p->init(ID, data);
return p;
}/**
* 返回读取点的个数
*/
int KMeans::getNumPoints(void) {
return numPoints;
}/**
* 返回P最接近的点,P非NULL
*/
int KMeans::closestCluster(Point *p) {
float lowestDist = -1;
int closestCluster = 0; for (int i = 0; i < numClusters; i++) {
Cluster *c = clusters[i];
float dist = c->distanceSquared(p);
if (lowestDist == -1) {
lowestDist = dist;
} else if (dist < lowestDist) {
lowestDist = dist;
closestCluster = i;
}
}
return closestCluster;
}
KMeans::~KMeans() {
for (int i = 0; i < numPoints; i++) {
delete(points[i]);
}
}/**
* 返回包含所有点的向量
*/
std::vector<Point*> KMeans::getPoints(void) {
return points;
}/**
* 迭代Kmeans算法.
*/
void KMeans::iterate (void) {
numChanges = 0; //在这次迭代中类成员变化情况
for(int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}
for (i = 0; i < numPoints; i++) {
Point *curpoint = points[i];
int clusterNum = closestCluster(curpoint);
if(curpoint->getClusterNum() != clusterNum) {
numChanges++;
curpoint->setClusterNum(clusterNum);
}
clusters[clusterNum]->addPoint(curpoint);
}
for(i = 0; i < numClusters; i++) {
clusters[i]->calculateMeans();
}
}/**
* 返回在最大迭代中成员在类中的变化情况
*/
int KMeans::getNumChanges(void) {
return numChanges;
}/**
* 连带类情况,输出所有点
*/
void KMeans::outputPoints (void) {
for (int i = 0; i < numPoints; i++) {
points[i]->print();
}
}/**
* 执行一个K类的点集
*/
void KMeans::doCluster(int k) {
numClusters = k;
float minError = -1;
int *clusterInfo = new int[numPoints];
if (numPoints <= numClusters)
numClusters = numPoints; //执行算法返回一个最优的
for(int j = 0; j < numKMeans; j++) {
initClusters();
//算法运行直到算法收敛 float prevError = -1; //迭代出错
for (numIters = 0; numIters < maxIters; numIters++) {
iterate();
if (prevError == -1)
prevError = sumErrors();
else if ( getNumChanges() == 0 ||
prevError - sumErrors() < convergenceThreshold) {
break;
}
}
//最好类的信息 float sum = sumErrors();
//printf("number of changes is %i\n", getNumChanges());
//printf("number of iterations is %i\n", numIters);
if (minError == -1 || sum < minError) {
minError = sum;
for(int i = 0; i < numPoints; i++) {
clusterInfo[i] = points[i]->getClusterNum();
}
}
}
//重建最佳类 for (int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}
for (i = 0; i < numPoints; i++) {
clusters[clusterInfo[i]]->addPoint(points[i]);
}
for (i = 0; i < numClusters; i++) {
clusters[i]->print();
printf ("\n");
}
}
/**
* 计算方差和
*/
float KMeans::sumErrors(void) {
float sumError = 0;
for (int i = 0; i < numClusters; i++)
sumError += clusters[i]->calculateError();
return sumError;
}/* 反回一个数的绝对值 */float KMeans::absolute(float x) {
if (x < 0 )
return -x;
else
return x;
}/**
* 标准化所有的点
*/
void KMeans::standardizePoints() {
//计算均值
for (int i = 0; i < dimensions; i++) {
means[i] = means[i]/numPoints;
}
//计算标准方差 (actually the mean absolute
//deviation which is sum(Xi - Mi)/n
float *tmpdata;
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for (int j = 0; j < dimensions; j++) {
stdev[j] += absolute(tmpdata[j] - means[j]);
//绝对差平均化
/* stdev[j] += pow((tmpdata[j] - means[j]), 2); //偏差标准化 */
}
} //计算偏差
for (i = 0; i < dimensions; i++) {
stdev[i] = stdev[i]/numPoints; //mean absolute deviation
/* stdev[i] = pow(stdev[i], 0.5)/(numPoints - 1); //standard deviation */
} //标准化数据
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for(int j = 0; j < dimensions; j++) {
if (stdev[j] == 0) {
//类中没变量,0输出
tmpdata[j] = 0;
} else {
tmpdata[j] = (tmpdata[j] - means[j]) / stdev[j];
}
}
}
}
main.cpp
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "kmeans.h"
#include "point.h"int main(int argc, char *argv[]) {
char* s = argv[1];
int numClusters = atoi(argv[2]);
KMeans *km = new KMeans ( s );
km->doCluster(numClusters);
}
望达人帮助。kmeans.cpp
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "point.h"
#include "kmeans.h"
#include "cluster.h"
#include <time.h>const int KMeans::maxIters = 250;
const float KMeans::convergenceThreshold = 0.00001;
const int KMeans::numKMeans = 10;
const long KMeans::seed = 123454321;
KMeans::KMeans(char* s ) : s(s) {
DataFp = NULL;
srand(seed);
numIters = 0;
numPoints = 0;
// 读文件S的第一行,这里声明了所有点的维度。
if ((DataFp = fopen( s, "r")) == NULL) {
perror("Unable to open data file ");
std::cout << s << std::endl;
exit(1);
}
fscanf(DataFp, "%i", &dimensions);
//数据的首要信息就是数据点的ID!!!
data = new float[dimensions];
means = new float[dimensions];
stdev = new float[dimensions];
for(int i = 0; i < dimensions; i++) {
means[i] = 0;
stdev[i] = 0;
}
readPoints();
}/**
* 在向量中选择预置点
*/
void KMeans::initClusters (void) {
//选择任意点
clusters.clear();
int *randNums = new int[numClusters];
for(int i = 0; i < numClusters; i++) {
int random = rand()%numPoints;
for (int j = 0; j < i; j++) {
if (random == randNums[j]) {
i--;
continue;
}
randNums[i] = random;
}
Point* randpoint = points[random];
Cluster *c = new Cluster(dimensions, randpoint->copy(), i);
clusters.push_back(c);
}
}/**
* 读取文本文件中的点,预置S向量'points'
*/
void KMeans::readPoints (void) {
Point *p;
while ((p = getPoint()) != NULL) {
numPoints++;
points.push_back(p);
}
if (numPoints == 0) {
printf("No points in %s\n", s);
exit(0);
}
standardizePoints();
}/**
* 读取文件数据
*/
Point* KMeans::getPoint(void) {
float tmp;
float ID; //标记点
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
ID = tmp;
} for (int i = 0; i < dimensions; i++) {
if ((fscanf(DataFp, "%f", &tmp) != 1)) {
return NULL;
} else {
means[i] += tmp;
data[i] = tmp;
}
} Point *p = new Point(dimensions);
p->init(ID, data);
return p;
}/**
* 返回读取点的个数
*/
int KMeans::getNumPoints(void) {
return numPoints;
}/**
* 返回P最接近的点,P非NULL
*/
int KMeans::closestCluster(Point *p) {
float lowestDist = -1;
int closestCluster = 0; for (int i = 0; i < numClusters; i++) {
Cluster *c = clusters[i];
float dist = c->distanceSquared(p);
if (lowestDist == -1) {
lowestDist = dist;
} else if (dist < lowestDist) {
lowestDist = dist;
closestCluster = i;
}
}
return closestCluster;
}
KMeans::~KMeans() {
for (int i = 0; i < numPoints; i++) {
delete(points[i]);
}
}/**
* 返回包含所有点的向量
*/
std::vector<Point*> KMeans::getPoints(void) {
return points;
}/**
* 迭代Kmeans算法.
*/
void KMeans::iterate (void) {
numChanges = 0; //在这次迭代中类成员变化情况
for(int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}
for (i = 0; i < numPoints; i++) {
Point *curpoint = points[i];
int clusterNum = closestCluster(curpoint);
if(curpoint->getClusterNum() != clusterNum) {
numChanges++;
curpoint->setClusterNum(clusterNum);
}
clusters[clusterNum]->addPoint(curpoint);
}
for(i = 0; i < numClusters; i++) {
clusters[i]->calculateMeans();
}
}/**
* 返回在最大迭代中成员在类中的变化情况
*/
int KMeans::getNumChanges(void) {
return numChanges;
}/**
* 连带类情况,输出所有点
*/
void KMeans::outputPoints (void) {
for (int i = 0; i < numPoints; i++) {
points[i]->print();
}
}/**
* 执行一个K类的点集
*/
void KMeans::doCluster(int k) {
numClusters = k;
float minError = -1;
int *clusterInfo = new int[numPoints];
if (numPoints <= numClusters)
numClusters = numPoints; //执行算法返回一个最优的
for(int j = 0; j < numKMeans; j++) {
initClusters();
//算法运行直到算法收敛 float prevError = -1; //迭代出错
for (numIters = 0; numIters < maxIters; numIters++) {
iterate();
if (prevError == -1)
prevError = sumErrors();
else if ( getNumChanges() == 0 ||
prevError - sumErrors() < convergenceThreshold) {
break;
}
}
//最好类的信息 float sum = sumErrors();
//printf("number of changes is %i\n", getNumChanges());
//printf("number of iterations is %i\n", numIters);
if (minError == -1 || sum < minError) {
minError = sum;
for(int i = 0; i < numPoints; i++) {
clusterInfo[i] = points[i]->getClusterNum();
}
}
}
//重建最佳类 for (int i = 0; i < numClusters; i++) {
clusters[i]->refresh();
}
for (i = 0; i < numPoints; i++) {
clusters[clusterInfo[i]]->addPoint(points[i]);
}
for (i = 0; i < numClusters; i++) {
clusters[i]->print();
printf ("\n");
}
}
/**
* 计算方差和
*/
float KMeans::sumErrors(void) {
float sumError = 0;
for (int i = 0; i < numClusters; i++)
sumError += clusters[i]->calculateError();
return sumError;
}/* 反回一个数的绝对值 */float KMeans::absolute(float x) {
if (x < 0 )
return -x;
else
return x;
}/**
* 标准化所有的点
*/
void KMeans::standardizePoints() {
//计算均值
for (int i = 0; i < dimensions; i++) {
means[i] = means[i]/numPoints;
}
//计算标准方差 (actually the mean absolute
//deviation which is sum(Xi - Mi)/n
float *tmpdata;
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for (int j = 0; j < dimensions; j++) {
stdev[j] += absolute(tmpdata[j] - means[j]);
//绝对差平均化
/* stdev[j] += pow((tmpdata[j] - means[j]), 2); //偏差标准化 */
}
} //计算偏差
for (i = 0; i < dimensions; i++) {
stdev[i] = stdev[i]/numPoints; //mean absolute deviation
/* stdev[i] = pow(stdev[i], 0.5)/(numPoints - 1); //standard deviation */
} //标准化数据
for(i = 0; i < numPoints; i++) {
tmpdata = points[i]->getData();
for(int j = 0; j < dimensions; j++) {
if (stdev[j] == 0) {
//类中没变量,0输出
tmpdata[j] = 0;
} else {
tmpdata[j] = (tmpdata[j] - means[j]) / stdev[j];
}
}
}
}
main.cpp
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "kmeans.h"
#include "point.h"int main(int argc, char *argv[]) {
char* s = argv[1];
int numClusters = atoi(argv[2]);
KMeans *km = new KMeans ( s );
km->doCluster(numClusters);
}
然后就拖控件,,用事件响应函数把得到的结果帮到EDIT中
可建立一个MFC EXE的项目,再将你的代码加入到项目当中(要加入一些预编译语句).
关键是修改你的程序的输出方式,即在按键的响应程序当中,要将结果输出到EDIT中.