一种快速拓扑聚类算法

该代码实现了一个C++程序,用于处理节点聚类问题。程序首先定义了点和邻接列表结构,然后通过遍历邻接列表更新节点值,确定节点间的相互关系。接着,依据节点关系进行聚类,找出最大节点编号并输出各个聚类的元素。最后,程序展示了如何存储和打印聚类结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用场景,节点编号不重叠,可以缺损,确定每个节点的相互关系和最大的节点编号,对节点进行聚类。如下图所示,分三个簇,计算每个簇包含的元素。

 插入代码,暂时没有继续优化的空间

// TopologicalClustering.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
#include <Windows.h>
#include <set>
#include <map>

using namespace std;

struct Point
{
    int x;
    int y;
    Point(int x0,int y0)
    {
        x = x0;
        y = y0;
    }
};

struct listS
{
    std::vector<listS*> ptrNeiber;
    int id;
    int value;
    bool flag = true;
};

int updataNet(listS* listCur, int minV, set<int>& vecNode)
{
    listCur->flag = false;
    for (int i = 0; i < listCur->ptrNeiber.size(); i++)
    {
        if (listCur->ptrNeiber[i]->flag)
        {
            vecNode.insert(listCur->ptrNeiber[i]->value);
            int curV = updataNet(listCur->ptrNeiber[i],minV,vecNode);
            if (curV<minV)
            {
                minV = curV;
            }
        }
    }
    return minV;
}

int main()
{
    int maxSize = 100;
    vector<Point> vecP = {Point(2,12),Point(12,5),Point(12,3),Point(12,7),Point(5,7),Point(7,8),Point(8,3),Point(3,26),Point(8,25),Point(26,11),
    Point(16,22),Point(16,4),Point(4,19),Point(22,19),Point(19,17),Point(22,17),Point(17,36),
    Point(41,14),Point(14,6),Point(41,6),Point(6,9)};

    vector<listS> listT(maxSize);
    for (int i = 0; i < maxSize; i++)
    {
        listS listInit;
        listInit.value = i;
        listInit.id = i;
        listT[i] = listInit;
    }
    set<int> initVec;
    for (int i = 0; i < vecP.size(); i++)
    {
        Point p0 = vecP[i];
        listS* listCur = &listT[p0.y];
        listT[p0.x].ptrNeiber.push_back(listCur);
        listCur = &listT[p0.x];
        listT[p0.y].ptrNeiber.push_back(listCur);
    }

    for (int i = 0; i < maxSize; i++)
    {
        if (listT[i].ptrNeiber.size()!=0)
        {
            listS* curList = &listT[i];
            set<int> vecNode;
            vecNode.insert(curList->value);
            curList->flag = false;
            int curMIn = curList->value = updataNet(curList,curList->value,vecNode);
            for (set<int>::iterator it = vecNode.begin(); it != vecNode.end(); ++it)
            {
                listT[*it].value = curMIn;
                listT[*it].flag = true;
            }
        }
    }

    map<int, vector<int>> mapCluster;
    map<int, vector<int>>::iterator mapIter;
    for (int i = 0; i < maxSize; i++)
    {
        if (listT[i].ptrNeiber.size()!=0)
        {
            mapIter = mapCluster.find(listT[i].value);
            if (mapIter!=mapCluster.end())
            {
                mapIter->second.push_back(i);
            }
            else
            {
                vector<int> vecTemp = {i};
                mapCluster.insert(std::pair<int, std::vector<int>>(listT[i].value, vecTemp));
            }
        }
    }
    for (mapIter=mapCluster.begin(); mapIter !=mapCluster.end(); ++mapIter)
    {
        cout << "簇" << mapIter->first <<":";
        for (int i = 0; i < mapIter->second.size(); i++)
        {
            cout << mapIter->second[i]<<",";
        }
        cout << endl;
    }

    std::cout << "Hello World!\n";
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

测试效果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值