es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Algoritmo de consulta utilizando un arreglo prioritario y sin tener en cuenta las condiciones.

Estoy enfrentando este problema en la logística de mi empresa:

Dado un arreglo de valores mixtos:

arr = [
    v1 => a,
    v2 => b,
    v3 => c,
    v4 => d
]

ordenado por prioridad ASC (v1 es más importante que v2, … etc)

Necesito buscar valores en una tabla t de la siguiente manera:

select * from t where
    ... Y
    t.v1 = a Y
    t.v2 = b Y
    t.v3 = c Y
    t.v4 = d

Los 3 puntos en la consulta son las condiciones fijas.

Si no puedo encontrar ningún valor en la consulta, realizar la misma consulta ignorando el valor menos importante del arreglo:

select * from t where
    ... Y
    t.v1 = a Y
    t.v2 = b Y
    t.v3 = c

Nuevamente, si no se encuentra el valor, realizar una consulta ignorando el siguiente valor menos importante:

select * from t where
    ... Y
    t.v1 = a Y
    t.v2 = b Y
    t.v4 = d

La consulta puede ignorar todos los elementos del arreglo como en la última consulta:

select * from t where ...

Repetir esto hasta encontrar al menos 1 resultado de consulta o si todos los elementos del arreglo son nulos y no se encontró ningún resultado (devolver falso).

He diseñado mi algoritmo de búsqueda utilizando números binarios para encontrar el valor que funciona de la siguiente manera:

binaryValue = (2 ^ arr.lenght) - 1 //(En este caso: 2^4-1 = 15)

convertir el número binario 15 en un arreglo de booleanos “exploded” = [1, 1, 1, 1] (15 en binario es 1111)

Luego realizar la consulta considerando la posición 0 del arreglo booleanArray “exploded”: si es verdadero, considerar el valor en el arreglo de valores mixtos “arr” y así sucesivamente.

Hacer un bucle desde 15 hasta 0 (la iteración 0 es cuando el arreglo booleano es [0,0,0,0] y se ignoran todos los casos). La secuencia será la siguiente con esta lógica:

[a, b, c, d] // [1,1,1,1] = 15 (select * from t where ... and v1=a and v2=b and v3=c and v4=d)
[a, b, c] // [1,1,1,0] = 14 (select * from t where ... and v1=a and v2=b and v3=c)
[a, b, d] // [1,1,0,1] = 13 (select * from t where ... and v1=a and v2=b and v4=d)
...
[] // [0,0,0,0] = 0 (select * from t where ...)

El algoritmo de búsqueda funciona correctamente, pero tengo un gran problema de rendimiento.

El número de consultas realizadas en esta búsqueda es arr.length! (factorial). Por lo tanto, cuando el arreglo tiene longitud 4, el peor escenario realiza 24 consultas.
Si la longitud de arr es 6 (que es la longitud con la que estoy lidiando actualmente en mi código en producción), el peor caso realiza 720 consultas, lo cual es inaceptable.

Necesito encontrar una forma de mejorar esta búsqueda. ¿Alguien puede ayudarme?

Gracias de antemano.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Mejorado Algoritmo de Búsqueda para un Array de Valores Mixtos

    Como experto en TI especializado en SQL, algoritmos, rendimiento, búsqueda y lógica, aquí está mi recomendación para mejorar el algoritmo de búsqueda para el array de valores mixtos.

    El actual algoritmo de búsqueda realiza arr.length! consultas, lo cual no es escalable para arrays con un gran número de elementos. En cambio, podemos utilizar una estrategia de dividir y conquistar para reducir el número de consultas y mejorar el rendimiento.

    Aquí está el algoritmo revisado:

    1. Ordenar el array de valores mixtos en orden descendente de prioridad. Esto significa que el valor más importante estará en la posición 0 y el valor menos importante estará al final del array.
    2. Inicializar una variable resultado como null. Esta variable contendrá el resultado final de la búsqueda.

    3. Crear un nuevo array queryArr para guardar la consulta de búsqueda. Inicializarlo como [...condicionesFijas], donde condicionesFijas son las condiciones fijas en la consulta.

    4. Crear una nueva variable índice e inicializarla en 0. Esta variable se utilizará para llevar un registro de la posición actual en queryArr.

    5. Mientras resultado siga siendo null y índice sea menor que arr.length:

    • Construir la consulta de búsqueda utilizando el actual queryArr: select * from t where ... and queryArr[0] and queryArr[1] and ... and queryArr[índice].

    • Ejecutar la consulta de búsqueda y almacenar el resultado en resultado. Si hay un resultado, devolverlo.

    • Si resultado sigue siendo null, eliminar el último elemento de queryArr e incrementar índice.

    1. Si no se encontraron resultados y índice es igual a arr.length, devolver false.

    Al ordenar el array de valores mixtos en orden descendente de prioridad y utilizar una estrategia de dividir y conquistar, podemos reducir significativamente el número de consultas y mejorar el rendimiento.

    ¡Espero que esto sea de ayuda! Avíseme si tiene alguna pregunta o necesita más asistencia.

Comments are closed.