⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csom.cpp

📁 fuzzy k-means algorithm for cluster
💻 CPP
字号:
#include "Csom.h"


void Csom::Create(int cxClient,
                  int cyClient,
                  int CellsUp,
                  int CellsAcross,
                  int NumIterations)
{

  m_dCellWidth  = (double)cxClient / (double)CellsAcross;

  m_dCellHeight = (double)cyClient / (double)CellsUp;

  m_iNumIterations = NumIterations;
  
  //create all the nodes
  for (int row=0; row<CellsUp; ++row)
  {
    for (int col=0; col<CellsAcross; ++col)
    {
      m_SOM.push_back(CNode(col*m_dCellWidth,           //left
                            (col+1)*m_dCellWidth,       //right
                            row*m_dCellHeight,          //top
                            (row+1)*m_dCellHeight,      //bottom
                            constSizeOfInputVector));   //num weights
    }
  }

  //this is the topological 'radius' of the feature map
  m_dMapRadius = max(constWindowWidth, constWindowHeight)/2;

   //used in the calculation of the neighbourhood width of m_dInfluence
  m_dTimeConstant = m_iNumIterations/log(m_dMapRadius);
}  

//---------------------------- Render ------------------------------------
//
//------------------------------------------------------------------------
void Csom::Render(HDC surface)
{
  //render all the cells
  for (int nd=0; nd<m_SOM.size(); ++nd)
  {
    m_SOM[nd].Render(surface);
    
  }

  SetBkMode(surface, TRANSPARENT);
  SetTextColor(surface, RGB(255,255,255));
  
  string s = "Iteration: " + itos(m_iIterationCount);
  TextOut(surface, 5, constWindowHeight - 40, s.c_str(), s.size());

  s = "Press 'R' to retrain";
  TextOut(surface, 260, constWindowHeight - 40, s.c_str(), s.size());

/*
  s = "Learning: " + ftos(m_dLearningRate);
  TextOut(surface, 5, 20, s.c_str(), s.size());

  s = "Radius: " + ftos(m_dNeighbourhoodRadius);
  TextOut(surface, 5, 40, s.c_str(), s.size());
*/
}
              
      
//--------------------------- Epoch --------------------------------------
//
//  Given a std::vector of input vectors this method choses one at random
//  and runs the network through one training epoch
//------------------------------------------------------------------------
bool Csom::Epoch(const vector<vector<double> > &data)
{
  //make sure the size of the input vector matches the size of each node's 
  //weight vector
  if (data[0].size() != constSizeOfInputVector) return false;

  //return if the training is complete
  if (m_bDone) return true;
 
  
  //enter the training loop
  if (--m_iNumIterations > 0)
  {
    //the input vectors are presented to the network at random
    int ThisVector = RandInt(0, data.size()-1);

    //present the vector to each node and determine the BMU
    m_pWinningNode = FindBestMatchingNode(data[ThisVector]);

    //calculate the width of the neighbourhood for this timestep
    m_dNeighbourhoodRadius = m_dMapRadius * exp(-(double)m_iIterationCount/m_dTimeConstant);

    //Now to adjust the weight vector of the BMU and its
    //neighbours

    //For each node calculate the m_dInfluence (Theta from equation 6 in
    //the tutorial. If it is greater than zero adjust the node's weights
    //accordingly
    for (int n=0; n<m_SOM.size(); ++n)
    {
      //calculate the Euclidean distance (squared) to this node from the
      //BMU
      double DistToNodeSq = (m_pWinningNode->X()-m_SOM[n].X()) *
                            (m_pWinningNode->X()-m_SOM[n].X()) +
                            (m_pWinningNode->Y()-m_SOM[n].Y()) *
                            (m_pWinningNode->Y()-m_SOM[n].Y()) ;

      double WidthSq = m_dNeighbourhoodRadius * m_dNeighbourhoodRadius;

      //if within the neighbourhood adjust its weights
      if (DistToNodeSq < (m_dNeighbourhoodRadius * m_dNeighbourhoodRadius))
      {

        //calculate by how much its weights are adjusted
        m_dInfluence = exp(-(DistToNodeSq) / (2*WidthSq));

        m_SOM[n].AdjustWeights(data[ThisVector],
                               m_dLearningRate,
                               m_dInfluence);
      }

    }//next node


    //reduce the learning rate
    m_dLearningRate = constStartLearningRate * exp(-(double)m_iIterationCount/m_iNumIterations);
    
    ++m_iIterationCount;

  }

  else
  {
    m_bDone = true;
  }

  return true;
}

//--------------------- CalculateBestMatchingNode ------------------------
//
//  this function presents an input vector to each node in the network
//  and calculates the Euclidean distance between the vectors for each
//  node. It returns a pointer to the best performer
//------------------------------------------------------------------------
CNode* Csom::FindBestMatchingNode(const vector<double> &vec)
{
  CNode* winner = NULL;

  double LowestDistance = 999999;
 
  for (int n=0; n<m_SOM.size(); ++n)
  {
    double dist = m_SOM[n].CalculateDistance(vec);

    if (dist < LowestDistance)
    {
      LowestDistance = dist;

      winner = &m_SOM[n];
    }
  }

  return winner;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -