"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cómo agrupamos identificadores relacionados en un gráfico no dirigido representado por dos columnas, \'Identificador1\' e \'Identificador2\', y les asignamos ID de grupo únicos?

¿Cómo agrupamos identificadores relacionados en un gráfico no dirigido representado por dos columnas, \'Identificador1\' e \'Identificador2\', y les asignamos ID de grupo únicos?

Publicado el 2024-10-31
Navegar:714

How do we group related identifiers in an undirected graph represented by two columns, \'Identifier1\' and \'Identifier2\', and assign them unique group IDs?

Encontrar subgrafos conectados en un gráfico no dirigido

Problema:

Dado un gráfico no dirigido representado por dos columnas, 'Identificador1' e 'Identificador2', ¿Cómo agrupamos identificadores que están relacionados entre sí y les asignamos ID de grupo únicos?

Solución:

Este problema se puede resolver tratando los datos como bordes en un gráfico y atravesando todos los bordes recursivamente.

Algoritmo recursivo:

  1. Cree una tabla que contenga todos los identificadores únicos de ambas columnas.
  2. Cree una tabla que contenga todos los bordes (pares de identificadores) en ambas direcciones.
  3. Defina una consulta recursiva que recorra el gráfico a partir de cada identificador y cree una ruta de identificadores atravesados.
  4. Agrupe los resultados por el identificador inicial (identificador de anclaje) para identificar los componentes conectados.
  5. Asigne un ID de grupo único a cada componente conectado según el identificador de anclaje.

Consulta de ejemplo (SQL):

WITH
CTE_Idents AS (
    SELECT Ident1 AS Ident
    FROM @T

    UNION

    SELECT Ident2 AS Ident
    FROM @T
),
CTE_Pairs AS (
    SELECT Ident1, Ident2
    FROM @T
    WHERE Ident1 <> Ident2

    UNION

    SELECT Ident2 AS Ident1, Ident1 AS Ident2
    FROM @T
    WHERE Ident1 <> Ident2
),
CTE_Recursive AS (
    SELECT
        CAST(CTE_Idents.Ident AS varchar(8000)) AS AnchorIdent 
        , Ident1
        , Ident2
        , CAST(','   Ident1   ','   Ident2   ',' AS varchar(8000)) AS IdentPath
        , 1 AS Lvl
    FROM 
        CTE_Pairs
        INNER JOIN CTE_Idents ON CTE_Idents.Ident = CTE_Pairs.Ident1

    UNION ALL

    SELECT 
        CTE_Recursive.AnchorIdent 
        , CTE_Pairs.Ident1
        , CTE_Pairs.Ident2
        , CAST(CTE_Recursive.IdentPath   CTE_Pairs.Ident2   ',' AS varchar(8000)) AS IdentPath
        , CTE_Recursive.Lvl   1 AS Lvl
    FROM
        CTE_Pairs
        INNER JOIN CTE_Recursive ON CTE_Recursive.Ident2 = CTE_Pairs.Ident1
    WHERE
        CTE_Recursive.IdentPath NOT LIKE CAST('%,'   CTE_Pairs.Ident2   ',%' AS varchar(8000))
),
CTE_RecursionResult AS (
    SELECT AnchorIdent, Ident1, Ident2
    FROM CTE_Recursive
),
CTE_CleanResult AS (
    SELECT AnchorIdent, Ident1 AS Ident
    FROM CTE_RecursionResult

    UNION

    SELECT AnchorIdent, Ident2 AS Ident
    FROM CTE_RecursionResult
)
SELECT
    CTE_Idents.Ident
    ,CASE WHEN CA_Data.XML_Value IS NULL 
    THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END AS GroupMembers
    ,DENSE_RANK() OVER(ORDER BY 
        CASE WHEN CA_Data.XML_Value IS NULL 
        THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END
    ) AS GroupID
FROM
    CTE_Idents
    CROSS APPLY
    (
        SELECT CTE_CleanResult.Ident ','
        FROM CTE_CleanResult
        WHERE CTE_CleanResult.AnchorIdent = CTE_Idents.Ident
        ORDER BY CTE_CleanResult.Ident FOR XML PATH(''), TYPE
    ) AS CA_XML(XML_Value)
    CROSS APPLY
    (
        SELECT CA_XML.XML_Value.value('.', 'NVARCHAR(MAX)')
    ) AS CA_Data(XML_Value)
WHERE
    CTE_Idents.Ident IS NOT NULL
ORDER BY Ident;

Puntos clave:

  • La CTE (expresión de tabla común) recursiva atraviesa el gráfico y construye componentes conectados.
  • La instrucción SELECT final asigna el grupo Identifica y genera resultados en el formato deseado.
  • Esta solución está optimizada para evitar cálculos redundantes y proporcionar resultados eficientes.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3