层次聚类和固定宽度聚类

以下是头文件:

 <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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值