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.m9S|S|=10S1<g1<g2<...<g10gcd(gi,gj)=1ijSg2g3...g10g2g3...g103×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>g12 . 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)=1xS

Ora, se risolviamo su e le soluzioni sono , allora è la soluzione per impostare la copertura.()f(S1),,f(Sk){f(Sb1),,f(Sbm)}{f1(Sb1),,f1(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? n9
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 , TS,T

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

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 ||ST||S|×|T||ST|109STST|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=S1S1S3=S1S2S4=S1S3k1Sk1Sk1k

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 , quindik1SkxSiS1xiS1,S2,S3,S4,,S9S1,S2,S4,S8,S9S2=S1S1S4=S2S2S8=S4S4 , 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]1Skk1Sk11Sk1Sk

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.xSkSi,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=p1ni1p2ni2Pi
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 pB | 1 N Pp3401 pi500 PiAppBAp|ApB|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.