GCD = 1 ile en küçük altkümenin boyutunu bulma


10

Bu, Polonya Collegiate Programming Contest 2012'nin uygulama oturumundan bir sorundur . Ana yarışma için çözümler bulabilsem de, bu sorunun çözümünü hiçbir yerde bulamıyorum.

Sorun şudur: büyük olmayan bir N farklı pozitif tamsayı kümesi verildiğinde, 1'den başka ortak böleni olmayan en küçük altkümenin boyutunu bulun . en fazla 500'dür ve bir çözüm olduğu varsayılabilir. . m K109mN

Bunu göstermeyi başardım m9 . Mantık şöyledir: Varsayalım az değil alt vardır boyutu , gcd ile = 1. Sonra her 9-alt kümeleri olmalıdır gcd> 1. Orada tam olarak 10 tür alt kümeleri ve onların gcds olmalıdır BÜKÜMÜ aralarında asal. İ \ neq j için bu gcds , burada . Ardından maksimum sayı S olduğu g_2g_3 ... G_ {10} . Ancak g_2g_3 ... g_ {10} \ ge 3 \ times5 \ times7 \ times11 \ times ... \ times29 = 3234846615> 10 ^ 9 , bir çelişki.| S | = 10 S 1 < g 1 < g 2 < . . . < g 10 gcd ( g i , g j ) = 1 i j S g 2 g 3 . . . g 10 g 2 g 3 . . . g 103 × 5 × 7 ×S|S|=10S1<g1<g2<...<g10gcd(gi,gj)=1ijSg2g3...g10g2g3...g103×5×7×11×...×29=3234846615>109

Bununla birlikte, bununla birlikte, basit bir kaba kuvvet hala çok yavaştır. Başka fikri olan var mı?


Ne yapamam ? g2=2
vonbrand

g2>g12 . 1 olamaz, çünkü 9 alt kümenin gcd değeri 1 g1
olamaz

Yanıtlar:


1

Bu sorun aşağıdakine eşdeğerdir ve her iki şekilde de azaltma oluşturmak önemsizdir.

Bir bit vektörleri listesi verildiğinde, minimum 0 sayısını bulun, böylece andhepsi bit vektörüyle sonuçlanır . ( )0()

Sonra set kapağının azaldığını gösteriyoruz . Set kapağı ile, yani S 1 , , S k setlerinin bir listesi verildi , birleşimlerini kapsayan minimum set sayısını bulun.()S1,,Sk

Biz setlerle unsurlar olmaya sipariş . Let f ( S ) = ( 1 - χ bir 1 ( S ) , ... , 1 - χ bir n ( S ) ) , χ x ( S ) = 1 ise X S , 0 olacaktır. Bu işlevin bir bijeksiyon olduğunu ve tersine sahip olduğunu unutmayın.a1,,anf(S)=(1χa1(S),,1χan(S))χx(S)=1xS

Şimdi, çözersek üzerine f ( S 1 ) , ... , f ( S k ) ve çözümleri olduğu { f ( S b 1 ) , ... , f ( S b m ) } , sonra da { f - 1 ( S b 1 ) , , f - 1 ( S b m ) }()f(S1),,f(Sk){f(Sb1),,f(Sbm)}{f1(Sb1),,f1(Sbm)} kapağı ayarlamak için bir çözümdür.

Bu yüzden bu problemin arama alanını budama yeteneğini test ettiğini düşünüyorum.


Minimum tepe kapağını nasıl buluyorsunuz?
Yuval Filmus

oh nvm bu çözüm, bunun yerine kapak ayarlanır.
Chao Xu

1
Bu doğru, ama belki de bu özel davanın belirli özelliklerinden yararlanabileceğimizi düşünüyorum. Örneğin, bu durumda, setlerin hepsi çok büyüktür, . Aslında, setlerdeki sayıların hepsi küçükse, boyutları daha da büyük olurdu. Ayrıca, kesinlikle her şeyi kapsayan 9 set bulabiliriz. Her neyse, arama alanını budamamı nasıl önerirsiniz? n9
Wakaka

Sorunun (*) soruda verilenle eşdeğer olduğunu anlamıyorum. Bir kere, soruda verilen problem, tüm tamsayıların olacağına dair söz verir , bu da problemde görünmeyen bit vektörlerinin ağırlıkları hakkında bir garantiye karşılık gelir (*). 109
DW

1

Tüm çift gcd'leri hesaplayarak, kopyaları kaldırarak ve sonra tekrarlayarak bunu nispeten verimli bir şekilde çözmek mümkündür. Etkili hale getiren, tekrarlamadan önce kopyaları kaldırma eylemidir.

Algoritmayı aşağıda daha ayrıntılı olarak açıklayacağım, ancak önce ikili bir operatör tanımlamaya yardımcı olur . Eğer S , T pozitif tamsayılar kümesi tanımlamak vardırS,T

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

Dikkat edin ve | S T | 10 9 (sizin probleminizde); tipik olarak, S T algoritması verimli hale yardımcı olan göstermektedir, bu sınırlar iki daha küçük olacaktır. Ayrıca S T ile | S | × | T | basit numaralandırma ile gcd işlemleri.|ST||S|×|T||ST|109STST|S|×|T|

Bu gösterimle, algoritma burada. sayı kümesi girdi olmasına izin verin . Bilgi İşlem G 2 = S 1S 1 , daha sonra S 3 = S 1S 2 , daha sonra S 4 = S 1S 3 , ve böyle devam eder. En küçük Bul k öyle ki 1 S k ama 1 S k - 1 . Sonra böyle küçük bir alt kümenin boyutunun k olduğunu biliyorsunuz.S1S2=S1S1S3=S1S2S4=S1S3k1Sk1Sk1k. Ayrıca böyle bir alt kümenin somut bir örneğini çıkarmak istiyorsanız, geri işaretçileri tutarak böyle bir seti kolayca yeniden oluşturabilirsiniz.

