以下是头文件:
<pre name="code" class="cpp">#ifndef WSNHSCDA_H
#define WSNHSCDA_H
#include "common.h"
//凡需要计算两个向量欧氏距离的类,都包含此类
class eucideanDistanceClass
{
public:
static double eucideanDistance( const vector<double>& f1, const vector<double>& f2 ); //计算向量之间的欧氏距离
};
// 测量得到的数据向量,标示一个测量值。
// 每隔一段时间,传感节点进行测量,一个测量值有很多特征值。
// 此类保存一次取样得到的数据。
class dataSample{
public:
dataSample():type(0)
{
};
void operator()( dataSample & a)
{
cout<<"type = "<<a.type<<": ";
vectorPrint(a.features);
};
dataSample &operator=(const dataSample& other)
{
this->type = other.type;
this->features = other.features;
return *this;
}
unsigned int size()
{
return features.size();
};
double push_back( double val )
{
features.push_back(val);
};
double & operator[](unsigned int i)
{
return features[i];
};
public:
unsigned int type;
vector<double> features;
};
// 簇的总结:簇中所有向量的线性和,数据向量的个数,簇ID。
// 由于簇要进行融合和传递,融合后还是一个簇总结,所以还需要保存节点ID和融合之前的簇的ID。
// 此类方便于簇总结传递的管理。
class clusterSample
{
public:
clusterSample():featuresNum(0),clusterID(0),sensorID(0),isMerged(0)
{
return;
};
void featuresUpdate(const clusterSample &cS ,unsigned int num = 1 );//用于融合
void featuresUpdate(const dataSample &dS ,unsigned int num = 1 );//用于聚类
void operator()(clusterSample & cS)
{
cout<<"ID: "<<cS.clusterID<<" featuresNum: "<<cS.featuresNum<<" ";
vectorPrint<double>(cS.featuresAvg);
};
public:
bool isMerged;
vector<double> featuresAvg;
vector<double> featuresSum;
unsigned int featuresNum;
unsigned int clusterID;//用于标示新的簇,簇ID
unsigned int sensorID;//用于标示新的簇,产生这个簇的节点ID
vector<clusterSample> mergeClusters;//仅仅用于簇的融合。保存融合之前簇的信息。
private:
void featuresAvgUpdate(unsigned int size);
private:
class eucideanDist :public eucideanDistanceClass
{
};
};
// 每个时间窗口的得到n个测量值。
// 在每一个节点上需要对测量值进行固定宽度聚类。
// 操作一个节点上的簇集合。包含原始的数据和簇信息。
// 此类方便节点自己管理自己的簇集合和子节点发送来的簇总结。
// 封装了关于节点对簇操作的所有逻辑,即是以节点为单位的。
class dataCluster
{
public:
dataCluster(vector<dataSample> & a, unsigned int sensorID = 0):dataSet(a),nodeID(sensorID)
{
return;
};
void fixedWidthCluster(double width);//对自身数据进行聚类
unsigned int size()
{
return dataSet.size();
};
public:
static unsigned int clusterCount; //记录簇的个数
vector<dataSample> dataSet;//节点自身的数据
vector<clusterSample> clusters;//节点根据自身的数据,构造出的簇集合
private:
void normalize();
class eucideanDist :public eucideanDistanceClass
{
};
unsigned int nodeID;
protected:
dataCluster()
{
};//为sensorNode单独构造的缺省构造函数
friend class sensorNode;
};
//由于KNN算法结构比较复杂
//需要在这里对KNN算法内容进行封装
//仅仅需要在这个类里面封装的是KNN算法的逻辑部分
//KNN算法步奏描绘如下:
//1、每一个clusterSample包含了一个特征值的向量。
//2、对于簇集合中的每一个簇,计算其他所有簇和这个簇的距离。
//3、根据前K个距离,计算平均簇间距离。
//4、并返回由前K个值算出的均值组成的向量。
class KNNClass
{
public:
KNNClass(vector<clusterSample> clusters,unsigned int k):clusters(clusters),k(k),AVGICD(0.0),SDICD(0.0)
{
dstMtrx.reserve(clusters.size());
};
double getAVGICD( )
{
return AVGICD;
};
double getSDICD()
{
return SDICD;
};
void creatDistanceMatrix( );
vector<double> getICD()
{
return ICD;
};
private:
void cnstrctICD();
void calAVGICD();
void calSDICD();
private:
class eucideanDist:public eucideanDistanceClass
{
};
const unsigned int k;
vecto