union find 算法 可用在聚类

本文介绍了并查集(Union Find)算法在解决聚类问题上的应用,通过四个具体的题目来阐述如何使用并查集进行集合的合并与查找。包括找到与0号有关联的所有集合人数、计算可能的宗教分支数量、判断有向关系是否能构成树以及模拟计算机网络修复等场景。并展示了不同题目中并查集操作的细微变化。

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

 
并查集(Union-Find Sets)
2009-02-23 12:38

本文通过几道题介绍一下并查集的应用。

第一道题目:The Sus pects (http://acm.pku.edu.cn/JudgeOnline/problem?id=1611)

1. N个人编号,从0到N-1。
2. 给出这N个人分成M个集合的描述(同一个人可以加入不同的集合)。
    求所有和0号有关系的集合的人数!


//用到并查集的3种基本操作
//并查集虽然用线性的数组,但是使用 的操作。

#include <stdio.h>
int set[30001],i,j;


void MakeSet(int n)
//集合初始化为-1
//set[x]<0 表示x是根 并且它的所有结点的个数为该值的绝对值。
//初始可以看成,数组中每个元素是一个根,相互独立的集合。
{
    for(i=0;i<n;i++)
        set[i]=-1;
}

int FindSet(int a)  
//查找含有a的集合的根
{
    int i=a,t;
    while(set[i]>=0) //递归查找直到找到根为止
        i=set[i];
       
     while(i!=a) //压缩路径,使得各个孩子直接指向根,以便下次搜索加速。
     {
         t=set[a];
         set[a]=i;
         a=t;
     }
    return i;
}
int UnionSet(int a,int b)
//合并含有a和b的集合。并返回合并后树的根
{
    if(a==b)
        return a;
    if(set[a]>=set[b])
    {
        set[b]+=set[a];   //把2集合元素个数相加
        set[a]=b;    //把a的根设置为b
        return b;
    }
    else
    {
        set[a]+=set[b];   //把2集合元素个数相加
        set[b]=a;    //把b的根设置为a
        return a;
    }
}

int main()
{
    int number,a,b,n,m;
    while(scanf("%d %d",&n,&m) && (n || m))
    {
        MakeSet(n);
        for(i=0;i<m;i++)
        {
            scanf("%d",&number);
            scanf("%d",&a);
            a=FindSet(a);    //找到第一个元素所在集合的根。
            for(j=1;j<number;j++)
            {
                scanf("%d",&b);
                b=FindSet(b);        //找到这个元素b所在的集合
                a=UnionSet(a,b); //把a和b合并,然后把合并后的根返回给a以便循环使用。
            }
        }
     

### 使用聚类算法优化目标检测模型中的锚框设计 在目标检测领域,锚框(anchor box)的设计对于模型性能至关重要。通过聚类算法优化锚框的设计是一种常见且有效的策略。以下是具体方法: #### 1. 数据准备 为了获得适合的锚框尺寸和比例,需要对训练数据集中标注的目标边界框进行统计分析。这些边界框通常是矩形区域,表示目标的位置和大小。可以提取所有标注的边界框宽高比作为输入数据用于后续聚类操作。 ```python import xml.etree.ElementTree as ET import os def parse_annotations(xml_path): wh_list = [] for file_name in os.listdir(xml_path): if not file_name.endswith('.xml'): continue tree = ET.parse(os.path.join(xml_path, file_name)) root = tree.getroot() size = root.find('size') width = float(size.find('width').text) height = float(size.find('height').text) for obj in root.findall('object'): bndbox = obj.find('bndbox') xmin = int(bndbox.find('xmin').text) ymin = int(bndbox.find('ymin').text) xmax = int(bndbox.find('xmax').text) ymax = int(bndbox.find('ymax').text) w = (xmax - xmin) * width h = (ymax - ymin) * height wh_list.append([w, h]) return wh_list ``` 上述代码展示了如何解析XML文件并获取宽度高度列表 `wh_list`[^5]。 #### 2. 应用 K-Means 或 K-Means++ K-Means 是一种常用的无监督学习算法,能够将相似的对象分组到同一簇中。然而,在实际应用中,标准 K-Means 的初始质心选择可能会导致较差的结果。因此,推荐使用改进版本 **K-Means++** 来初始化质心位置,从而提升聚类效果[^4]。 - 定义距离度量函数:由于锚框涉及面积计算,通常采用 IoU(Intersection over Union)而非欧氏距离衡量两个边界框之间的差异。 ```python from sklearn.cluster import KMeans import numpy as np def iou_distance(box, clusters): """ 计算单个边框与一组簇中心的距离(IoU) :param box: 单一边界框 [w,h] :param clusters: 所有簇中心 [[w0,h0],...,[wk,hk]] :return: 平均交并比 """ intersection_area = np.minimum(clusters[:, 0], box[0]) * np.minimum(clusters[:, 1], box[1]) union_area = box[0]*box[1] + clusters[:, 0]*clusters[:, 1] - intersection_area ious = intersection_area / union_area return 1 - np.max(ious) class YOLO_Kmeans: def __init__(self, cluster_number=9): self.cluster_number = cluster_number def fit(self, data_wh): kmeans_model = KMeans(n_clusters=self.cluster_number, init='k-means++', n_init=10).fit(data_wh) anchors = sorted(kmeans_model.cluster_centers_, key=lambda x:x[0]*x[1]) avg_iou = sum(np.max(iou_distance(d, anchors)) for d in data_wh)/len(data_wh)*100 print(f"Anchor Boxes: {anchors}") print(f"Avg IOU with ground truth boxes: {avg_iou:.2f}%") return anchors ``` 此部分实现了基于 K-Means++ 初始化的聚类过程,并输出平均 IoU 值评估拟合质量[^2]。 #### 3. 结果验证与调整 完成聚类后得到的一系列锚框应反映训练样本的真实分布特性。如果发现某些类别未被充分覆盖,则可考虑增加更多样例或者重新划分测试集合再执行一次完整的流程[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值