Trovare la dimensione del sottoinsieme più piccolo con GCD = 1


10

Questo è un problema derivante dalla sessione di pratica del concorso collegiale di programmazione polacco 2012 . Anche se sono riuscito a trovare le soluzioni per il concorso principale, non riesco a trovare la soluzione per questo problema da nessuna parte.

Il problema è: dato un insieme di interi positivi distinti non superiori a , trova la dimensione del sottoinsieme più piccolo che non ha divisori comuni diversi da 1. è al massimo 500 e si può presumere che esista una soluzione .10 9 m NN109mN

Sono riuscito a mostrare che . Il mio ragionamento è: supponiamo che esista un sottoinsieme minimo di dimensione , con gcd = 1. Quindi tutti i 9 sottoinsiemi di devono avere gcd> 1. Esistono esattamente 10 tali sottoinsiemi e i loro gcd devono essere a coppie coprimi. Lascia che questi gcd siano , dove , per i \ neq j . Quindi il numero massimo in S è g_2g_3 ... g_ {10} . Ma g_2g_3 ... g_ {10} \ ge 3 \ times5 \ times7 \ times11 \ times ... \ times29 = 3234846615> 10 ^ 9 , una contraddizione.m≤9S|S|=10S1<g1<g2<...<g10gcd(gi,gj)=1i≠jSg2g3...g10g2g3...g10≥3×5×7×11×...×29=3234846615>109

Tuttavia, anche con questo, una forza bruta semplice è ancora troppo lenta. Qualcuno ha qualche altra idea?


Perché non g2=2 ?
— vonbrand

g2>g1≥2 . g1 non può essere 1, poiché 9 sottoinsiemi non possono avere un gcd di 1.
— Wakaka

Risposte:


1

Questo problema è equivalente al seguente ed è banale costruire la riduzione in entrambi i modi.

Dato un elenco di vettori di bit, trovare il numero minimo di essi in modo tale che andtutti risultino il vettore bit. 0(∗)

Quindi mostriamo che la copertina impostata si riduce a . Per set cover, intendo, dato un elenco di set , trova il numero minimo di set che copre la loro unione.(∗)S1,…,Sk

Ordiniamo che gli elementi negli insiemi siano . Sia , dove se , 0 altrimenti. Nota questa funzione è una biiezione quindi ha un inverso.a1,…,anf(S)=(1−χa1(S),…,1−χan(S))χx(S)=1x∈S

Ora, se risolviamo su e le soluzioni sono , allora è la soluzione per impostare la copertura.(∗)f(S1),…,f(Sk){f(Sb1),…,f(Sbm)}{f−1(Sb1),…,f−1(Sbm)}

Quindi penso che questo problema stia testando la capacità di potare lo spazio di ricerca.


Come si trova la copertura minima del vertice?
— Yuval Filmus

oh nvm questa soluzione, è invece coperta.
— Chao Xu

1
Questo è vero, ma sto pensando che forse possiamo sfruttare alcune proprietà di questo caso speciale. Ad esempio, in questo caso i set sono tutti molto grandi, con dimensioni non inferiori a . In effetti, se i numeri nei set sono tutti piccoli, le loro dimensioni sarebbero ancora più grandi. Inoltre, possiamo sicuramente trovare 9 set che coprono tutto. Comunque, come mi consigli di potare lo spazio di ricerca? n−9
— Wakaka,

Non vedo come il problema (*) sia equivalente a quello indicato nella domanda. Per prima cosa, il problema dato nella domanda ha la promessa che tutti i numeri interi saranno , il che corrisponde a una garanzia sui pesi dei vettori di bit che non appare nel problema (*). ≤109
— DW

1

È possibile risolverlo in modo relativamente efficiente calcolando tutti i gcd a coppie, rimuovendo i duplicati e quindi ricorrendo. È l'atto di rimuovere i duplicati prima di ricorrere che lo rende efficiente.

Spiegherò l'algoritmo in modo più dettagliato di seguito, ma prima aiuta a definire un operatore binario . Se sono insiemi di numeri interi positivi, definireS , T⊗S,T

S⊗T={gcd(s,t):s∈S,t∈T}.

Si noti chee (nel tuo problema); in genere, sarà anche più piccolo di quanto suggerisca uno di questi limiti, il che aiuta a rendere l'algoritmo efficiente. Inoltre, possiamo calcolare conoperazioni gcd per semplice enumerazione.| S ⊗ T | ≤ 10 9 S ⊗ T S ⊗ T | S | × | T ||S⊗T|≤|S|×|T||S⊗T|≤109S⊗TS⊗T|S|×|T|

Con questa notazione, ecco l'algoritmo. Lascia che sia l'insieme di numeri di input. Calcola , quindi , quindi e così via. Trova il più piccolo in modo tale che ma . Quindi sai che la dimensione del più piccolo sottoinsieme è . Se si desidera anche fornire un esempio concreto di tale sottoinsieme, mantenendo i puntatori posteriori è possibile ricostruire facilmente tale set.S1S2=S1⊗S1S3=S1⊗S2S4=S1⊗S3k1∈Sk1∉Sk−1k

Questo sarà relativamente efficiente, poiché nessuna delle serie intermedie cresce di dimensioni superiori a (in effetti, la loro dimensione sarà probabilmente molto più piccola di quella) e il tempo di esecuzione richiede circa operazioni gcd.109500×(|S1|+|S2|+⋯)

