GCD = 1の最小サブセットのサイズを見つける


10

これは、ポーランドの大学プログラミングコンテスト2012の練習セッションの問題です。メインコンテストの解決策は見つかりましたが、この問題の解決策はどこにも見当たりません。

問題は次のとおりです以下の異なる正の整数のセットが与えられたら、1以外の公約数を持たない最小サブセットのサイズを見つけますは最大で500であり、解が存在すると仮定できます。10 9 m NN109mN

私はそれを示すために、管理。私の推論は次のとおりです。サイズがで、gcd = 1の最小サブセットがあるとします。次に、すべての9サブセットはgcd> 1でなければなりません。そのようなサブセットは正確に10あり、それらのgcdはペアワイズでなければなりませんcoprime。これらのgcdをとすると、i \ neq jに対してになります。その場合、Sの最大数はg_2g_3 ... g_ {10}です。しかし、g_2g_3 ... g_ {10} \ ge 3 \ times5 \ times7 \ times11 \ times ... \ times29 = 3234846615> 10 ^ 9、これは矛盾です。S | S | = 10 S 1 < g 1 < g 2 < 。。。< g 10 gcd (g i、g j)= 1 i ≠ j Sm≤9S|S|=10S1<g1<g2<...<g10gcd(gi,gj)=1i≠jS g 2 g 3。。。G 10 ≥ 3 × 5 × 7 × 11 × 。。。× 29 = 3234846615 > 10 9g2g3...g10g2g3...g10≥3×5×7×11×...×29=3234846615>109

ただし、これを使用しても、単純な総当たりはまだ遅すぎます。誰か他のアイデアはありますか?


なぜg_2 = 2できないのg2=2ですか?
— フォンブランド2013年

g2>g1≥2。g1 9-サブセットが1のGCDを持つことができないので、1にすることはできません
— Wakaka

回答:


1

この問題は次と同等であり、両方の方法でリダクションを構築することは簡単です。

ビットベクトルのリストを指定して、それらのandすべてがビットベクトルになるような最小数を見つけます。(∗ )0(∗)

次に、セットカバーが減少することを示します。セットカバーとは、セットリストが与えられたときに、それらの和集合をカバーするセットの最小数を見つけることを意味します。S 1、… 、S k(∗)S1,…,Sk

セットの要素を順に並べます。ましょう、ここでであれば、そうでなければ0。この関数は全単射であるため、逆の関数があることに注意してください。 F (S )= (1 - χ 1(S )、... 、1 - χ N(S ))χ X(S )= 1 のx ∈ Sa1,…,anf(S)=(1−χa1(S),…,1−χan(S))χx(S)=1x∈S

今、我々は解決している場合に、およびソリューションは、、次いではカバーを設定するためのソリューションです。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)}

したがって、この問題は、検索スペースを整理する能力をテストしていると思います。


どのようにして最小頂点カバーを見つけますか?
— Yuval Filmus 2013年

ああ、このソリューションはnvmです。代わりにカバーが設定されています。
— Chao Xu

1
それは本当ですが、この特殊なケースの特定の特性を活用できると私は考えています。たとえば、この場合、セットはすべて非常に巨大で、サイズは以上です。実際、セットの数がすべて小さい場合、それらのサイズはさらに大きくなります。さらに、すべてをカバーする9セットを間違いなく見つけることができます。とにかく、どうすれば検索スペースを削除することができますか?n−9
— ワカカ

問題(*)が質問で与えられたものとどのように等しいかわかりません。1つには、質問で与えられた問題は、すべての整数がになるという約束を持っています。これは、問題(*)に現れないビットベクトルの重みに関する保証に対応します。≤109
— DW

1

すべてのペアワイズgcdを計算し、重複を削除してから再帰することで、これを比較的効率的に解決できます。再帰する前に重複を削除することで効率的になります。

アルゴリズムについては以下で詳しく説明しますが、最初に、二項演算子を定義すると役立ちます。場合は正の整数の集合である、定義S 、T⊗S,T

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

ことに注意してくださいおよび(問題中); 通常、は、これらの境界のどちらかが示唆するよりもさらに小さくなり、アルゴリズムの効率化に役立ちます。でを計算できることにも注意してください単純な列挙によるgcd操作。| S ⊗ T | ≤ 10 9 S ⊗ T S ⊗ T | S | × | T ||S⊗T|≤|S|×|T||S⊗T|≤109S⊗TS⊗T|S|×|T|

その表記で、これがアルゴリズムです。してみましょう数字の入力集合とします。計算、その後、、その後、、というように。だがような最小のを見つける。次に、そのような最小のサブセットのサイズがであることを知っています。そのようなサブセットの具体的な例も出力したい場合は、バックポインターを保持することで、そのようなセットを簡単に再構築できます。S 2 = S 1 ⊗ S 1 S 3 = S 1 ⊗ S 2 S 4 = S 1 ⊗ S 3、K 1 ∈ S K 1 ∉ S K - 1 KS1S2=S1⊗S1S3=S1⊗S2S4=S1⊗S3k1∈Sk1∉Sk−1k

