cluster二维数组存放数据的编号,每次计算两个簇的距离,找出距离最近的,将其中一个簇的编号加入另一个编号的一维序列中,再将这个编号清除,之后再循环cluster。
#include<vector>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
struct Point
{
double x;
double y;
};
double distance(const Point& a, const Point& b)
{
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x * x + y * y);
}
vector<vector<int>> agens(const vector<Point>& data,int k)
{
int n = data.size();
vector<vector<int>> cluster;
for (int i = 0; i < n; i++)
{
cluster.push_back({ i });
}
while (cluster.size() > k)
{
int index_i = 0;
int index_j = 1;
double min = distance(data[cluster[0][0]], data[cluster[1][0]]);
for (int i = 0; i < cluster.size(); i++) //找出距离最近的两个簇
{
for (int j = i + 1; j < cluster.size(); j++)
{
double dis = distance(data[cluster[i][0]], data[cluster[j][0]]);
if (dis < min)
{
index_i = i;
index_j = j;
min = dis;
}
}
}
cluster[index_i].insert(cluster[index_i].end(), cluster[index_j].begin(), cluster[index_j].end());
cluster.erase(cluster.begin() + index_j);
}
return cluster;
}
vector<Point> ReadData(string filename)
{
vector<Point> data;
ifstream file(filename);
if (file.is_open())
{
string line;
while (getline(file, line))
{
istringstream iss(line);
double x, y;
string token;
Point point;
if (getline(iss, token, ',') && istringstream(token) >> point.x &&
getline(iss, token, ',') && istringstream(token) >> point.y) {
data.push_back(point);
}
/*if (iss >> x >> y)
{
data.push_back({ x, y });
}*/
}
}
else
{
cout << "open fail";
}
file.close();
return data;
}
int main()
{
//vector<Point> Data = { {1, 1}, {1, 2}, {2, 1}, {2,2}, {3, 4},{3,5} ,{4,4} ,{4,5} };
vector<Point> Data = ReadData("data2.txt");
int k;
cin >> k;
vector<vector<int>> labels;
labels=agens(Data, k);
for (const vector<int>& row : labels)
{
cout << "{";
int size = row.size();
for (int i = 0; i < size; i++)
{
cout << row[i] + 1;
if (i != size - 1)
{
cout << ",";
}
}
cout << "}";
}
}
关键在于理解 distance(data[cluster[i][0]], data[cluster[j][0]]);
结果:
数据1:注释部分
数据2:data2.txt