Ecco un'ottimizzazione che potrebbe migliorare ulteriormente l'efficienza. Fondamentalmente, puoi usare il raddoppio iterato per trovare il più piccolo tale che . In particolare, per ogni elemento , teniamo traccia del sottoinsieme più piccolo di cui gcd è e la cui dimensione è . (Quando rimuovete i duplicati, risolvete i legami a favore del sottoinsieme più piccolo.) Ora, anziché calcolare la sequenza di nove insiemi , invece la sequenza di cinque insiemi , calcolando , quindi , quindik1∈Skx∈SiS1x≤iS1,S2,S3,S4,…,S9S1,S2,S4,S8,S9S2=S1⊗S1S4=S2⊗S2S8=S4⊗S4 , quindi . Mentre , trova il primo tale che . Una volta trovato tale che , puoi immediatamente fermarti: puoi trovare il sottoinsieme più piccolo il cui gcd è guardando il sottoinsieme associato a . Quindi, puoi fermarti non appena raggiungi un set tale che , che ti consente di fermarti presto se trovi un sottoinsieme più piccolo.S9=S1×S8k∈[1,2,4,8,9]1∈Skk1∈Sk11Sk1∈Sk

Questo dovrebbe essere efficiente in termini di tempo e spazio. Per risparmiare spazio, per ogni elemento , non è necessario memorizzare l'intero set: è sufficiente memorizzare due backpointer (quindi i due elementi di cui hai preso il gcd, per ottenere ) e facoltativamente la dimensione del sottoinsieme corrispondente.x∈SkSi,Sjx

In linea di principio, è possibile sostituire la sequenza con qualsiasi altra catena di addizione . Non so se qualche altra catena di aggiunte sarà migliore. La scelta ottimale potrebbe dipendere dalla distribuzione delle risposte corrette e dalle dimensioni previste degli insiemi , il che non mi è chiaro, ma che probabilmente può essere derivato empiricamente attraverso la sperimentazione.[1,2,4,8,9]Sk

Riconoscimenti: i miei ringraziamenti a KWillets per l'idea di memorizzare un sottoinsieme di numeri insieme a ciascun elemento di , che consente di fermarsi presto.Si


Credo che la ricerca binaria non sia necessaria; puoi memorizzare il conteggio degli elementi con ogni gcd e impostarlo sulla somma minima delle coppie durante ogni raddoppio.
— KWillets,

Ottimo punto, @KWillets! Grazie per questa bellissima idea! L'ho incorporato nella mia risposta.
— DW

0

Forse è più veloce osservarlo in un altro modo ... il primo più grande meno di è 31607, per un conteggio totale di 3401 numeri primi tra 2 e 31607, non un numero molto grande. Scrivi ciascuno dei numeri che ti è stato dato completamente fattorizzato rispetto ai numeri primi fino a 31607: Qui è 1 o un numero primo grande. Quindi un insieme di è relativamente primo se i corrispondenti vettori sono linearmente indipendenti (e i loro sono diversi o entrambi 1) e stai cercando il rango di una matrice.109

ai=p1ni1p2ni2…Pi
PiainijP

Qual è la connessione all'indipendenza lineare? I vettori e sono linearmente indipendenti, ma il GCD è mentre vogliamo . (1,1)(1,0)(1,0)(0,0)
— Yuval Filmus

1
L'indipendenza lineare non sembra funzionare, ma possiamo usare questa scomposizione primaria in modo diverso. Per ogni primo (tra e al massimo ), definire l'insieme come l'insieme di tutti i numeri (tra l'insieme dato) che non hanno come fattore. Il problema ora è trovare un sottoinsieme di numeri più piccolo tale che per ogni , . Questo è il problema del set di colpi, equivalente al problema di set cover. Questo è completo, ma potrebbero esserci alcune implementazioni abbastanza veloci per questa dimensione. 3401 p i 500 P i A p p B A p | A p ∩ B | ≥ 1 N Pp3401 pi500 PiAppBAp|Ap∩B|≥1NP
— polkjh

Potresti indirizzarmi verso alcune implementazioni che potrebbero funzionare? Finora, posso trovare solo algoritmi di approssimazione. Grazie!
— Wakaka,

Questo documento di indagine esamina sia le soluzioni approssimative che esatte. E quando rispondi a un commento, aggiungi @ nome della persona al commento. Invierà una notifica a quella persona. Altrimenti potrebbero non sapere nemmeno del tuo commento.
— polkjh

-1

Se riesci a trovare un sottoinsieme con gcd (S) = 1, allora posso sempre rimuovere elementi ridondanti dal sottoinsieme fino a quando rimangono solo 2 elementi, che hanno gcd (S) = 1. Pertanto, posso affermare che il più piccolo il sottoinsieme conterrà 2 elementi o non esisterà.

Ora, utilizziamo la ricorsione per risolvere questo problema. Dividiamo la matrice di numeri in 2 parti, una con n-1 elementi e una con 1 elemento (ultimo elemento). O i 2 numeri saranno nei primi n-1 elementi o un elemento sarà lì dalla prima parte accoppiata con l'ultimo elemento. Pertanto, siamo in grado di risolvere questo problema in

T (n) = T (n-1) + O (n) tempo. che significa T (n) = O (n ^ 2).


4
gcd(6,10,15)=1 . Quale elemento puoi rimuovere?
— Rick Decker,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.