Menemukan ukuran subset terkecil dengan GCD = 1

10

Ini adalah masalah dari sesi latihan Kontes Pemrograman Collegiate Polandia 2012 . Meskipun saya dapat menemukan solusi untuk kontes utama, saya sepertinya tidak dapat menemukan solusi untuk masalah ini di mana saja.

Masalahnya adalah: Diberikan satu set N bilangan bulat positif yang berbeda tidak lebih besar dari 109 , temukan ukuran m dari subset terkecil yang tidak memiliki pembagi umum selain 1. N paling banyak 500, dan sebuah solusi dapat diasumsikan ada.

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 , sebuah kontradiksi.

Namun, bahkan dengan ini, kekuatan kasar langsung masih terlalu lambat. Apakah ada yang punya ide lain?

Wakaka
sumber
tidak bisa ? g2=2
vonbrand
g 1g2>g12 . tidak boleh 1, karena 9-subset tidak dapat memiliki gcd dari 1.g1
Wakaka

Jawaban:

1

Masalah ini setara dengan yang berikut ini, dan sepele untuk membangun reduksi dua arah.

Diberikan daftar vektor bit, temukan jumlah minimumnya sedemikian rupa sehingga andsemuanya menghasilkan vektor bit. ( )0()

Kemudian kami tampilkan set cover reduced ke . Dengan menetapkan sampul, maksud saya diberi daftar set , temukan jumlah set minimum yang mencakup penyatuan mereka.S 1 , , S k()S1,...,Sk

Kami memerintahkan elemen dalam set menjadi . Misalkan , di mana jika , 0 sebaliknya. Perhatikan bahwa fungsi ini adalah penambangan sehingga memiliki kebalikannya. f ( S ) = ( 1 - χ sebuah 1 ( S ) , ... , 1 - χ sebuah n ( S ) ) χ x ( S ) = 1 x SSebuah1,...,Sebuahnf(S)=(1-χSebuah1(S),...,1-χSebuahn(S))χx(S)=1xS

Sekarang, jika kita memecahkan pada , dan solusinya adalah , lalu adalah solusi untuk mengatur penutup.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)}{f-1(Sb1),...,f-1(Sbm)}

Jadi saya akan berpikir masalah ini menguji kemampuan seseorang untuk memangkas ruang pencarian.

Chao Xu
sumber
Bagaimana Anda menemukan penutup simpul minimum?
Yuval Filmus
oh nvm solusi ini, set penutupnya saja.
Chao Xu
1
Itu benar, tapi saya pikir mungkin kita dapat mengeksploitasi properti tertentu dari kasus khusus ini. Misalnya, dalam hal ini set semuanya sangat besar, dengan ukuran tidak kurang dari . Bahkan, jika angka-angka di set semua kecil, ukurannya akan lebih besar. Selanjutnya, kita pasti dapat menemukan 9 set yang mencakup semuanya. Lagi pula, bagaimana Anda menyarankan saya memangkas ruang pencarian? n-9
Wakaka
Saya tidak melihat bagaimana masalah (*) setara dengan yang diberikan dalam pertanyaan. Untuk satu hal, masalah yang diberikan dalam pertanyaan memiliki janji bahwa semua bilangan bulat akan menjadi , yang sesuai dengan jaminan tentang bobot vektor bit yang tidak muncul dalam masalah (*). 109
DW
1

Dimungkinkan untuk menyelesaikan ini secara relatif efisien dengan menghitung semua gcd berpasangan, menghapus duplikat, dan kemudian berulang. Ini tindakan menghapus duplikat sebelum Anda berulang yang membuatnya efisien.

Saya akan menjelaskan algoritma lebih terinci di bawah ini, tetapi pertama-tama, ini membantu untuk mendefinisikan operator biner . Jika adalah himpunan bilangan bulat positif, tentukanS , TS,T

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

Perhatikan bahwadan (dalam masalah Anda); biasanya, akan lebih kecil daripada yang disarankan, yang membantu membuat algoritma menjadi efisien. Perhatikan juga bahwa kita dapat menghitung denganoperasi gcd dengan penghitungan sederhana.| S T | 10 9 S T S T | S | × | T ||ST||S|×|T||ST|109STST|S|×|T|

Dengan notasi itu, berikut adalah algoritma. Biarkan menjadi set input angka. Hitung , lalu , lalu , dan seterusnya. Temukan terkecil sehingga tetapi . Maka Anda tahu bahwa ukuran subset terkecil seperti itu adalah . Jika Anda juga ingin menampilkan contoh konkret dari subset seperti itu, dengan mempertahankan back-pointer Anda dapat dengan mudah merekonstruksi set tersebut.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

Ini akan relatif efisien, karena tidak ada set perantara tumbuh dalam ukuran di atas (pada kenyataannya, ukurannya mungkin akan jauh lebih kecil dari itu), dan waktu berjalan membutuhkan sekitar operasi gcd. 500 × ( | S 1 | + | S 2 | + )109500×(|S1|+|S2|+)