Bu, ara setlerin hiçbiri üzerinde büyüymediği için nispeten verimli olacaktır (aslında, boyutları muhtemelen bundan daha küçük olacaktır) ve çalışma süresi yaklaşık 500 × ( | S 1 | + | S 2 gerektirir) | + ) gcd işlemleri.109500×(|S1|+|S2|+)

İşte verimliliği daha da artırabilecek bir optimizasyon. Temel olarak, tekrarlanan en küçük bulmak için iki katına kullanabilirsiniz öyle ki 1 S k . Özellikle, her bir x S i elemanı için , gcd x olan ve boyutu i olan S 1'in en küçük alt kümesini takip ediyoruz . (Yinelenenleri kaldırdığınızda, bağları daha küçük olan alt küme lehine çözersiniz.) Şimdi, dokuz kümenin sırasını hesaplamak yerine S 1 , S 2 , S 3 , S 4 ,k1SkxSiS1xi , bunun yerine S 2 = S 1S 1 , sonra S 4 = S 2S 2 hesaplayarak S 1 , S 2 , S 4 , S 8 , S 9 beş setin sırasınıhesaplıyoruz, S 8 = S 4S 4 , sonra S 9 = S 1 × S 8S1,S2,S3,S4,,S9S1,S2,S4,S8,S9S2=S1S1S4=S2S2S8=S4S4S9=S1×S8. Gittiğiniz gibi, ilk bulmak böyle 1 S k . Eğer bulduktan sonra k öyle ki 1 S k , hemen durdurabilirsiniz: kimin gcd en küçük alt kümesini bulabilirsiniz 1 ile ilişkili alt kümesi bakarak 1 . Yani, bir dizi ulaşmak en kısa sürede durabilir S k öyle ki 1 S k , daha küçük bir alt kümesi bulursanız erken durdurmak için olanak sağlayan.k[1,2,4,8,9]1Skk1Sk11Sk1Sk

Bu zaman ve alan açısından verimli olmalıdır. Yerden tasarruf etmek için, her bir öğesi için , tüm seti saklamanız gerekmez: iki arka noktası depolamak yeterlidir (böylece gcd'yi aldığınız S i , S j'nin iki öğesi x elde etmek için ) ve isteğe bağlı olarak karşılık gelen alt kümenin boyutu.xSkSi,Sjx

Prensip olarak, dizisini başka bir ilave zinciriyle değiştirebilirsiniz . Başka bir ekleme zincirinin daha iyi olup olmayacağını bilmiyorum. Optimal seçimi doğru cevaplar ve kümelerin beklenen boyutlarının dağılımı bağlı olabilir S k bana belli değil, ama muhtemelen deneyler yoluyla ampirik olarak elde edilebilir.[1,2,4,8,9]Sk

Kredi: Her elemanın birlikte sayıların bir alt kümesi depolamak fikrine KWillets için teşekkür ediyorum erken durdurma sağlar.Si


İkili aramanın gerekli olmadığına inanıyorum; her gcd ile öğe sayısını kaydedebilir ve her iki katlama sırasında minimum çift toplamına ayarlayabilirsiniz.
KWillets

Harika bir nokta, @KWillets! Bu güzel fikir için teşekkürler! Cevabıma dahil ettim.
DW

0

Belki de buna başka bir şekilde bakmak daha hızlı ... en büyük asal 109 is 31607, for a total count of 3401 primes between 2 and 31607, not a very large number. Write each of the numbers you are given fully factored over the primes up to 31607:

ai=p1ni1p2ni2Pi
Here Pi is 1 or a large prime. Then a set of the ai's is relatively prime if the corresponding nij vectors are linearly independent (and their Ps are different or both 1), and you are looking for the rank of a matrix.

What is the connection to linear independence? The vectors (1,1) and (1,0) are linearly independent, but the GCD is (1,0) while we want (0,0).
Yuval Filmus

1
Linear independence doesn't seem to work, but we can use this prime decomposition in a different way. For each prime p (among 3401 pi's and at most 500 Pi's), define set Ap as the collection of all numbers (among the given set) which do not have p as a factor. The problem now is to find a smallest subset B of numbers such that for each Ap, |ApB|1. This is the hitting set problem, equivalent to set cover problem. This is NP-complete, but there might be some implementations fast enough for this size.
polkjh

Could you direct me to some implementations that could work? So far, I can only find approximation algorithms. Thanks!
Wakaka

This survey paper looks at both approximate and exact solutions. And when replying to a comment, please add @name-of-person to the comment. It will send a notification to that person. Otherwise they may never even know about your comment.
polkjh

-1

If you are able to find a subset with gcd(S) = 1, then I can always remove redundant elements from the subset till only 2 elements remain , which have gcd(S) = 1. Therefore, I can claim that either the smallest subset will contain 2 elements or it will not exist.

Now, we use recursion to solve this problem. Let's divide the array of numbers into 2 parts, one with n-1 elements and one with 1 element (last element). Either the 2 numbers will be in the first n-1 elements or one element will be there from 1st part paired with last element. Therefore, we are able to solve this problem in

T(n) = T(n-1) + O(n) time. which means T(n) = O(n^2).


4
gcd(6,10,15)=1. Which element can you remove?
Rick Decker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.