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.

Tratando de entender la complejidad temporal de esta suma de subconjuntos recursiva dinámica.

Devuelve verdadero si existe una subsecuencia de A[0…n] con la suma dada

def subsetSum(A, n, k, lookup):

# devuelve verdadero si la suma se vuelve 0 (se encuentra una subsecuencia)
if k == 0:
    return True

# caso base: no quedan elementos o la suma se vuelve negativa
if n < 0 or k < 0:
    return False

# construye una llave única a partir de elementos dinámicos de la entrada
key = (n, k)

# si el subproblema se ve por primera vez, resuélvelo y
# almacenar su resultado en un diccionario
if key not in lookup:

    # Caso 1. Incluye el elemento actual 'A[n]' en la subsecuencia y llama recursivamente
    # por los otros elementos 'n-1' con el total disminuido en 'k-A[n]'
    include = subsetSum(A, n - 1, k - A[n], lookup)

    # Caso 2. Excluye el elemento actual 'A[n]' de la subsecuencia y llama recursivamente por
    # los otros elementos 'n-1'
    exclude = subsetSum(A, n - 1, k, lookup)

    # asigna verdadero si obtenemos una subsecuencia incluyendo o excluyendo el elemento actual
    lookup[key] = include or exclude

# devuelve la solución al subproblema actual
return lookup[key]

if name == ”main‘:

# Entrada: un conjunto de elementos y una suma
A = [7, 3, 2, 5, 8]
k = 14

# crear un diccionario para almacenar soluciones a subproblemas
lookup = {}

if subsetSum(A, len(A) - 1, k, lookup):
    print('Existe una subsecuencia con la suma dada')
else:
    print('No existe una subsecuencia con la suma dada')

Se dice que la complejidad de este algoritmo es O (n * sum), pero no puedo entender cómo o por qué;
¿alguien puede ayudarme? Puede ser una explicación detallada o una relación de recurrencia, cualquier cosa está bien

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La complejidad temporal del algoritmo de suma de subconjuntos es O(n * sum), donde n es el número de elementos en el arreglo de entrada y sum es la suma objetivo que estamos tratando de alcanzar. Esta complejidad temporal se deriva del hecho de que el algoritmo resuelve todos los subproblemas posibles que se pueden construir a partir del arreglo de entrada.

    Para comprender cómo es O(n * sum), consideremos los dos casos principales en el algoritmo:

    1. Si la suma objetivo k es cero, entonces la función devuelve Veradero de inmediato. Esto se debe a que siempre existe un subconjunto vacío (con suma = 0).
    2. Si la suma objetivo k no es cero, entonces consideramos los dos casos base:
      a. Si n es negativo (es decir, hemos agotado todos los elementos en el arreglo de entrada), entonces devolvemos Falso.
      b. Si la suma objetivo se vuelve negativa (es decir, nos hemos pasado de la suma objetivo), entonces devolvemos Falso.

    Ahora necesitamos considerar los casos recursivos. El algoritmo hace lo siguiente:

    1. Calcula una clave única (n, k) de los elementos dinámicos de entrada.
    2. Si la clave no está en el diccionario de búsqueda, luego resolvemos el subproblema y almacenamos el resultado en el diccionario.
    3. Luego devolvemos la solución al subproblema.

    Para cada subproblema, tenemos dos opciones:

    1. Incluir el elemento actual A[n] en el subconjunto y recurrir para los elementos restantes con una suma total disminuida k – A[n].
    2. Excluir el elemento actual A[n] del subconjunto y recurrir para los elementos restantes.

    Si consideramos todos los subconjuntos posibles del arreglo de entrada, entonces podemos construir 2^n subproblemas (ya que cada elemento en el arreglo de entrada puede ser incluido o excluido del subconjunto). Sin embargo, a medida que resolvemos cada subproblema, estamos almacenando el resultado en el diccionario de búsqueda. Esto significa que podemos evitar resolver el mismo subproblema varias veces. En otras palabras, si encontramos un subproblema que hemos visto antes (es decir, la clave existe en el diccionario de búsqueda), entonces podemos devolver la solución de inmediato.

    Por lo tanto, dado que el algoritmo resuelve todos los subproblemas posibles que se pueden construir a partir del arreglo de entrada, y cada subproblema se puede resolver con tiempo O(1), la complejidad temporal es O(n * sum).

    En resumen, la complejidad temporal del algoritmo de suma de subconjuntos es O(n * sum) porque construye todos los subproblemas posibles que se pueden construir a partir del arreglo de entrada, y cada subproblema se puede resolver con tiempo constante.

Comments are closed.