Dado un gráfico no dirigido y dos conjuntos de nodos, ¿cuál es el mejor algoritmo para verificar que cada elemento del primer conjunto sea adyacente a cada elemento del segundo conjunto?

No puedo decir cuál es el mejor algoritmo absoluto, pero su búsqueda puede acelerarse si tiene la capacidad de cambiar la forma en que almacena su gráfico no dirigido. La forma en que elija hacer esto depende del tamaño del gráfico y de la frecuencia con la que desee realizar la función de búsqueda que está solicitando.

Si los gráficos nunca se vuelven muy grandes, uno podría representar cada nodo como una matriz binaria con un 1 que representa un enlace a un nodo adyacente y un 0 para ningún enlace (por ejemplo, si el tamaño máximo del gráfico fuera 8, entonces si el nodo 0 representaba fácilmente como 01001100 esto indicaría un enlace entre el nodo 1 y los nodos 1, 4 y 5). Con este tipo de representación de datos, para realizar su búsqueda, crearía una representación de nodo exuivalente para cada una de las 2 listas. Cuando tiene este valor, realiza una función AND lógica del primer valor contra cada nodo en la segunda lista … Y luego hace lo mismo para el segundo valor contra la primera lista. Todos estos resultados deben verificarse para asegurarse de que son resultados distintos de cero (cualquier resultado cero indica falta de adyacencia). Este conjunto de operaciones es O (n + m) pero puede o no ser eficiente en la memoria dependiendo del tamaño de su gráfico y el número promedio de conexión nodal conectada. Si su implementación actual usa matrices con índices de 64 bits y un promedio de, digamos, 8 conexiones por nodo … Entonces su gráfica está usando actualmente un promedio de 512 bits por nodo. En este caso, la eficiencia de utilización de la memoria cambia si el tamaño máximo del gráfico es menor o mayor que 512 nodos.
Si desea almacenar los gráficos como indicios, aún puede acelerar sus búsquedas almacenando la lista de adyacencia como un árbol b equilibrado o una tabla hash para hacer que el tiempo de su algoritmo sea O (n • ln (m)).

Esa necesidad de todos significa que, en última instancia, tendrá que verificar cada nodo en cualquiera de los conjuntos para ver si son adyacentes a cada uno en el otro para obtener una respuesta positiva.

Sin embargo, hay formas de mejorar el tiempo necesario para obtener un resultado negativo. Ordene cada nodo en cada conjunto por número de nodos adyacentes. Si un nodo dado tiene menos adyacencias que el otro conjunto tiene nodos, entonces es imposible que la condición sea verdadera. Después de eso, hay varias heurísticas que pueden ayudar, pero dependen en gran medida de los tamaños relativos de los conjuntos y de cuán densa / escasa sería la matriz de adyacencia.

La solución que propone es en realidad O (n (m + E2)) donde n es el número de nodos en el conjunto1, m es el número de nodos en el conjunto2 y E2 es el número total de aristas en el conjunto2. Esta última variable es importante, porque la forma en que se formula el problema no tenemos forma de saber qué tan densa es la gráfica. Podría ser que set2 esté completamente conectado a cualquier otro nodo en el gráfico, en cuyo caso E2 podría ser n * m; o si hay nodos fuera de set1 y set2, podría ser aún mayor.

Con eso en mente, aquí hay una solución que propondré que debería llevarnos a O (n + E), donde n es el número de nodos en el conjunto más pequeño y E es el número de bordes en el conjunto más pequeño.

para cada nodo en el conjunto más pequeño:
suma = 0
para cada vecino en la lista de adyacencia del nodo:
si el conjunto más grande contiene vecino:
suma ++
si suma falso retorno
volver verdadero

Suponiendo que cada conjunto se represente como un conjunto desordenado / hash, la comprobación de contención es O (1).

Debido a que el gráfico no está dirigido, solo necesitamos escanear uno de los conjuntos.

More Interesting

¿Cómo se pueden realizar los pagos mediante algoritmos informáticos?

Cómo resolver el problema ALCATRAZ3 (The honeycomb maze) en SPOJ

¿Cuál es el algoritmo de compresión de texto más utilizado en la industria?

¿Cuáles son los usos de diferentes algoritmos de clasificación como burbuja, selección, inserción, shell, fusión, montón, rápido, árbol, raíz, conteo y clasificación de cubetas en escenarios de la vida real?

¿Podemos decir que el Aprendizaje automático es nuestro compromiso para los problemas para los que no pudimos encontrar algoritmos? Argumentos

¿Qué nivel de estadísticas y algoritmos necesito saber para ser bueno en el aprendizaje automático de estadísticas?

¿Cuál es la forma más eficiente de restar una lista de otra?

¿Cuál es el algoritmo de coincidencia utilizado por las declaraciones de consulta SQL del servidor SQL como "Me gusta 'A%'", "Me gusta '% A'" o "Me gusta '% A%'"?

¿De qué juez en línea puedo aprender algoritmos estándar y estructuras de datos?

¿Puedo volverme competente en estructuras de datos y algoritmos sin leer el libro CLRS?

¿Cuáles son algunos buenos tutoriales que dividen, conquistan y analizan los algoritmos más complejos jamás diseñados?

Cómo resolver la línea de problemas SPOJ usando DP con máscaras de bits

¿Las personas aprenden algoritmos antes de aprender JavaScript?

¿Qué tan difícil es aprender por sí mismo cómo codificar algoritmos eficientes?

¿Cuáles son algunos ejemplos bien conocidos donde se usa la programación dinámica?