martes, 17 de diciembre de 2019

LISTA DE PROBLEMAS


La coincidencia numérica tridimensional es un problema de decisión de NP completo . Está dado por tres conjuntos múltiples de enteros  y , cada uno con  elementos y un límite El objetivo es seleccionar un subconjunto de  tal que cada entero en  y  ocurre exactamente una vez y eso por cada triple  en el subconjunto sostiene. Este problema está etiquetado como [SP16] en. 


Ejemplo editar ]

Tomar  y Esta instancia tiene una solución, a saberTenga en cuenta que cada triple suma aEl conjunto no es una solución por varias razones: no se utilizan todos los números (un  falta), se usa un número con demasiada frecuencia (el ) y no todas las sumas triples a  (ya que Sin embargo, hay al menos una solución a este problema, que es la propiedad que nos interesa con los problemas de decisión. Si tomáramos por lo mismo  y , este problema no tendría solución (todos los números suman , que no es igual a  en este caso).

Problemas relacionados editar ]

Cada instancia del problema numérico de coincidencia tridimensional es una instancia tanto del problema de 3 particiones como del problema de coincidencia tridimensional.

Prueba de integridad de NP editar ]


La integridad de NP del problema de 3 particiones es declarada por Garey y Johnson en "Computers and Intractability; A Guide to the Theory of NP-Completeness", que hace referencia a este problema con el código [SP16]. [1] Se realiza mediante una reducción del emparejamiento tridimensional a través de 4 particiones. Para demostrar la completitud NP del emparejamiento numérico tridimensional, la prueba es similar, pero se debe usar una reducción del emparejamiento tridimensional mediante el problema del emparejamiento numérico 4-dimensional.










En teoría de números y ciencias de la computación , el problema de partición , o partición de números , [1] es la tarea de decidir si un conjunto múltiple S dado de enteros positivos se puede dividir en dos subconjuntos 1 y 2 de modo que la suma de los números en 1 es igual a la suma de los números en 2 . Aunque el problema de la partición es NP-completo , hay una programación dinámica de tiempo pseudo-polinomial solución, y hay heurísticas que resuelven el problema en muchos casos, de manera óptima o aproximadamente. Por esta razón, se le ha llamado "el problema NP-hard más fácil". [2]
Existe una versión de optimización del problema de partición, que consiste en dividir el multiset S en dos subconjuntos 1 , 2 de modo que la diferencia entre la suma de elementos en 1 y la suma de elementos en 2 se minimice. La versión de optimización es NP-hard , pero puede resolverse eficientemente en la práctica.

Ejemplos editar ]

Dado S = {3,1,1,2,2,1}, una solución válida para el problema de partición son los dos conjuntos 1 = {1,1,1,2} y 2 = {2,3}. Ambos conjuntos suman 5, y particionan S . Tenga en cuenta que esta solución no es única. 1 = {3,1,1} y 2 = {2,2,1} es otra solución.
No todos los conjuntos múltiples de enteros positivos tienen una partición en dos subconjuntos con la misma suma. Un ejemplo de tal conjunto es S = {2,5}.

Algoritmo de tiempo pseudo-polinomial editar ]

El problema puede resolverse mediante programación dinámica cuando el tamaño del conjunto y el tamaño de la suma de los enteros en el conjunto no son demasiado grandes para que los requisitos de almacenamiento no sean factibles.
Supongamos que la entrada al algoritmo es un conjunto múltiple  de cardinalidad :
S = { 1 , ..., N }
Deje que K sea la suma de todos los elementos en S . Esto es: K = 1 + ... + N . Construiremos un algoritmo que determine si hay un subconjunto de S que sume aSi hay un subconjunto, entonces:
si K es par, el resto de S también suma
si K es impar, entonces el resto de S suma aEsta es la mejor solución posible.

Relación de recurrencia editar ]

Deseamos determinar si hay un subconjunto de S que sume aDejar:
p ( i , j ) sea verdadero si un subconjunto de { 1 , ..., j } suma i y falso en caso contrario.
Entonces p (N ) es Verdadero si y solo si hay un subconjunto de S que sumaEl objetivo de nuestro algoritmo será calcular p (N ). En ayuda de esto, tenemos la siguiente relación de recurrencia :
p ( i , j ) es True si p ( i , j - 1) es True o si p ( i - j , j - 1) es True
p ( i , j ) es falso de lo contrario
El razonamiento para esto es el siguiente: hay un subconjunto de S que suma a i usando números
1 , ..., j
si y solo si alguno de los siguientes es verdadero:
Hay un subconjunto de { 1 , ..., j −1 } que suma i ;
hay un subconjunto de { 1 , ..., j −1 } que suma i - j , ya que j + suma de ese subconjunto = i .

El algoritmo pseudo-polinomial editar ]

El algoritmo consiste en construir una tabla de tamaño  por que contiene los valores de la recurrencia. Recuerda eso es la suma de todos  elementos en Una vez que toda la tabla está llena, regresamosA continuación se muestra una representación de la tabla.Hay una flecha azul de un bloque a otro si el valor del bloque objetivo puede depender del valor del bloque fuente. Esta dependencia es una propiedad de la relación de recurrencia.
Dependencias de la entrada de la tabla ( i , j )
función find_partition ( S ) es 
    de entrada: Una lista de los números enteros S .
    salida: Verdadero si S puede dividirse en dos subconjuntos que tienen la misma suma.

    n ← | S |
    K ← suma ( S )
     P ← tabla booleana vacía de tamaño (+ 1) por (n + 1)

    inicializar fila superior ( P (0, x )) de P en True
     initialize más a la izquierda en columna ( P ( x , 0)) de P , a excepción de P (0, 0) en False

    para  i  de 1 a 
        para  j  de 1 a n
             si ( i - S [ j ])> = 0 entonces 
                P ( i , j ) ← P ( i , j -1) o  P ( i - S [ j ], j -1)
             más 
                P ( i , j ) ← P ( i , j -1)

   devolver  P (, n )

Ejemplo editar ]

A continuación se muestra la tabla de P para el ejemplo de conjunto utilizado más arriba S = {3, 1, 1, 2, 2, 1}:
Resultado de la ejecución del algoritmo de ejemplo en la tabla P

Análisis editar ]

Este algoritmo se ejecuta en el tiempo O ( KN ) , donde N es el número de elementos en el conjunto de entrada y K es la suma de elementos en el conjunto de entrada.
El algoritmo se puede extender a la k -WAY problema de múltiples particiones, pero luego toma O ( n ( k - 1) k - 1 ) de memoria donde m es el número más grande en la entrada, por lo que es poco práctico incluso para k = 3 a menos que las entradas sean números muy pequeños. [3]

Caso especial del problema de suma de subconjuntos editar ]

El problema de partición puede verse como un caso especial del problema de suma de subconjuntos y la solución de programación dinámica de tiempo pseudopolinomial dada anteriormente generaliza a una solución para el problema de suma de subconjuntos .

Aproximación del algoritmo de aproximación editar ]

Existen varios algoritmos heurísticos para producir aproximaciones al problema de optimización de la partición. Estos pueden extenderse a algoritmos exactos de espacio lineal . [3]

El algoritmo codicioso editar ]

Un enfoque del problema, que imita la forma en que los niños eligen equipos para un juego, es el algoritmo codicioso , que itera a través de los números en orden descendente, asignando a cada uno de ellos el subconjunto que tenga la suma más pequeña. Este enfoque tiene un tiempo de ejecución de O ( n log n ) . Esta heurística funciona bien en la práctica cuando los números en el conjunto son aproximadamente del mismo tamaño que su cardinalidad o menos, pero no se garantiza que produzca la mejor partición posible. Por ejemplo, dado el conjunto S = {4, 5, 6, 7, 8} como entrada, este algoritmo codicioso dividiría S en los subconjuntos {4, 5, 8} y {6, 7}; sin embargo, S tiene una partición exactamente equilibrada en subconjuntos {7, 8} y {4, 5, 6}.
Este enfoque codicioso es conocido por dar un 7 / 6 - aproximación a la solución óptima de la versión optimización; es decir, si el algoritmo codicioso salidas dos conjuntos A y B , a continuación, max (s A, ΣB) ≤ 7/6 OPT , donde OPT es el tamaño del conjunto más grande en la mejor partición posible. [4] A continuación se ofrece un ejemplo (escrito en Python ) para el algoritmo codicioso.
def  find_partition ( números ): 
    "" "Separe los números dados en dos series de suma igual. 
    Args: 
        números: una colección de números, por ejemplo, una lista de enteros. 
    Devuelve: 
        dos listas de números. 
    " "" 
    A  =  [] 
    B  =  [] 
    sum_A  =  0 
    sum_B  =  0 
    para  n  en  ordenados ( int_list ,  revertir = Verdadero ): 
        si  sum_A  <  sum_B : 
           a . agregar (n ) 
           sum_A  =  sum_A  +  n 
        otra cosa : 
           B . agregar ( n ) 
           sum_B  =  sum_B  +  n 
    return  ( A ,  B )
Este algoritmo puede extenderse al caso de k > 2 conjuntos: para tomar los k elementos más grandes, y para cada partición de ellos, extiende la partición agregando los elementos restantes sucesivamente a cualquier conjunto que sea más pequeño. (La versión simple anterior corresponde a k = 2 ). Esta versión se ejecuta en tiempo O (2 k 2 ) y es conocido para dar un 4/3 - 1/k aproximación. [4] Entonces, tenemos un esquema de aproximación de tiempo polinómico (PTAS) para el problema de partición de números, aunque esto no es unesquema de aproximación de tiempo completamente polinomial (el tiempo de ejecución es exponencial en la garantía de aproximación deseada). Sin embargo, hay variaciones de esta idea que son esquemas de aproximación de tiempo completamente polinomial para el problema de suma de subconjuntos y, por lo tanto, también para el problema de partición. [5] [6]

Algoritmo de diferenciación editar ]

Otra heurística es el método de diferenciación más grande (LDM), [7] también llamado Karmarkar - Karp heuristic [3] después del par de científicos que lo publicó en 1982. [8] LDM opera en dos fases. La primera fase del algoritmo toma los dos números más grandes de la entrada y los reemplaza por su diferencia; esto se repite hasta que solo quede un número. El reemplazo representa la decisión de colocar los dos números en conjuntos diferentes, sin decidir de inmediato cuál está en qué conjunto. Al final de la fase uno, el único número restante es la diferencia de las dos sumas de subconjuntos. La segunda fase reconstruye la solución real. [2]
La heurística de diferenciación funciona mejor que la codiciosa, pero sigue siendo mala para los casos en que los números son exponenciales en el tamaño del conjunto. [2]
El siguiente código Java implementa la primera fase de Karmarkar – Karp. Utiliza un montón para encontrar eficientemente el par de números restantes más grandes.
int  karmarkarKarpPartition ( int []  baseArr )  { 	
    // crea el montón máximo	 
    PriorityQueue < Integer >  heap  =  new  PriorityQueue < Integer > ( baseArr . length ,  REVERSE_INT_CMP );

    for  ( int  value  :  baseArr )  { 		
        heap . agregar ( valor ); 	
    }

    while ( heap . size ()  >  1 )  { 
        int  val1  =  heap . encuesta (); 	
        int  val2  =  montón . sondear (); 	
        montón . agregar ( val1  -  val2 ); 
    }

    volver  montón . encuesta (); 
}

Otros enfoques editar ]

También hay algoritmos en cualquier momento , basados ​​en la heurística de diferenciación, que primero encuentran la solución devuelta por la heurística de diferenciación, luego encuentran soluciones progresivamente mejores según lo permita el tiempo (posiblemente requiera un tiempo exponencial para alcanzar la óptima, en el peor de los casos). [9]

Instancias difíciles editar ]

Los conjuntos con solo una o sin particiones tienden a ser más difíciles (o más caros) de resolver en comparación con sus tamaños de entrada. Cuando los valores son pequeños en comparación con el tamaño del conjunto, las particiones perfectas son más probables. Se sabe que el problema sufre una " transición de fase "; siendo probable que para algunos conjuntos y es poco probable para los demás. Si m es el número de bits necesarios para expresar cualquier número en el conjunto yn es el tamaño del conjunto, entonces tiende a tener muchas soluciones y tiende a tener pocas o ninguna solución. A medida que nym aumentan, la probabilidad de una partición perfecta va a 1 o 0 respectivamente. Originalmente, esto fue argumentado en base a la evidencia empírica de Gent y Walsh, [10] luego utilizando métodos de física estadística de Mertens, [11] y luego probado por Borgs , Chayes y Pittel . [12]

Variantes y generalizaciones editar ]

La restricción de requerir que la partición tenga el mismo tamaño, o que todos los enteros de entrada sean distintos, también es NP-hard. cita requerida ]
Hay un problema llamado problema de 3 particiones que consiste en particionar el conjunto S en | S | / 3 se triplica cada uno con la misma suma. Este problema es bastante diferente al problema de la partición y no tiene un algoritmo de tiempo pseudo-polinomial a menos que P = NP . [13]
El problema de partición multidireccional generaliza la versión de optimización del problema de partición. Aquí, el objetivo es dividir un conjunto o conjunto múltiple de n enteros en un número dado k de subconjuntos, minimizando la diferencia entre las sumas de subconjunto más pequeñas y más grandes. [3]

Versión probabilística editar ]

Un problema relacionado, algo similar a la paradoja del cumpleaños , es el de determinar el tamaño del conjunto de entrada para que tengamos una probabilidad de la mitad de que hay una solución, bajo el supuesto de que cada elemento del conjunto se selecciona aleatoriamente con uniforme distribución entre 1 y algún valor dado.
La solución a este problema puede ser contra intuitiva, como la paradoja del cumpleaños.

No hay comentarios:

Publicar un comentario