You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实体间关联关系发现:基于共享值的实体分组求解

实体关联分组实现方案(Scala/Python/伪代码)

给定如下数据集(Scala格式):

List((X,Set(" 1", " 7")), (Z,Set(" 5")), (D,Set(" 2")), (E,Set(" 8")), ("F ",Set(" 5", " 9", " 108")), (G,Set(" 2", " 11")), (A,Set(" 7", " 5")), (M,Set(108)))

需按规则分组:若两个实体的集合存在共同元素则二者相关,关联关系可传递。最终将所有关联实体归为一组,输出类似((X,Z,A,F,M),(D,G),(E))的分组结果(组内、组间顺序无关)。


Scala 实现

核心思路是用**并查集(Union-Find)**处理传递性关联,先统一数据格式(解决空格、类型不一致问题),再通过元素映射完成实体合并:

import scala.collection.mutable

object EntityGrouping {
  def main(args: Array[String]): Unit = {
    // 原始数据集
    val rawData = List(
      ("X", Set(" 1", " 7")),
      ("Z", Set(" 5")),
      ("D", Set(" 2")),
      ("E", Set(" 8")),
      ("F ", Set(" 5", " 9", " 108")),
      ("G", Set(" 2", " 11")),
      ("A", Set(" 7", " 5")),
      ("M", Set(108))
    )

    // 数据预处理:实体名去空格,集合元素统一为去空格的字符串
    val cleanedData = rawData.map { case (entity, elements) =>
      val cleanEntity = entity.trim
      val cleanElements = elements.map(e => e.toString.trim)
      (cleanEntity, cleanElements)
    }

    // 构建元素到实体列表的映射:key=元素,value=关联实体集合
    val elementToEntities = mutable.HashMap[String, mutable.Set[String]]()
    cleanedData.foreach { case (entity, elements) =>
      elements.foreach { elem =>
        elementToEntities.getOrElseUpdate(elem, mutable.Set()) += entity
      }
    }

    // 并查集实现
    val parent = mutable.HashMap[String, String]()
    // 初始化:每个实体的父节点是自己
    cleanedData.foreach { case (entity, _) => parent(entity) = entity }

    // 查找根节点(带路径压缩)
    def find(entity: String): String = {
      if (parent(entity) != entity) {
        parent(entity) = find(parent(entity))
      }
      parent(entity)
    }

    // 合并两个实体的集合
    def union(a: String, b: String): Unit = {
      val rootA = find(a)
      val rootB = find(b)
      if (rootA != rootB) {
        parent(rootB) = rootA
      }
    }

    // 遍历每个元素对应的实体列表,合并所有关联实体
    elementToEntities.values.foreach { entities =>
      if (entities.size > 1) {
        val head = entities.head
        entities.tail.foreach(union(head, _))
      }
    }

    // 分组:按根节点聚合实体
    val groups = cleanedData.map(_._1).groupBy(find).values
    // 输出结果(转成Tuple格式,顺序无关)
    val result = groups.map(_.toList).toList
    println(result)
    // 输出示例:List(List(X, Z, A, F, M), List(D, G), List(E))
  }
}

Python 实现

同样基于并查集,步骤与Scala一致,语法更简洁:

def main():
    # 原始数据集
    raw_data = [
        ("X", {" 1", " 7"}),
        ("Z", {" 5"}),
        ("D", {" 2"}),
        ("E", {" 8"}),
        ("F ", {" 5", " 9", " 108"}),
        ("G", {" 2", " 11"}),
        ("A", {" 7", " 5"}),
        ("M", {108})
    ]

    # 数据预处理:统一格式
    cleaned_data = []
    for entity, elements in raw_data:
        clean_entity = entity.strip()
        clean_elements = {str(e).strip() for e in elements}
        cleaned_data.append((clean_entity, clean_elements))

    # 构建元素到实体的映射
    element_to_entities = {}
    for entity, elements in cleaned_data:
        for elem in elements:
            if elem not in element_to_entities:
                element_to_entities[elem] = set()
            element_to_entities[elem].add(entity)

    # 并查集初始化
    parent = {}
    for entity, _ in cleaned_data:
        parent[entity] = entity

    # 查找根节点(路径压缩)
    def find(entity):
        while parent[entity] != entity:
            parent[entity] = parent[parent[entity]]
            entity = parent[entity]
        return entity

    # 合并集合
    def union(a, b):
        root_a = find(a)
        root_b = find(b)
        if root_a != root_b:
            parent[root_b] = root_a

    # 合并所有关联实体
    for entities in element_to_entities.values():
        if len(entities) > 1:
            entities = list(entities)
            head = entities[0]
            for entity in entities[1:]:
                union(head, entity)

    # 分组
    groups = {}
    for entity, _ in cleaned_data:
        root = find(entity)
        if root not in groups:
            groups[root] = []
        groups[root].append(entity)

    # 输出结果
    result = tuple(tuple(group) for group in groups.values())
    print(result)
    # 输出示例:(('X', 'A', 'Z', 'F', 'M'), ('D', 'G'), ('E',))

if __name__ == "__main__":
    main()

伪代码

// 1. 数据预处理
FUNCTION preprocess(rawData):
    cleanedData = []
    FOR each (entity, elements) IN rawData:
        cleanEntity = trim(entity)
        cleanElements = { trim(str(elem)) FOR elem IN elements }
        ADD (cleanEntity, cleanElements) TO cleanedData
    RETURN cleanedData

// 2. 构建元素-实体映射
FUNCTION buildElementMap(cleanedData):
    elementMap = EMPTY MAP
    FOR each (entity, elements) IN cleanedData:
        FOR each elem IN elements:
            IF elem NOT IN elementMap:
                elementMap[elem] = EMPTY SET
            ADD entity TO elementMap[elem]
    RETURN elementMap

// 3. 并查集操作
INIT parent MAP: FOR each entity IN cleanedData, parent[entity] = entity

FUNCTION find(entity):
    IF parent[entity] != entity:
        parent[entity] = find(parent[entity])  // 路径压缩
    RETURN parent[entity]

FUNCTION union(a, b):
    rootA = find(a)
    rootB = find(b)
    IF rootA != rootB:
        parent[rootB] = rootA

// 4. 合并关联实体
elementMap = buildElementMap(cleanedData)
FOR each entities IN elementMap.values():
    IF size(entities) > 1:
        head = first element IN entities
        FOR each entity IN entities EXCEPT head:
            union(head, entity)

// 5. 生成分组
groups = EMPTY MAP
FOR each entity IN cleanedData:
    root = find(entity)
    IF root NOT IN groups:
        groups[root] = EMPTY LIST
    ADD entity TO groups[root]

// 输出分组结果
OUTPUT values of groups

内容的提问来源于stack exchange,提问作者soumya-kole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:00:46