中間セットのサイズが超えることはなく(実際、それらのサイズはおそらくそれよりはるかに小さいため)、実行時間は約必要ですこれは比較的効率的です。 gcd操作。 500 × (| S 1 | + | S 2 | + ⋯ )109500×(|S1|+|S2|+⋯)

これは、効率をさらに向上させる可能性のある最適化です。基本的に、反復ダブリングを使用して、ような最小のを見つけることができます。特に、各要素について、gcdがでサイズがであるの最小サブセットを追跡します。(重複を削除すると、小さい方のサブセットを優先してタイを解決します。)ここで、9つのセットのシーケンスを計算する代わりに、代わりに5つのセットのシーケンスを計算します。、計算することにより、、次に1 ∈ 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 1 ⊗ S 1 、S 4 = S 2 ⊗ S 2 Sk1∈Skx∈SiS1x≤iS1,S2,S3,S4,…,S9S1,S2,S4,S8,S9S2=S1⊗S1S4=S2⊗S2S 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=S4⊗S4、次に。進むにつれて、なる最初のます。となるようなを見つけたら、すぐに停止できます関連付けられているサブセットを調べると、gcdがである最小のサブセットを見つけることができます。そのため、がになるようなセット達したらすぐに停止できます。これにより、小さいサブセットが見つかった場合に早期に停止できます。S9=S1×S8k∈[1,2,4,8,9]1∈Skk1∈Sk11Sk1∈Sk

これは、時間効率とスペース効率に優れている必要があります。スペースを節約するには、各要素、セット全体を格納する必要はありません。2つのバックポインタを格納するだけで十分です(を取得するには、gcdを実行した 2つの要素)。オプションで、対応するサブセットのサイズ。S I、S jの Xx∈SkSi,Sjx

原則として、シーケンスを他の追加チェーンで置き換えることができます。他の追加チェーンの方が優れているかどうかはわかりません。最適な選択は、正解の分布とセット予想されるサイズに依存する可能性があります。S K[1,2,4,8,9]Sk

クレジット:の各要素と一緒に数字のサブセットを格納するためのアイデアKWilletsに感謝早く停止することができます。Si


バイナリ検索は必要ないと思います。各gcdで要素数を保存し、それを各倍加の間の最小ペア合計に設定できます。
— KWillets 2015

素晴らしい点、@ KWillets!その美しいアイデアをありがとう!私はそれを私の答えに組み込んだ。
— DW

0

おそらくこれを別の方法で見ると速くなります...よりも小さい最大素数は31607であり、2から31607までの合計3401素数であり、それほど大きな数ではありません。あなたが与えられた完全アップ31607に素数の上に織り込まれる番号の各書く: ここ 1であるか、大きな素数。次に、対応するベクトルが線形独立であり(それらのが異なるか、両方とも1である)、マトリックスのランクを探している場合、のセットは比較的素数です。 ai=p n i 1 1 p n i 2 2 …PiPiainijP109

ai=p1ni1p2ni2…Pi
PiainijP

線形独立との関係は何ですか?ベクトルとは線形独立ですが、GCDはですが、必要です。(1 、0 )、 (1 、0 )、 (0 、0 )(1,1)(1,0)(1,0)(0,0)
— Yuval Filmus 2013年

1
線形独立は機能していないようですが、この素分解を別の方法で使用できます。各素数(と最大の間)について、セットを、因子としてを持たない(与えられたセットの中の)すべての数値のコレクションとして定義します。ここでの問題は、各、ような数値の最小サブセットを見つけることです。これはヒッティングセット問題であり、セットカバー問題と同等です。これは完全ですが、このサイズに十分に高速な実装もいくつかあります。3401 p i 500 P i A p p B A p | P ∩ B | ≥ 1 N Pp3401 pi500 PiAppBAp|Ap∩B|≥1NP
— polkjh

機能する可能性のあるいくつかの実装を教えていただけますか?これまでのところ、私は近似アルゴリズムしか見つけることができません。ありがとう!
— ワカカ

この調査ペーパーでは、近似解と正確解の両方を調べます。また、コメントに返信するときは、@ name-of-personをコメントに追加してください。その人に通知を送信します。そうでなければ、彼らはあなたのコメントについてさえ知ることはないかもしれません。
— polkjh 2013年

-1

gcd(S)= 1のサブセットを見つけることができる場合、gcd(S)= 1の2つの要素のみが残るまで、サブセットから冗長要素を常に削除できます。サブセットには2つの要素が含まれるか、存在しません。

現在、この問題を解決するために再帰を使用しています。数値の配列を2つの部分に分割しましょう。1つはn-1要素、もう1つは1要素(最後の要素)です。2つの数値は最初のn-1要素にあるか、最後の要素とペアになった最初の部分から1つの要素がそこにあります。したがって、私たちはこの問題を解決することができます

T(n)= T(n-1)+ O(n)時間。これは、T(n)= O(n ^ 2)を意味します。


4
gcd(6,10,15)=1。どの要素を削除できますか?
— Rick Decker
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.