K means algorithm c++ language implementation code

  • 2020-04-02 01:55:46
  • OfStack


//k-mean.h
 #ifndef KMEAN_HEAD
 #define KMEAN_HEAD

 #include <vector>
 #include <map>

 //The definition of a point in space
 class Node
 {
     public:
        double pos_x;
        double pos_y;
        double pos_z;
      Node()
      {
          pos_x = 0.0;
          pos_y = 0.0;
          pos_z = 0.0;
      }
      Node(double x,double y,double z)
      {
          pos_x = x;
          pos_y = y;
          pos_z = z;
      }
       friend bool operator < (const Node& first,const Node& second)
       {
          //Comparison of the X-axis
          if(first.pos_x < second.pos_x)
          {
             return true;
          }
        else if (first.pos_x > second.pos_x)
          {
              return false;
        }
         //Compare the Y-axis
      else
      {
        if(first.pos_y < second.pos_y)
             {
                 return true;
             }
             else if (first.pos_y > second.pos_y)
             {
                return false;
             }
             //Comparison of the z axis
         else
         {
             if(first.pos_z < second.pos_z)
                 {
                     return true;
                 }
                 else if (first.pos_z >=  second.pos_z)
                 {
                    return false;
                 }
             }
      }
       }
       friend bool operator == (const Node& first,const Node& second)
       {
             if(first.pos_x == second.pos_x && first.pos_y == second.pos_y && first.pos_z == second.pos_z)
             {
                 return true;
             }
             else
             {
                 return false;
             }
       }
 };
 class KMean
 {
 private:
     int cluster_num;//Number of clusters generated.
     std:: vector<Node> mean_nodes;//The mean point
     std:: vector<Node> data;//All the data points
     std:: map <int , std:: vector<Node> > cluster;//Cluster,key is the subscript of the cluster, and value is all points in the cluster

     void Init();//Initialize the function (generate the representation immediately)
     void ClusterProcess();//In the clustering process, the points in the space are divided into different clusters
     Node GetMean(int cluster_index);//Generate the mean
     void NewCluster();//Identify the new cluster procedure, which calls the ClusterProcess function.
     double Kdistance(Node active,Node other);//Judge the distance between the two points
     public:
     KMean(int c_num,std:: vector<Node> node_vector);
     void Star();//Start the k-means algorithm
 };
#endif // KMEAN_HEAD

