アルゴリズムの繰り返しと生成関数


18

コンビナトリクスは、コンピューターサイエンスで重要な役割を果たします。アルゴリズムの設計と設計の両方で、組み合わせ手法を頻繁に利用します。たとえば、グラフで頂点カバーセットを見つける方法の1つは、\ binom {n} {k}の可能なサブセットすべてを検査するだけです。二項関数は指数関数的に成長しますが、kが何らかの固定定数である場合、漸近解析による多項式時間アルゴリズムになります。k(nk)k

多くの場合、現実の問題には、より複雑な組み合わせのメカニズムが必要であり、それを繰り返しの観点から定義することができます。有名な例の1つは、(単純に)次のように定義されたフィボナッチ数列です。

f(n)={1if n=10if n=0f(n1)+f(n2)otherwise

n番目の項の値の計算は、この繰り返しを使用して指数関数的に増加しますが、動的プログラミングのおかげで、線形時間で計算できます。現在、すべての繰り返しがDP(オフハンド、階乗関数)に役立つわけではありませんが、カウントを生成関数ではなく繰り返しとして定義する場合、潜在的に悪用可能なプロパティです。

関数の生成は、特定の構造のカウントを形式化するエレガントな方法です。おそらく最も有名なのは、次のように定義された二項関数です。

(x+y)α=k=0(αk)xαkyk

幸いなことに、これには閉じた形式のソリューションがあります。すべての生成関数がこのようなコンパクトな記述を許可するわけではありません。

私の質問はこれです:アルゴリズムの設計で使用される関数を生成する頻度はどれくらいですか?分析によってアルゴリズムに必要な成長率を理解するためにそれらがどのように活用されるかは簡単にわかりますが、問題を解決する方法を作成するときに問題について教えてください。

同じカウントが何度も繰り返しとして再定式化される場合、動的プログラミングに役立つ可能性がありますが、おそらく同じ生成関数は閉じた形式になります。だから、それはそれほど均等にカットされていません。


生成関数が数式(たとえば、フィボナッチ数のBinetの数式)を提供し、それを使用して、再帰を使用する代わりに(おそらくより効率的に)数値を計算できる場合、それを答えと見なしますか?
アルヤバタ

回答:


11

生成関数は、カウントアルゴリズムを設計するときに役立ちます。つまり、特定のプロパティを持つオブジェクトの数を探しているときだけでなく、これらのオブジェクトを列挙する方法を探しているとき(そしておそらく、オブジェクトをカウントするアルゴリズムを生成するとき)もです。Ronald Graham、Donald Knuth、およびOren Patashnikによる具象数学の第7章には非常に優れたプレゼンテーションがあります。以下の例はこれらの本からのものです(間違いや明確さの欠如は私のものです)。

コインのセットを変更する方法を探しているとします。たとえば、一般的な米国の金種¹では、可能なコインはです。変化に¢42を与えるための1つの可能性は、です。別の可能性はです。書きます。より一般的には、変化を与えるすべての方法に対して生成関数を書くことができます: より専門的な用語では、は5つの変数のべき級数空間の項です[1],[5],[10],[25],[100][25][10][5][1][1][10][10][10][10][1][1]42[25][10][5][1]2=[10]4[1]2

H=h0q0d0n0p0[100]h[25]q[10]d[5]n[1]p
H[100],[25],[10],[5],[1]。この空間での単項式の評価を 変化にセント を与える方法は、評価がである単項式の数です。最初にペニーのみを変更する方法を書き留め、次にペニーとニッケルを変更する方法を書き留めることで、を漸進的に表現できます。(はコイン意味しません。)
[100]h[25]q[10]d[5]n[1]p=100h+25q+10d+5n+p
vvHPNI
P=I+[1]+[1]2+[1]3+=II[1]N=(I+[5]+[5]2+[5]3+)P=PI[5]D=(I+[10]+[10]2+[10]3+)N=NI[10]Q=(I+[25]+[25]2+[25]3+)D=DI[25]H=(I+[100]+[100]2+[100]3+)Q=QI[100]
変更を与える方法を列挙するだけでなく数えたい場合は、取得した正式なシリーズを使用する簡単な方法があります。準同型適用し の係数における与えるために多くの方法であり変化セント。
S:[1]X,[5]X5,[10]X10,[25]X25,[100]X100
XvS(C)v

より難しい例:2×1ドミノで長方形を並べるすべての方法を勉強したいとします。たとえば、2つの水平ドミノまたは2つの垂直ドミノを使用して、2×2の長方形を並べるには2つの方法があります。長方形を並べる方法の数を数えるのはかなり簡単ですが、場合はすぐに明らかになります。ドミノを貼り付けることで、高さ3の水平バンドのすべての可能なタイルを列挙できます。これにより、繰り返しパターンがすばやく生成されます。 2×n3×n

{U=o+LV+ΓΛ+UV=IU+=VΛ=IU+=Λ
ここで、面白い形は基本的なドミノ配置を表します。はドミノではなく、は水平ドミノの左部分の上にある垂直ドミノ、は、高さ3のバンドの下部に揃えられた垂直ドミノです。は、バンドの上部とその下の2つの水平ドミノと1ステップ右に揃えられた水平ドミノです。ここでは、乗算は水平連結を表し、可換ではありませんが、このべき級数の変数を形成する基本パターン間に方程式があります。コインの場合と同様に、すべてのドミノの代わりにを使用し、タイルの数の生成シリーズを取得できますoLI=X3×(2n/3)長方形(つまり、係数は、ドミノを含み、幅がの領域長方形を方法の数です)。このシリーズは、より用途の広い方法でも使用できます。たとえば、垂直ドミノと水平ドミノを区別することにより、指定された数の垂直ドミノと水平ドミノのタイルをカウントできます。X3k6k3k2k

繰り返しますが、コンクリート数学を読んで、急ぎの少ない³プレゼンテーションをご覧ください。

¹ リストが不完全であることはわかっています。数学的な例に適した簡略化された米国を想定します
。²² また、それが出てきたら、球形のコインを想定します。
³ そしてより良い組版。


8

2001年の学生プログラミングコンテストで解決しなければならなかった問題を覚えています。問題は次のとおりです。

質量が1、7、13、...の場合(どの質量か覚えていませんが、有限の確定した質量のセットがありました)、これを使用して所定の重量をスケールで計量できるかどうかを決定する関数を設計します質量のセット。

ネストされたループから始めましたが、すぐに壁にぶつかりました。それから私は、重いものを続ける前に、軽いものでできることを列挙することから始めなければならないことに気付いた。多くのネストされていないループで問題を解決できました。

当時、私は若々しくrog慢で自給自足ではなかった(そして関数の生成について知っていて練習していた)ので、関数の生成に関する問題を次のように定義したかもしれません。

を、質量のセットが与えられたときに重みを計量できる方法の数のOGFとして定義します。f(x)n

単一の質量1が与えられた場合、右の皿のどの重さを量ることができますか?

3つの可能性:

  • 左の皿にマスを置いたら、1の重さを量ることができます。
  • 質量を正しい鍋に置くと、-1の重さができます。
  • 質量を使用しない場合、0の重量を量ることができます。

だから、重量を量るための一つの方法があり、重量を量るための一つの方法、そして一つの方法を比較検討する。この質量の生成関数はようなもので、以下に対応します。101x1+1+x

1x3x(1x)

単一の質量の生成関数はです。mxm+1+xm

1x3mxm(1xm)

質量の多重集合が与えられた場合、は単一の質量生成関数の積として表されます。Mf

f(x)=mM(1x3m)xmMmmM(1xm)

ここで、多項式の演算を実行できるパッケージが与えられた場合、あなたはただする必要があります:

  • 両方の製品を計算します。
  • これらの製品の分割を、最低度から始めてください。(終了)
  • 多項式をシフトします(ユークリッド除算をで行い、商を保持し、余りをダンプします)xk

これで完了です。これで、多項式には、インデックスでをする方法がいくつかあります。唯一の入力は質量のマルチセットです。w0wM

数学的に適切なコンポーネントを使用してアルゴリズムを設計しました。アルゴリズムの主要部分は、最初に最低次数をもつ多項式除算であり、線形であり、既製のパッケージで実装できます。最適ではないかもしれませんが、コンテストで私がやったよりも間違いなくパフォーマンスが良く、間違いも少ないです。

除算プロセスをよく見ると、プロセスのすべての状態で残りが「現在の隠された状態」であり、商が結果であることがすぐにわかります。「現在の非表示状態」がどこでもゼロに達すると、プロセスは終了します。

多項式を配列として実装することができます。または、実際にスパースである場合は、インデックス係数の順序付きリストとして実装できますが、これによりアルゴリズムは変更されません。


3

マトロイド上の単調サブモジュラー最大化のアルゴリズムを開発している間、再帰を解かなければなりませんでした に 気づいた後、この問題をユニバーサルシーケンス計算に。後者は生成関数を使用して達成され、そこから再び生成関数を使用して明示的な式を得ました。好奇心が強い場合は、この派生を含めることを決して気にしませんでしたが、論文で解決策を見つけることができます。

γ+1(m)=(2m)γ(m)+(m+1)γ1(m),γ0(m)=1,γm+1(m)=e.
γ(m)=m(γ(m1)γ1(m1))γ(0)γ(m)

0

おそらく、Quicksortとその多くの変種の広範な研究が最も明確な例でしょう。代替の考慮事項を管理する組み合わせの考慮事項があり、非常に複雑な方程式の解を分析すると、それらのパフォーマンス上の利点(またはそうでない)が示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.