Berikut ini adalah pengoptimalan yang mungkin meningkatkan efisiensi lebih jauh. Pada dasarnya, Anda dapat menggunakan penggandaan iterated untuk menemukan terkecil sehingga . Khususnya, untuk setiap elemen , kami melacak subset terkecil dari yang gcdnya dan yang ukurannya . (Ketika Anda menghapus duplikat, Anda menyelesaikan ikatan yang mendukung subset yang lebih kecil.) Sekarang, daripada menghitung urutan sembilan set , kami malah menghitung urutan lima set , dengan menghitung , lalu , lalu1 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 , lalu . Saat Anda mulai, cari pertama sedemikian sehingga . Setelah Anda menemukan sedemikian sehingga , Anda dapat segera berhenti: Anda dapat menemukan subset terkecil yang gcdnya dengan melihat subset yang terkait dengan . Jadi, Anda dapat berhenti segera setelah mencapai set sedemikian rupa sehingga , yang memungkinkan Anda untuk berhenti lebih awal jika Anda menemukan subset yang lebih kecil.S9=S1×S8k[1,2,4,8,9]1Skk1Sk11Sk1Sk

Ini harus efisien waktu dan efisien ruang. Untuk menghemat ruang, untuk setiap elemen , Anda tidak perlu menyimpan seluruh set: cukup untuk menyimpan dua backpointers (jadi dua elemen yang Anda ambil gcd dari, untuk mendapatkan ) dan secara opsional ukuran subset yang sesuai.S i , S j xxSkSi,Sjx

Pada prinsipnya, Anda dapat mengganti urutan dengan rantai tambahan lainnya . Saya tidak tahu apakah beberapa rantai tambahan lain akan lebih baik. Pilihan optimal mungkin tergantung pada distribusi jawaban yang benar dan ukuran yang diharapkan dari set , yang tidak jelas bagi saya, tetapi mungkin dapat diturunkan secara empiris melalui eksperimen.S k[1,2,4,8,9]Sk

Penghargaan: Terima kasih saya kepada KWillets untuk gagasan menyimpan subset angka bersama dengan setiap elemen , yang memungkinkan penghentian lebih awal.Ssaya

DW
sumber
Saya percaya pencarian biner tidak perlu; Anda dapat menyimpan jumlah elemen dengan setiap gcd, dan mengaturnya ke jumlah pasangan minimum selama setiap penggandaan.
KWillets
Poin bagus, @KWillets! Terima kasih atas ide indah itu! Saya memasukkannya ke dalam jawaban saya.
DW
0

Mungkin lebih cepat melihat ini dengan cara lain ... prime terbesar kurang dari adalah 31607, untuk jumlah total 3401 bilangan prima antara 2 dan 31607, bukan jumlah yang sangat besar. Tuliskan masing-masing angka yang Anda berikan dengan faktor penuh hingga bilangan prima hingga 31607: Di sini adalah 1 atau prime yang besar. Kemudian satu set 's adalah relatif prima jika sesuai vektor bebas linear (dan mereka s berbeda atau keduanya 1), dan Anda sedang mencari rank dari matriks. ai=p n i 1 1 p n i 2 2PiPiainijP109

Sebuahsaya=hal1nsaya1hal2nsaya2...Psaya
PsayaSebuahsayansayajP
vonbrand
sumber
Apa hubungannya dengan independensi linear? Vektor dan adalah bebas linear, tetapi GCD adalah sementara kami inginkan . ( 1 , 0 ) ( 1 , 0 ) ( 0 , 0 )(1,1)(1,0)(1,0)(0,0)
Yuval Filmus
1
Independensi linear tampaknya tidak berfungsi, tetapi kita dapat menggunakan dekomposisi utama ini dengan cara yang berbeda. Untuk setiap prime (di antara dan paling banyak ), tentukan himpunan sebagai kumpulan semua angka (di antara himpunan yang diberikan) yang tidak memiliki sebagai faktor. Masalahnya sekarang adalah menemukan subset terkecil dari angka sedemikian rupa sehingga untuk setiap , . Ini adalah masalah hitting set, setara dengan set cover. Ini -complete, tetapi mungkin ada beberapa implementasi yang cukup cepat untuk ukuran ini. hal3401 halsaya500 PsayaSEBUAHhalhalBSEBUAHhal|SEBUAHhalB|1NP
polkjh
Bisakah Anda mengarahkan saya ke beberapa implementasi yang bisa bekerja? Sejauh ini, saya hanya dapat menemukan algoritma aproksimasi. Terima kasih!
Wakaka
Makalah survei ini membahas solusi perkiraan dan tepat. Dan ketika membalas komentar, tambahkan @ nama-orang ke komentar. Ini akan mengirimkan pemberitahuan kepada orang itu. Kalau tidak, mereka mungkin tidak akan pernah tahu tentang komentar Anda.
polkjh
-1

Jika Anda dapat menemukan subset dengan gcd (S) = 1, maka saya selalu dapat menghapus elemen redundan dari subset sampai hanya 2 elemen yang tersisa, yang memiliki gcd (S) = 1. Oleh karena itu, saya dapat mengklaim bahwa salah satu yang terkecil subset akan berisi 2 elemen atau tidak akan ada.

Sekarang, kami menggunakan rekursi untuk menyelesaikan masalah ini. Mari kita membagi array angka menjadi 2 bagian, satu dengan elemen n-1 dan satu dengan elemen 1 (elemen terakhir). Entah 2 angka akan berada di elemen n-1 pertama atau satu elemen akan ada di sana dari bagian 1 dipasangkan dengan elemen terakhir. Karenanya, kami dapat menyelesaikan masalah ini di

T (n) = T (n-1) + O (n) waktu. yang berarti T (n) = O (n ^ 2).

Pratik
sumber
4
. Elemen mana yang bisa Anda hapus? gcd(6,10,15)=1
Rick Decker