模式識別中分級聚類算法

分級聚類原理

具體原理參見清華大學出版社出版張學工編著的模式識別一書或者任意一本模式識別書。其分類規則有最大、最小、均值分類。本練習實現最小規則分類,即根據類間最小距離的最小值判定爲一類。


C++代碼

1.cluster.cpp

// cluster.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Point.h"
#include "ClassItem.h"
#include "iostream"
#include "cmath"

vector<Point> points;
vector<ClassItem> clas;

void outPutPoint(vector<Point> point){    //用於輸出點
    vector<Point>::iterator it = point.begin();
    while (it != point.end()){
        cout<<it->x<<"  "<<it->y<<"  "<<it->z<<endl;
        it++;
    }
}
void outPutClass(vector<ClassItem> clas){
    cout<<"輸出類"<<endl;
//  vector<ClassItem>::iterator it = clas.begin();
    auto it = clas.begin();
    while (it!= clas.end()){
//      vector<int>::iterator its = (it->getItem()).begin();
        auto its = it->getItem().begin();
        while(its != (it->getItem()).end()){
            cout<<*its<<"  ";
            its++;
        }

        cout<<"類中包含的數目"<<it->getNum()<<endl;
        it++;
    }
}

double calDistance(int index1,int index2){//計算距離(兩個點之間)
    double dis;
    dis = pow((points[index1].x-points[index2].x),2)+pow((points[index1].y-points[index2].y),2)
        +pow((points[index1].z-points[index2].z),2);
    return dis;
}

void julei(int cl1,int cl2){
    clas[cl1].addNum(clas[cl2].getNum());
    clas[cl2].setNum(0);
    ClassItem::CLASSNUM--;
    vector<int> cl2Item = clas[cl2].getItem();
    vector<int>::iterator it = cl2Item.begin();
    while(it!= cl2Item.end()){
        clas[cl1].getItem().push_back(*it);
        it++;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    int m_x[] = {3,0,2,2,2};
    int m_y[] = {1,2,3,0,1};
    int m_z[] = {3,4,2,3,3};

    for(int i = 0; i!= 5;++i){
        ClassItem cla;
        cla = ClassItem(1,i);
        clas.push_back(cla);        //構造類的向量
        Point point;
        point= Point(m_x[i],m_y[i],m_z[i]);//構造點的數組
        points.push_back(point);
    }

    while(ClassItem::CLASSNUM!= 2){
        //判斷距離求得最小距離
        double minDis = pow(10,3);
        int cl1,cl2;
        for(int i = 0;i!= 4;++i){
            for(int j = i+1;j != 5;++j){
                if(clas[i].getNum()!= 0 && clas[j].getNum()!= 0){
                    vector<int> item1 = clas[i].getItem();
                    vector<int> item2 = clas[j].getItem();
                    vector<int>::iterator it1 = item1.begin();
                    vector<int>::iterator it2 = item2.begin();
                    while(it1 != item1.end()){
                        while(it2 != item2.end()){
                            double distance = calDistance(*it1,*it2);
                            it2++;
                            if(distance < minDis){
                                cl1 = i;
                                cl2 = j;
                                minDis = distance;
                            }
                        }
                        it1++;
                    }
                }
            }
        }
        //聚類
        julei(cl1,cl2);
    }

    outPutPoint(points);//輸出點測試
    outPutClass(clas);  //輸出類的測試。
    while(1);
    return 0;
}

2.ClassItem.cpp

#include "stdafx.h"
#include "ClassItem.h"

int ClassItem::CLASSNUM = 5; //總類數,當有合併的時候減1
void ClassItem::addNum(int num){
    this->num +=num;
}
void ClassItem::addPoint(int index){
    item.push_back(index);
}
//構造函數
ClassItem::ClassItem(void)
{
}
ClassItem::ClassItem(int num, int index){ //用於初始化用
    this->num = num;
    this->item.push_back(index);
}

int ClassItem::getNum(){
    return num;
}
void ClassItem::setNum(int num){
    this->num = num;
}
vector<int> &ClassItem::getItem(){
    return item;
}

ClassItem::~ClassItem(void)
{
}

3.Point.cpp

#include "stdafx.h"
#include "Point.h"

Point::Point(int x,int y,int z){
    this->x = x;
    this->y = y;
    this->z = z;
}
Point::Point(void)
{
}


Point::~Point(void)
{
}

注意

1.具體類的頭文件就不上了


問題

1.在ClassItem.cpp中定義的getItem函數

vector<int> &ClassItem::getItem(){
    return item;
}

首先定義的時候沒有加上引用符號,從而造成了錯誤,但是這個錯誤真心不好找,打印出class時,系統提示迭代器不匹配。搗鼓了很久纔有些許理解,可能是因爲沒有引用的時候本身沒有被修改,所以當打印的時候item還沒有被創建。所以產生了錯誤。具體原因不是很清楚,如果哪位大神知道還請不吝賜教。


結果

實驗結果

可見點被分成了兩類,1,3,4,5點爲一類,2點爲一類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章