The same code at the page code block index 0


 #include "k-mean.h"
 #include <vector>
 #include <map>
 #include <ctime>
 #include <cstdlib>
 #include <algorithm>
 #include <cmath>
 #include <iostream>
 using namespace std;
 #define MAXDISTANCE 1000000

 KMean::KMean(int c_num,vector<Node> node_vector)
 {
       cluster_num = c_num;
       data = node_vector;
       srand((int)time(0));
       Init();
 }
 void KMean::Init()//Initialize the function (generate the representation immediately)
 {
      for(int i =0 ;i<cluster_num;)
      {
            int pos = rand() % data.size();
            bool insert_flag = true;
            //First determine if the selected point is a center point
            for(unsigned int j = 0;j<mean_nodes.size();j++)
            {
                if(mean_nodes[j] ==  data[i])
                {
                    insert_flag = false;
                    break;
                }
            }
            if(insert_flag )
            {
                  mean_nodes.push_back(data[pos]);
                  i++;
            }
      }
      ClusterProcess();//Carry out the clustering process
 }
  void KMean::ClusterProcess()//In the clustering process, the points in the space are divided into different clusters
  {
             //It traverses all the points in space
             for( unsigned int i = 0 ; i < data.size();i++)
             {
                  //Ignore center
                 bool continue_flag = false;
                 for(unsigned int j = 0;j<mean_nodes.size();j++)
                     {
                         if(mean_nodes[j] ==  data[i])
                         {
                                 continue_flag = true;
                                 break;
                         }
                     }
                 if(continue_flag)
                     {
                         continue;
                     }
                  //Here is the clustering process
                  //First, find the center closest to the current point and record the cluster where the center is located
                  int min_kdistance = MAXDISTANCE;
                  int index = 0 ;
                  for(unsigned int j = 0;j < mean_nodes.size();j++)
                  {
                      double dis = Kdistance(data[i],mean_nodes[j]);
                      if(dis < min_kdistance)
                      {
                          min_kdistance = dis;
                          index = j;
                      }
                  }
                   //Delete the current point from the original cluster
                   map<int,vector<Node> >::iterator iter;
         //Search for all clusters
                   for(iter = cluster.begin();iter != cluster.end();++iter)
                   {
                vector<Node>::iterator node_iter;
                      bool jump_flag = false;
                      //Search for vectors in each cluster
                      for(node_iter = iter->second.begin();node_iter != iter->second.end();node_iter++)
                   {
                   if(*node_iter == data[i])
                  {
                             //If the current point is in the updated cluster, the next operation is ignored
                       if(index == iter->first)
                            {
                           continue_flag = true;
                             }
                             else
                             {
                           iter->second.erase(node_iter);
                             }
                       jump_flag = true;
                       break;
                    }
                }
                    if(jump_flag)
                    {
                     break;
                    }
                     }
                   if(continue_flag)
               {
                     continue;
                   }
                   //Inserts the current point into the cluster corresponding to the central point
                   //See if the center point is already in the map
                  bool insert_flag = true;
                  for(iter = cluster.begin(); iter != cluster.end();++iter)
                  {
                     if(iter->first == index)
                  {
                          iter->second.push_back(data[i]);
                          insert_flag = false;
                       break;
                   }
                  }
                  //Creates a new element object if it does not exist
                  if(insert_flag)
                  {
                      vector<Node> cluster_node_vector;
                      cluster_node_vector.push_back(data[i]);
                      cluster.insert(make_pair(index,cluster_node_vector));
                  }
             }
  }

  double KMean::Kdistance(Node active,Node other)
  {
         return sqrt(pow((active.pos_x-other.pos_x),2) + pow((active.pos_y - other.pos_y),2) + pow((active.pos_z - other.pos_z),2));
  }

  Node KMean::GetMean(int cluster_index)
  {
      //Pass in a parameter to see if it has crossed the line
      if( cluster_num <0 || unsigned (cluster_index) >= mean_nodes.size() )
      {
          Node new_node;
          new_node.pos_x = -1.0;
          new_node.pos_y = -1.0;
          new_node.pos_z = -1.0;
          return new_node;
      }
      //Find the mean of all the points in the cluster
      Node sum_node;
      Node aver_node;
        for(int j = 0;j < cluster[cluster_index].size();j++)
         {
           sum_node.pos_x += cluster[cluster_index].at(j).pos_x;
            sum_node.pos_y += cluster[cluster_index].at(j).pos_y;
           sum_node.pos_z += cluster[cluster_index].at(j).pos_z;
        }
         aver_node.pos_x = sum_node.pos_x*1.0/ cluster[cluster_index].size();
         aver_node.pos_y = sum_node.pos_y*1.0 / cluster[cluster_index].size();
         aver_node.pos_z = sum_node.pos_z*1.0 / cluster[cluster_index].size();
       //Find the closest point to the mean
      double min_dis = MAXDISTANCE;
      Node new_mean_doc;
      for(unsigned int i  = 0;i< cluster[cluster_index].size();i++)
      {
            double dis = Kdistance(aver_node,cluster[cluster_index].at(i));
            if(min_dis > dis)
            {
                  min_dis = dis;
                  new_mean_doc = cluster[cluster_index].at(i);
            }
      }
      return new_mean_doc;
  }

  void KMean::NewCluster()//Identify the new center point
  {
       for (unsigned int i = 0;i < mean_nodes.size();i++)
       {
            Node new_node =GetMean(i);
            mean_nodes[i] = new_node;
       }
       ClusterProcess();
  }

 void KMean::Star()
 {
     for (int i = 0;i<100;i++)
     {
         NewCluster();
         cout << "no:"<< i<<endl;
         for(int j = 0;j < mean_nodes.size();j++)
     {
         cout << cluster[j].size()<<endl;
     }
     }
 }


#include <iostream>
#include <vector>
#include "k-mean.h"
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
 {
     srand((int) time(0));
     vector<Node> data;
     for(int i =0;i<100;i++)
     {
          Node node;
          node.pos_x = (random() % 17 )*1.2;
          node.pos_y = (random() % 19 )*1.2;
          node.pos_z = (random() % 21) *1.2;
          data.push_back(node);
     }
     KMean kmean(3,data);
     kmean.Star();
     return 0;
 }


Related articles: