Encontrar el tamaño del subconjunto más pequeño con GCD = 1

10

Este es un problema de la sesión de práctica del Concurso de Programación Universitaria de Polonia 2012 . Aunque pude encontrar las soluciones para el concurso principal, parece que no puedo encontrar la solución para este problema en ninguna parte.

El problema es: dado un conjunto de N enteros positivos distintos no mayores que 109 , encuentre el tamaño m del subconjunto más pequeño que no tenga un divisor común que no sea 1. N es como máximo 500, y se puede suponer que existe una solución.

m9S|S|=10S1<g1<g2<...<g10i j S g 2 g 3 . . . g 10 g 2 g 3 . . . g 103 × 5 × 7 × 11 × . . . × 29 = 3234846615 > 10 9gcd(gi,gj)=1ijSg2g3...g10g2g3...g103×5×7×11×...×29=3234846615>109 , una contradicción.

Sin embargo, incluso con esto, una fuerza bruta directa es demasiado lenta. ¿Alguien tiene alguna otra idea?

Wakaka
fuente
¿Por qué no puede ? g2=2
vonbrand
g 1g2>g12 . no puede ser 1, ya que los 9 subconjuntos no pueden tener un mcd de 1.g1
Wakaka

Respuestas:

1

Este problema es equivalente al siguiente, y es trivial construir reducción en ambos sentidos.

Dada una lista de vectores de bits, encuentre el número mínimo de ellos de modo que andtodos den como resultado el vector de bits. ( )0()

Luego mostramos que la cobertura del conjunto se reduce a . Por cubierta de conjunto, quiero decir, dada una lista de conjuntos , encuentre el número mínimo de conjuntos que cubre su unión.S 1 , ... , S k()S1,,Sk

Ordenamos que los elementos en los conjuntos sean . Sea , donde si , 0 en caso contrario. Tenga en cuenta que esta función es una biyección, por lo que tiene un inverso. f ( S ) = ( 1 - χ a 1 ( S ) , , 1 - χ a n ( S ) ) χ x ( S ) = 1 x Sa1,,anf(S)=(1χa1(S),,1χan(S))χx(S)=1xS

Ahora, si resolvemos en , y las soluciones son , entonces es la solución para configurar la cobertura.f ( S 1 ) , , f ( S k ) { f ( S b 1 ) , , f ( S b m ) } { f - 1 ( S b 1 ) , , f - 1 ( S b m ) }()f(S1),,f(Sk){f(Sb1),,f(Sbm)}{f1(Sb1),,f1(Sbm)}

Por lo tanto, creo que este problema es probar la capacidad de uno para podar el espacio de búsqueda.

Chao Xu
fuente
¿Cómo encuentras la cobertura mínima de vértice?
Yuval Filmus
oh nvm esta solución, se establece en su lugar.
Chao Xu
1
Eso es cierto, pero creo que quizás podamos explotar ciertas propiedades de este caso especial. Por ejemplo, en este caso, los conjuntos son todos muy grandes, con tamaños no inferiores a . De hecho, si los números en los conjuntos son todos pequeños, sus tamaños serían aún mayores. Además, definitivamente podemos encontrar 9 juegos que cubren todo. De todos modos, ¿cómo sugieres que pode el espacio de búsqueda? n9
Wakaka
No veo cómo el problema (*) es equivalente al que se da en la pregunta. Por un lado, el problema dado en la pregunta promete que todos los enteros serán , lo que corresponde a una garantía sobre los pesos de los vectores de bits que no aparece en el problema (*). 109
DW
1

Es posible resolver esto de manera relativamente eficiente calculando todos los gcd de pares, eliminando duplicados y luego recurriendo. Es el acto de eliminar duplicados antes de recurrir lo que lo hace eficiente.

Explicaré el algoritmo con más detalle a continuación, pero primero, ayuda a definir un operador binario . Si son conjuntos de enteros positivos, definaS , TS,T

ST={gcd(s,t):sS,tT}.

Tenga en cuenta quey (en su problema); típicamente, será aún más pequeño de lo que sugiere cualquiera de esos límites, lo que ayuda a que el algoritmo sea eficiente. También tenga en cuenta que podemos calcular conoperaciones de gcd por enumeración simple.El | S T | 10 9 S T S T | S | × | T ||ST||S|×|T||ST|109STST|S|×|T|

Con esa notación, aquí está el algoritmo. Deje que sea ​​el conjunto de números de entrada. Calcule , luego , luego , y así sucesivamente. Encuentre la más pequeña tal que pero . Entonces sabes que el tamaño del subconjunto más pequeño es . Si también desea generar un ejemplo concreto de dicho subconjunto, manteniendo los punteros hacia atrás puede reconstruir fácilmente dicho conjunto.S 2 = S 1S 1 S 3 = S 1S 2 S 4 = S 1S 3 k 1 S k 1 S k - 1 kS1S2=S1S1S3=S1S2S4=S1S3k1Sk1Sk1k

Esto será relativamente eficiente, ya que ninguno de los conjuntos intermedios crece en tamaño por encima de (de hecho, su tamaño probablemente será mucho más pequeño que eso), y el tiempo de ejecución requiere aproximadamente operaciones gcd. 500 × ( | S 1 | + | S 2 | + )109500×(|S1|+|S2|+)

Aquí hay una optimización que podría mejorar aún más la eficiencia. Básicamente, puede usar la duplicación iterada para encontrar la más pequeña de manera que . En particular, para cada elemento , hacemos un seguimiento del subconjunto más pequeño de cuyo mcd es y cuyo tamaño es . (Cuando elimina duplicados, resuelve los vínculos a favor del subconjunto que es más pequeño). Ahora, en lugar de calcular la secuencia de nueve conjuntos , calculamos la secuencia de cinco conjuntos , calculando , luego , luego1 S k x S i S 1 x i S 1 , S 2 , S 3 , S 4 , , S 9 S 1 , S 2 , S 4 , S 8 , S 9 S 2 = S 1S 1 S 4 = S 2S 2 Sk1SkxSiS1xiS1,S2,S3,S4,,S9S1,S2,S4,S8,S9S2=S1S1S4=S2S2S 9 = S 1 × S 8 k [ 1 , 2 , 4 , 8 , 9 ] 1 S k k 1 S k 1 1 S k 1 S kS8=S4S4 , luego . A medida que avanza, encuentre la primera tal que . Una vez que haya encontrado tal que , puede detenerse de inmediato: puede encontrar el subconjunto más pequeño cuyo mcd es mirando el subconjunto asociado con . Por lo tanto, puede detenerse tan pronto como llegue a un conjunto tal que , lo que le permite detenerse temprano si encuentra un subconjunto más pequeño.S9=S1×S8k[1,2,4,8,9]1Skk1Sk11Sk1Sk

Esto debería ser eficiente en el tiempo y en el espacio. Para ahorrar espacio, para cada elemento , no necesita almacenar todo el conjunto: es suficiente para almacenar dos backpointers (por lo que los dos elementos de que tomó el mcd, para obtener ) y opcionalmente el tamaño del subconjunto correspondiente.S i , S j xxSkSi,Sjx

En principio, puede reemplazar la secuencia por cualquier otra cadena de adición . No sé si alguna otra cadena de adición será mejor. La elección óptima podría depender de la distribución de las respuestas correctas y los tamaños esperados de los conjuntos , lo cual no es claro para mí, pero probablemente puede derivarse empíricamente a través de la experimentación.S k[1,2,4,8,9]Sk

Créditos: Mi agradecimiento a KWillets por la idea de almacenar un subconjunto de números junto con cada elemento de , lo que permite parar antes.Si

DW
fuente
Creo que la búsqueda binaria no es necesaria; puede almacenar el recuento de elementos con cada mcd y establecerlo en la suma mínima de pares durante cada duplicación.
KWillets
Gran punto, @KWillets! Gracias por esa hermosa idea! Lo he incorporado a mi respuesta.
DW
0

Quizás es más rápido ver esto de otra manera ... el primo más grande menor que es 31607, para un recuento total de 3401 primos entre 2 y 31607, no un número muy grande. Escriba cada uno de los números que se le da con factores completos sobre los números primos hasta 31607: Aquí es 1 o un primo grande. Entonces, un conjunto de es relativamente primo si los vectores correspondientes son linealmente independientes (y sus s son diferentes o ambos 1), y está buscando el rango de una matriz. ai=p n i 1 1 p n i 2 2PiPiainijP109

ai=p1ni1p2ni2Pi
PiainijP
vonbrand
fuente
¿Cuál es la conexión con la independencia lineal? Los vectores y son linealmente independientes, pero el MCD es mientras que queremos . ( 1 , 0 ) ( 1 , 0 ) ( 0 , 0 )(1,1)(1,0)(1,0)(0,0)
Yuval Filmus
1
La independencia lineal no parece funcionar, pero podemos usar esta descomposición principal de una manera diferente. Para cada primo (entre 's y como máximo ' s), defina el conjunto como la colección de todos los números (entre el conjunto dado) que no tienen como factor. El problema ahora es encontrar un subconjunto más pequeño de números, de modo que para cada , . Este es el problema del conjunto de golpes, equivalente al problema del conjunto de cobertura. Esto es completo, pero puede haber algunas implementaciones lo suficientemente rápidas para este tamaño. 3401 p i 500 P i A p p B A p | A pB | 1 N Pp3401 pi500 PiAppBAp|ApB|1NP
polkjh
¿Podría dirigirme a algunas implementaciones que podrían funcionar? Hasta ahora, solo puedo encontrar algoritmos de aproximación. ¡Gracias!
Wakaka
Este estudio de encuesta analiza soluciones aproximadas y exactas. Y cuando responda a un comentario, agregue @ nombre de persona al comentario. Enviará una notificación a esa persona. De lo contrario, es posible que nunca sepan tu comentario.
polkjh
-1

Si puede encontrar un subconjunto con gcd (S) = 1, siempre puedo eliminar elementos redundantes del subconjunto hasta que solo queden 2 elementos, que tienen gcd (S) = 1. Por lo tanto, puedo afirmar que el más pequeño El subconjunto contendrá 2 elementos o no existirá.

Ahora, usamos la recursividad para resolver este problema. Dividamos la matriz de números en 2 partes, una con n-1 elementos y otra con 1 elemento (último elemento). O bien los 2 números estarán en los primeros n-1 elementos o un elemento estará allí desde la primera parte emparejado con el último elemento. Por lo tanto, podemos resolver este problema en

T (n) = T (n-1) + O (n) tiempo. lo que significa T (n) = O (n ^ 2).

Pratik
fuente
44
gcd(6,10,15)=1