可能な組み合わせ。 組み合わせ論の要素

組み合わせとは、固定数を持ち、要素の繰り返しのない、有限セットの要素を順序付けずに選択したものです。 異なる組み合わせは少なくとも 1 つの要素が異なる必要があり、要素の順序は重要ではありません。 たとえば、ラテン文字のすべての母音のセット (AEIOU) から、3 つの文字を 10 通り組み合わせて、次の順序のない 3 つ組を形成できます。


AEI、AEO、AEU、AIO、AIU、AOU、EIO、EIU、EOU、IOU.


興味深いのは、同じ 5 つの文字を 2 文字ずつ組み合わせて、次のような順序のないペアを作ると、10 通りの異なる組み合わせが得られることです。


AE、AI、AO、AU、EI、EO、EU、IO、IU、OU.


ただし、同じラテン語の母音を 4 つずつ組み合わせると、次の 5 つの異なる組み合わせしか得られません。


エイオ、エイウ、アイオウ、エイオウ、アエオウ。


一般に、n 個の異なる要素の組み合わせの数を m 個の要素で表すには、次の関数、インデックス、またはベクトル (Appel) 記号が使用されます。



指定の形式に関係なく、n 個の要素×m 個の要素の組み合わせの数は、次の乗算式および階乗式によって決定できます。


これらの式を使用した計算の結果が、ラテン語の母音の組み合わせを使用した上記の例の結果と一致することを確認するのは簡単です。 特に、n=5 および m=3 の場合、これらの式を使用して計算すると、次の結果が得られます。


一般的な場合、組み合わせの数の式には組み合わせの意味があり、n > m > 0 となる n と m の任意の整数値に対して有効です。 m > n かつ m の場合< 0, то число сочетаний равно 0, так как в этом случае основное множество из n элементов вообще не имеет подмножеств мощности m:



さらに、次の組み合わせ制限の数値を覚えておくと便利です。これらの数値は、乗法および階乗の公式に直接代入することで簡単に確認できます。



また、n が実数であっても、m が整数である限り、乗算公式は有効なままであることにも注意してください。 ただし、その計算結果は形式的な妥当性を維持しながらも、その組み合わせの意味を失います。


組み合わせのアイデンティティ


n と m の任意の値の組み合わせの数を決定するための乗法式と階乗式の実際の使用は、分子と分母の階乗積が指数関数的に増加するため、あまり生産的ではありません。 n と m の比較的小さな値であっても、これらの製品は、多くの場合、現代のコンピューティングおよびソフトウェア システムで整数を表現できる可能性を超えています。 同時に、それらの値は、比較的小さい可能性がある組み合わせの数の結果として得られる値よりもはるかに大きいことがわかります。 たとえば、n=10、m=8 要素の組み合わせは 45 通りです。ただし、階乗式を使用してこの値を求めるには、まず 10 というさらに大きな値を計算する必要があります。 分子に8! 分母で:


大きな値を処理する時間のかかる操作を除外し、組み合わせの数を決定するには、乗法式や階乗式から直接得られるさまざまな漸化式を使用できます。 特に、次の漸化式は乗法公式から導き出され、組み合わせの数の符号を超えてインデックスの比を取得することができます。


最後に、添字を変更しないと次の漸化式が得られます。これは、組み合わせの数の階乗式から簡単に取得できます。


基本的な変換の後、結果として得られる 3 つの漸化関係は次の形式で表すことができます。



最初の 2 つの式の左部分と右部分を加算し、その結果を n だけ減らすと、重要な漸化関係が得られます。これは、組み合わせの数を加算する恒等式と呼ばれます。


加算恒等式は、n と m の大きな値の組み合わせの数を効率的に決定するための基本的な再帰規則を提供します。これにより、階乗積の乗算演算をより単純な加算演算に置き換えることができ、組み合わせの数が少なくなります。 特に、加算恒等式を使用すると、次の反復変換シーケンスを実行することで、上で検討した n=10 x m=8 要素の組み合わせの数を簡単に決定できるようになります。


さらに、有限和を計算するための加算恒等式からいくつかの有用な関係を導き出すことができます。特に、次の形式を持つ添字の合計公式です。



このような関係は、その下付き文字が 0 より大きい限り、最大の上付き文字を持つ項にわたって加法恒等式の漸化式を拡張することによって取得されます。次の数値例は、示された再帰的変換のプロセスを示しています。



添字の合計公式は、自然数の累乗の合計を計算するためによく使用されます。 特に、m=1 と仮定すると、この式を使用すると、自然系列の最初の n 個の数値の合計を簡単に見つけることができます。


加算公式のもう 1 つの有用なバージョンは、最小の上付き文字を持つ項にわたって加算恒等式の漸化式を拡張することによって取得できます。 次の数値例は、この反復変換の変形を示しています。



一般的な場合、このような変換の結果、両方のインデックスが隣接する項と 1 だけ異なる組み合わせの数の合計が得られ、インデックスの差は一定のままになります (考慮された例では、 1に等しい)。 したがって、組み合わせ数の両方のインデックスに対する次の合計公式が得られます。



上で論じた漸化式と和の公式に加えて、組み合わせ分析では組み合わせ数に関する他の多くの有用な恒等式が得られています。 その中で最も重要なのは、 対称性の同一性、次の形式になります。



対称性の同一性の妥当性は、5 つの要素の組み合わせの数を 2 と (5 2) = 3 で比較することによって次の例で確認できます。



対称恒等式には、n 個の要素から m 個の要素を選択するためのオプションの数を決定すると同時に、残り (nm) 個の選択されていない要素からの組み合わせの数も確立されるため、明らかな組み合わせの意味があります。 示された対称性は、組み合わせの数の階乗式で m を (nm) に相互に置き換えることですぐに得られます。


数値と恒等式の組み合わせは、現代の計算数学のさまざまな分野で広く使用されています。 ただし、最も一般的なアプリケーションは、ニュートンの二項式とパスカルの三角形に関連付けられています。

二項定理


さまざまな数学的変換や計算を実行するには、代数二項式 (二項式) の自然累乗を多項式の形式で表現できることが重要です。 次数が小さい場合は、二項式を直接乗算することで、目的の多項式を簡単に取得できます。 特に、2 つの項の和の 2 乗と 3 乗を表す次の公式は、初等数学のコースでよく知られています。



一般的なケースでは、二項式の任意の次数 n に対して、多項式の形式での目的の表現は、次の等式が成り立つことを宣言するニュートンの二項定理によって提供されます。



この等式は通常、ニュートンの二項式と呼ばれます。 右側の多項式は、左側の二項式の n 個の項 X と Y の積の和であり、その前の係数は二項式と呼ばれ、得られるインデックスとの組み合わせの数に等しくなります。彼らの力から。 組み合わせ分析ではニュートンの二項公式が特に人気があるため、二項係数と組み合わせの数という用語は通常同義語とみなされます。


明らかに、二乗和と立方体の公式は、それぞれ n=2 と n=3 の二項定理の特殊なケースです。 より高いべき乗 (n>3) を処理するには、ニュートンの二項公式を使用する必要があります。 4 次二項 (n=4) への適用を次の例で示します。



二項公式はニュートン以前からアラブ東欧や西ヨーロッパの中世の数学者には知られていたことに留意すべきである。 したがって、その通称は歴史的には正しくありません。 ニュートンの利点は、この式を任意の実数指数 r の場合に一般化し、正または負の有理値および無理数値を取り得ることです。 一般的な場合、このようなニュートン二項式は右辺に無限和があり、次のように書くのが通例です。



たとえば、指数 r=1/2 の正の小数点の場合、二項係数の値を考慮すると、次の展開が得られます。


一般的なケースでは、任意の指数に対するニュートン二項公式は、べき級数における任意の関数の展開を与えるマクローリン公式の特定のバージョンです。 ニュートンは |z| についてそれを示しました。< 1 этот ряд сходится, и сумма в правой части становится конечной. При любой натуральной степени r = n в правой части также получается конечная сумма из (n+1) первых слагаемых, так как все C(n, k>n) = 0 。 ここで Z=X/Y と置き、左右の部分に Yn を掛けると、上で説明したニュートンの二項公式の変形が得られます。


その普遍性にもかかわらず、二項定理は二項の整数の非負べき乗に対してのみその組み合わせの意味を保持します。 この場合、二項係数のいくつかの有用な恒等式を証明するために使用できます。 特に、下位のインデックスと両方のインデックスによる組み合わせの数の合計公式が上で検討されました。 欠落している上付き和の恒等式は、X = Y = 1 または Z = 1 を設定することにより、ニュートンの二項式から簡単に取得できます。



もう 1 つの有用な恒等式は、偶数と奇数の二項係数の合計が等しいことを確立します。 X = 1、Y = 1、または Z = 1 の場合、ニュートンの二項公式からすぐに得られます。



最後に、考慮された両方の恒等式から、偶数のみまたは奇数のみを含む二項係数の合計の恒等式を取得します。



考慮された恒等式と、組み合わせの数の符号の下からインデックスを削除するための再帰規則に基づいて、多数の興味深い関係を取得できます。 たとえば、上付き文字の合計の式で、すべての n を (n1) に置き換え、各項のインデックスを取り出すと、次の関係が得られます。



偶数と奇数の二項係数の合計の式で同様の手法を使用すると、たとえば次の関係の妥当性を証明できます。



もう 1 つの便利な恒等式を使用すると、次のコーシーの公式を使用して、任意の次数 n および k の 2 つの二項式の対称に位置する二項係数の積の合計を簡単に計算できます。



この式の妥当性は、次の恒等関係の左側と右側の変数 Z の任意の次数 m に対する係数の必要な等しいことから得られます。



n=k=m の特定のケースでは、対称性を考慮して、二項係数の二乗和のより一般的な式が得られます。



二項係数の他の多くの有用な恒等式は、組み合わせ分析に関する広範な文献で見つけることができます。 ただし、それらの最も有名な実際の応用は、パスカルの三角形に関連しています。


パスカルの三角形


パスカルの算術三角形は、二項係数で構成される無限の数値表を形成します。 その行は、二項累乗によって上から下に順序付けされます。 各行では、二項係数が、対応する組み合わせ数の上位インデックスの昇順で左から右に配置されます。 パスカルの三角形は通常、二等辺三角形または長方形で書かれます。


より視覚的で一般的なのは二等辺形式です。この形式では、市松模様に配置された二項係数が無限の二等辺三角形を形成します。 4 次 (n=4) までの二項式の最初のフラグメントは次のとおりです。


一般に、パスカルの二等辺三角形は、加算恒等性と組み合わせ数の対称性に基づいて、二項係数を決定するための便利な幾何学的規則を提供します。 特に、加算恒等式によれば、二項係数は、それに最も近い前の行の 2 つの係数の合計です。 対称恒等式によれば、パスカルの二等辺三角形は二等分線に関して対称です。 したがって、その各行は二項係数の数値回文です。 これらの代数的および幾何学的機能により、パスカルの二等辺三角形を拡張し、任意の次数の二項係数の値を一貫して見つけることが容易になります。


ただし、パスカルの三角形のさまざまな特性を研究するには、形式的にはより厳密な長方形形式を使用する方が便利です。 この形式では、二項係数の下三角行列によって与えられ、無限の直角三角形を形成します。 9 次 (n=9) までの二項式のパスカルの直角三角形の最初の部分は、次の形式になります。



幾何学的には、このような長方形のテーブルは、パスカルの二等辺三角形を水平方向に変形することによって得られます。 その結果、パスカルの二等辺三角形の辺に平行な数列は、パスカルの直角三角形の垂直線と対角線となり、両三角形の水平線は一致します。 同時に、パスカルの直角三角形は、対応する二等辺三角形に固有の視覚的な対称性を失いますが、二項係数の加算と対称性の規則は引き続き有効です。 これを補うために、パスカルの直角三角形の水平、垂直、対角の二項係数のさまざまな数値特性を正式に分析する方が便利になります。


パスカルの直角三角形の輪郭の分析を開始すると、上付き文字による二項の合計公式に従って、番号 n の任意の行の要素の合計が 2 n に等しいことが簡単にわかります。 このことから、番号 n の水平方向の要素の合計は (2 n 1) に等しいことがわかります。 この結果は、各水平方向の要素の合計の値が 2 進数系で記述される場合に非常に明白になります。 たとえば、n=4 の場合、このような加算は次のように記述できます。



ここでは、2 のべき乗にも関連する等高線のさらに興味深い特性をいくつか紹介します。 水平方向の数値が 2 の累乗 (n=2 k) である場合、そのすべての内部要素 (極端な単位を除く) は偶数であることがわかります。 逆に、その数が 2 の累乗より 1 少ない場合 (n=2 k 1)、水平方向の数はすべて奇数になります。 これらのプロパティの有効性は、たとえば水平方向 n=4 と n=3、または n=8 と n=7 で内部二項係数のパリティをチェックすることによって検証できます。


パスカルの直角三角形の行番号を素数 p とする。 この場合、そのすべての内部二項係数は p で割り切れます。 このプロパティは、単純な水平数の小さな値をチェックするのが簡単です。 たとえば、5 番目の水平方向 (5、10、および 5) のすべての内部二項係数は、明らかに 5 で割り切れます。水平方向 p の素数に対するこの結果の妥当性を証明するには、その二項係数の乗法式を書く必要があります。係数は次のようになります。


p は素数なので m! で割り切れないため、二項係数の整数値を保証するには、この式の分子の他の因数の積が m! で割り切れなければなりません。 したがって、角括弧内の関係は自然数 N であり、望ましい結果が明らかになります。



この結果を使用すると、内部要素が指定された素数 p で割り切れるパスカルの三角形のすべての等高線の数は p のべき乗である、つまり n=p k の形式を持つことが証明できます。 特に、p=3 の場合、素数 p は、上で確立したように行 3 のすべての内部要素だけでなく、たとえば 9 番目の水平方向 (9、36、84、および 126) も分割します。 一方、パスカルの三角形では、すべての内部要素が合成数で割り切れる水平線を見つけることは不可能です。 そうでない場合、そのような水平方向の数は、そのすべての内部要素を除算する合成数の素約数の次数と同時になければなりませんが、これは明白な理由により不可能です。


考慮した考察により、パスカルの三角形の水平要素の可分性に関する次の一般的な基準を定式化することができます。 番号 n のパスカルの三角形の水平方向のすべての内部要素の最大公約数 (gcd) は、n=pk の場合は素数 p に等しく、その他の場合は 1 です。


GCD(Cmn) = ( ) 任意の 0< m < n .


水平線の分析の結論として、水平線を形成する一連の二項係数が持つもう 1 つの興味深い特性を考慮する価値があります。 番号 n の任意の水平方向の二項係数に数値 10 の連続する累乗を乗算し、これらの積をすべて加算すると、11 n が得られます。 この結果の正式な実証は、値 X=10 および Y=1 (または Z=1) をニュートンの二項公式に代入することです。 次の数値例は、n=5 の場合のこのプロパティの実装を示しています。



パスカルの直角三角形の垂直方向の特性の分析は、構成要素の個々の特性を研究することから始めることができます。 形式的には、各垂直 m は、一定の上付き文字 (m) と下付き文字の増分を持つ次の二項係数の無限シーケンスによって形成されます。



明らかに、m=0 の場合は 1 の列が得られ、m=1 の場合は自然数の列が形成されます。 m=2 の場合、縦方向は三角形の数字で構成されます。 それぞれの三角数は正三角形として平面上に表現でき、その中に市松模様に配置された任意のオブジェクト (カーネル) が埋め込まれます。 この場合、各三角数 T k の値によって表現される原子核の数が決まり、インデックスはそれを表現するために何行の原子核が必要であるかを示します。 たとえば、最初の 4 つの三角数字は、対応するカーネル文字「@」の数から次の構成を表します。

同様の方法で、自然数を二乗することによって得られる平方数 S k 、および一般に正多角形を規則的に埋めることによって形成される多角形の比喩的な数を考慮に入れることができることに留意されたい。 特に、最初の 4 つの平方数は次のように表すことができます。

パスカルの三角形の垂直の分析に戻ると、m=3 の次の垂直が四面体 (ピラミッド) の数で満たされていることがわかります。 このような各数値 P k は、四面体の形に配置できる原子核の数を指定し、インデックスは、原子核を 3 次元空間で表現するために原子核の行から何層の水平三角形の層が必要かを決定します。 この場合、すべての水平レイヤーは連続した三角形の数字として表される必要があります。 m>3 のパスカルの三角形の次の垂直の要素は、平面上または 3 次元空間上で明確な幾何学的解釈を持たない超四面体数の行を形成しますが、形式的には三角形および四面体数の多次元類似物に対応します。


パスカルの三角形の垂直の数値系列には考慮された個々の巻き毛の特徴がありますが、それらについては、添字による組み合わせの数を合計する式を使用して、同じ方法で初期要素の値の部分和を計算することができます。 。 パスカルの三角形では、この公式は次の幾何学的解釈を持ちます。 任意の垂直方向の n 個の上位二項係数の値の合計は、1 行下にある次の垂直方向の要素の値に等しくなります。 この結果は、三角形、四面体、および超四面体数の幾何学的構造とも一致します。これは、そのような各数の表現が、より低い次数の数を表すカーネル層で構成されているためです。 特に、n 番目の三角形数 T n は、その線形ファイバーを表すすべての自然数を合計することによって取得できます。


同様に、四面体の数 P n は、その水平核層を構成する最初の n 個の三角形数の次の合計を計算することで簡単に見つけることができます。


パスカルの直角三角形の水平線と垂直線に加えて、要素の対角線の列を追跡することができ、その特性の研究も特に興味深いものです。 この場合、通常、下降対角線と昇順対角線は区別されます。 下降対角線はパスカルの直角三角形の斜辺に平行です。 これらは、両方のインデックスの増分を伴う一連の二項係数によって形成されます。 対称性の同一性により、下降対角線はその要素の値がパスカルの三角形の対応する垂直行と一致するため、上で検討したすべてのプロパティを繰り返します。 指定された対応関係は、垂直方向のゼロが考慮されない場合、下降対角線と任意の数 n の垂直方向の要素の値の一致によって追跡できます。



上向きの対角線は、パスカルの直角三角形の斜辺に対して幾何学的に垂直な数字の行を形成します。 これらは、下付き文字の増分と上付き文字の増分を持つ二項係数で埋められます。 特に、上部の 7 つの昇順対角線は、後続のゼロを除いて、次の数値シーケンスを形成します。



一般的なケースでは、次の二項係数は番号 n の昇順の対角線上にあり、それぞれのインデックスの合計は (n1) に等しくなります。



組み合わせの数の加算恒等により、各対角要素は、前の 2 つの昇順対角線のインデックスに対応する 2 つの要素の合計に等しくなります。 これにより、前の 2 つの対角線からの隣接する水平要素をペアごとに合計して、対角線に沿ってパスカルの三角形を無限に拡張することによって、後続の各上行対角線を構築することが可能になります。 次のパスカルの三角形の断片は、数字 6 と 7 の対角線に沿った数字 8 の上昇対角線の構築を示しています。

この構築方法では、3 番目から始まる任意の昇順対角線の要素の合計は、前の 2 つの昇順対角線の要素の合計と等しくなります。また、最初の 2 つの対角線は 1 つの要素 (値) のみで構成されます。対応する計算の結果は次の数値系列を形成し、これに従って、パスカルの直角三角形の上向きの対角線の考慮された特性の妥当性を検証することができます。



これらの数値を分析すると、同様の法則に従って、よく知られたフィボナッチ数列が形成され、連続する各数値は前の 2 つの数値の合計に等しく、最初の 2 つの数値は 1 に等しいことがわかります。



したがって、次の重要な結論を引き出すことができます。パスカルの三角形の要素の対角和はフィボナッチ数列を構成します。 この性質により、パスカルの三角形の別の興味深い特徴を確立することができます。 フィボナッチ数式を再帰的に展開すると、最初の n 個のフィボナッチ数の合計が (F n+2 1) に等しいことを証明するのは簡単です。

したがって、上位 n 個の対角を満たす二項係数の合計も (F n+2 1) に等しくなります。 パスカルの三角形の最初の n 個の対角線の合計は、その対角線上にある数値 (n + 2) の二項係数の合計より 1 少ないことになります。


結論として、パスカルの三角形の水平線、垂直線、対角線の考慮された特性は、一見共通点のないさまざまな数学的側面を結びつける膨大な種類の可能性をすべて網羅するわけではないことに注意する必要があります。 このような珍しい性質により、パスカルの三角形を最も先進的な数値システムの 1 つとみなすことが可能になりますが、その可能性をすべて列挙することはできず、過大評価することも困難です。


パスカルの三角形を使用して組み合わせの数を計算するアルゴリズムを以下に示します。

プライベート関数 SochTT (ByVal n As Integer, ByVal k As Integer) As Double Dim i As Integer Dim j As Integer Dim TT () As Double ReDim TT (n, k) For i = 0 To n TT (0, i) = 1 TT (i, i) = 1 次の場合 i = 2 To n の場合 j = 1 To i - 1 TT (i, j) = TT (i - 1, j - 1) + TT (i - 1, j)次へ 次へ SochTT = TT (n, k) 終了関数


組み合わせの数を何度も計算する必要がある場合は、パスカルの三角形を一度作成してから、配列からデータを取得する方が便利な場合があります。

Dim TT () As Double Private Sub CreateTT () ReDim TT (0, 0) BuildTT 0, 0 End Sub Private Function SochTT (ByVal n As Integer, ByVal k As Integer) As Double If n > Ubound (TT) then BuildTT Ubound (TT) + 1, n SochTT = TT (n, k) End Function Private Sub TerminateTT () ReDim TT (0, 0) End Sub Private Sub BuildTT (ByVal start As Integer、ByVal end As Integer) Dim i As Integer Dim j As Integer ReDim Preserve TT (end, end) For i = start To end TT (0, i) = 1 TT (i, i) = 1 Next If end< 2 Then Exit Sub If start < 2 Then start = 2 For i = start To end For j = 1 To i - 1 TT (i, j) = TT (i - 1, j - 1) + TT (i - 1, j) Next Next End Sub


まず、CreateTT プロシージャを呼び出す必要があります。 その後、SochTT 関数を使用して組み合わせの数を取得できます。 三角形が必要なくなったら、TerminateTT を呼び出します。 上記のコードでは、SochTT 関数を呼び出すときに、三角形が必要なレベルまで完成していない場合は、BuildTT プロシージャを使用して完成させます。 次に、関数は TT 配列の必要な要素を取得して返します。


Dim X () As Integer Dim Counter () As Integer Dim K As Integer Dim N As Integer Public Sub Soch() Dim i As Integer N = CInt(InputBox("Enter N")) K = CInt(InputBox("Enter K ")) K = K + 1 ReDim X(N) For i = 1 To N X(i) = i Next txtOut.Text = "" ReDim Counter(K) Counter(0) = 1 SochGenerate 1 End Sub Private Sub SochGenerate( ByVal c As Integer) Dim i As Integer Dim j As Integer Dim n1 As Integer Dim Out() As Integer Dim X1() As Integer If c = K then ReDim Out(K) X1 = X For i = 1 To K - 1 n1 = 0 j = 1 ~ N の場合 X1(j)<>0 then n1 = n1 + 1 If n1 = Counter(i) then Out(i) = X1(j) X1(j) = 0 Exit For End If Next txtOut.Text = txtOut.Text & CStr(Out(i)) Next txtOut.Text = txtOut.Text & vbCrLf Else For Counter(c) = Counter(c - 1) To N - c + 1 SochGenerate c + 1 Next End If End Sub

自然数の組み合わせの列挙


多くの実際的な問題を解決するには、単にその数を決定するだけでなく、特定の有限集合の要素から取得できる固定カーディナリティのすべての組み合わせを列挙する必要があります。 有限集合の要素に整数番号を付ける可能性が常に存在することを考慮すると、ほとんどの場合、自然数の組み合わせを列挙するためのアルゴリズムの使用に限定することができます。 その中で最も自然で単純なものは、自然数の組み合わせをリストするアルゴリズムです。 辞書順.


このアルゴリズムを正式に説明するには、主集合 (m 個の要素のすべての組み合わせをリストする必要がある) が 1 から n までの連続した自然数を形成すると仮定すると便利です。 次に、m の任意の組み合わせ

順序付けの結果、このような組み合わせのベクトルの各位置の値は、次のように上下から値が制限されることが当然わかります。



辞書編集アルゴリズムは、辞書編集的に最小のベクトルから開始して、そのような組み合わせのベクトルを順番に生成します。ここで、すべての位置には、インデックスに等しい次の要素の可能な最小値が含まれます。



次の各組み合わせベクトルは、制限値にまだ達していない右端の要素を見つけるために要素を左から右に表示した後、現在のベクトルから形成されます。



そのような要素の値は 1 ずつ増加する必要があります。その右側の各要素には、左側に隣接する要素よりも 1 大きい、可能な限り小さい値が割り当てられる必要があります。 これらの変更後、次の組み合わせベクトルは次の元素構成になります。



したがって、最初の (j1) 要素の値が等しく、位置 j の要素の値が前の要素の値より 1 大きいため、次の組み合わせベクトルは前の組み合わせベクトルよりも辞書的に大きくなります。 。 指定された辞書順の昇順関係は、アルゴリズムのすべての反復で満たされることが保証されます。 その結果、増加する辞書式シーケンスが形成され、これは辞書式上最大の組み合わせベクトルによって完成され、すべての位置の要素が次の最大値を持ちます。



考慮されている辞書編集アルゴリズムは次の例を示しています。ここでは、n=6 個の最初の自然数と m=4 個の数値の 15 個の組み合わせすべて、つまり、主要な生成集合のすべての可能な 4 要素のサブセットを辞書編集順に昇順にリストする必要があります。 1、2、3、4、5、6) 6 つの要素。 計算結果を次の表に示します。

この例では、組み合わせベクトルの位置の数値の最大許容値は、それぞれ 3、4、5、および 6 です。各組み合わせベクトルの結果を解釈する便宜上、右端の要素は、まだ最大値に達している部分には下線が付けられています。 組み合わせベクトルの数値インデックスは、その番号を辞書順に決定します。 一般的な場合、n 要素と m の任意の組み合わせの辞書数 N は、次の公式を使用して計算できます。ここで、見た目上の理由から、組み合わせの数を示すために Appel の記号が使用されます。



特に、辞書順で m=4 による n=6 要素の組み合わせ番号 (1、3、4、6) に対してこの公式を使用した次の計算では、結果 N=8 が得られます。これは、上で説明した例に対応します。



一般に、両方のインデックスの組み合わせ数の合計の恒等式を使用すると、これを使用して計算すると、辞書学的に最小の組み合わせの数 (1, ... i, ... m) が得られることがわかります。式は常に 1 と等しくなります。



また、この式に従って計算した場合の辞書学的に最大の組み合わせ (m, ... nm+i, ... n) の数は、m による n 要素の組み合わせの数に等しいことも明らかです。



組み合わせの辞書順数を計算する公式は、辞書順の番号によって組み合わせベクトルを決定する必要がある逆問題を解くために使用できます。 このような逆問題を解くには、目的の組み合わせのベクトルの要素 (C 1 , ... C i , ... C m) のすべての未知の値が集中する方程式として記述する必要があります。その右辺の組み合わせの数、および組み合わせの数の既知の差 L は、m と目的の組み合わせの数 N によって n 要素の左辺に書き込まれます。



この方程式の解は、次の「貪欲な」アルゴリズムを提供し、その反復において、目的の組み合わせのベクトルの要素の値が順番に選択されます。 最初の反復では、(制限内で) 可能な最小値 C 1 が選択されます。この場合、右辺の最初の項の最大値は L を超えません。



ここで、L の左側は、選択した値 C 1 を使用して右側の最初の組み合わせ数だけ減算され、C 2 の値は 2 回目の反復で同じ方法で決定される必要があります。



同様に、後続のすべての反復を実行して、最後の要素 C m までの、目的の組み合わせの他のすべての要素 C i の値を選択する必要があります。



明らかな理由により、最後の要素 C m の値は、その組み合わせの数と L の左辺の残差値との等しいことに基づいて決定できます。



組み合わせ C m の最後の要素の値は、その可能な値を列挙することなく、さらに簡単に見つけることができることに注意してください。



考慮されているアルゴリズムの反復の実装を次の例で示します。ここでは、n=6 および m=4 の場合、辞書順で数値 N=8 の組み合わせを決定する必要があります。



辞書順で指定された数値の組み合わせを決定するアルゴリズム機能は、さまざまな方向に使用できます。 特に、組み合わせを辞書順にリストする場合、以前に取得した組み合わせへの戻りを提供する必要があり、その番号だけを知るだけで十分です。 さらに、辞書番号の任意の順序を規定する任意の順序で組み合わせを生成することが可能になります。


次に、辞書順に組み合わせを生成するアルゴリズムを示します。


2 for i:= 1 to k do A[i] := i;

5 begin write(A, …, A[k]);

6 A[k] = n の場合、p:= p 1 そうでない場合、p:= k;

8 for i:= k downto p do A[i] := A[p] + i p + 1


要素の繰り返しによる組み合わせ


すべての要素が異なる古典的な組み合わせとは異なり、繰り返しを伴う組み合わせでは、有限セットの要素の順序のない選択が形成されます。この場合、どの要素も無制限に頻繁に出現する可能性があり、必ずしも 1 つのコピーに存在するとは限りません。 同時に、要素の繰り返しの数は通常、組み合わせの長さによってのみ制限され、少なくとも 1 つの要素が異なる組み合わせは異なるものとみなされます。 たとえば、セット 1、2、3 から任意に異なる 4 つの数字を選択すると、次の 15 通りの繰り返しの組み合わせを作成できます。


1111 1112 1113 1122 1123 1133 1222 1223 1233 1333 2222 2223 2233 2333 3333.


一般に、繰り返しのある組み合わせは、任意のタイプの n 個の要素を選択することによって形成できます。 ただし、これらは常に 1 から n までの連続する自然数に関連付けることができます。 次に、この範囲内の m 個の異なる数値の任意の組み合わせを、左から右へ非降順に並べてベクトル形式で記述することができます。



当然のことながら、この形式の記述では、無制限に繰り返すことができるため、隣接する要素はすべて同じになります。 ただし、n 個の要素を m 回繰り返す各組み合わせベクトルは、(n + m − 1) 個の要素を m 回繰り返す組み合わせベクトルに関連付けることができます。これは次のように構成されます。



ベクトル f の要素のどの値についても、ベクトル C の要素は異なることが保証されており、1 から (n+m1) の範囲で値の昇順に厳密に順序付けされていることは明らかです。 :



組み合わせベクトル f と C の要素間には 1 対 1 の対応関係があるため、n 要素を m 回繰り返す組み合わせを体系的に列挙するための次の簡単な方法を提案できます。 たとえば、(n + m1) 個の要素のすべての C の組み合わせを辞書順に m ずつリストし、次の式に従って、それらのそれぞれの要素を繰り返し f を持つ組み合わせの対応する要素に順次変換するだけで済みます。



その結果、要素の繰り返しを伴う組み合わせベクトルのシーケンスが形成され、要素の繰り返しのない対応する組み合わせの列挙によって生成された順序で配置されます。 特に、4 桁の繰り返しを持つ 3 桁の 1、2、3 の組み合わせの上記のシーケンスを取得するには、6 桁の 1、2、3、4、5 の繰り返しを含まないすべての組み合わせを辞書順にリストする必要があります。 6 x 4 桁を指定された方法で変換します。 次の例は、辞書番号 8 と組み合わせ (1,3,4,6) の変換を示しています。



要素の繰り返しのある組み合わせと繰り返しのない組み合わせの間で考慮される 1 対 1 の対応は、それらのセットが同等であることを意味します。 したがって、一般的な場合、m にわたって n 個の要素が繰り返される組み合わせの数は、m にわたって (n + m1) 個の要素が繰り返されない組み合わせの数に等しくなります。 f の繰り返しがある場合と C の繰り返しがない場合の組み合わせの数を示すために同じ記号を使用すると、この等価性は次のように書くことができます。


上記の例では、n=3 および m=4 の場合、繰り返しのある組み合わせの数が 15 になることを確認するのは簡単です。これは、それらを直接列挙した結果と一致します。


古典的なバージョンとは異なり、繰り返し n と m の組み合わせパラメータの値は互いに直接関連していないため、正の値のどの組み合わせでも f(n,m) > 0 であることに注意してください。 対応する境界条件は、値 (n+m1) と (n1) または (n+m1) と m の間の等しいことから決定されます。



また、m が 1 に等しい場合、要素の繰り返しは不可能であるため、n>0 の任意の正の値に対して次の等式が成り立つことも明らかです。


さらに、n と m の任意の正の値の繰り返しを含む組み合わせの数については、次の漸化関係が成り立ちます。これは、要素の繰り返しを持たない組み合わせの数についての加法恒等式と同様です。



実際には、左側と右側の部分で繰り返しを行わずに、対応する数の組み合わせを形式的に置換することで、指定された加算恒等式に変わります。



階乗積を計算する時間のかかる演算を除外し、より単純な加算演算に置き換える必要がある場合、考慮された漸化関係を使用して、繰り返しの組み合わせの数を効果的に決定できます。 同時に、f(n,m) の値を計算するには、f(1,m) と f(i,1) の形式の項の合計が得られるまで、この漸化式を適用するだけで済みます。 i は、n から 1 までの範囲の値をとります。定義により、そのような項はそれぞれ 1 と i に等しくなります。 次の例は、n=3 および m=4 の場合のこの変換手法の使用を示しています。



バイナリの組み合わせの列挙


ハードウェアで組み合わせを実装する場合、またはアセンブリ言語でプログラミングする場合、組み合わせレコードをバイナリ形式で処理できることが重要です。 この場合、n 個の要素と m の組み合わせは、n ビットの 2 進数 (B n 、…B j 、…B 1) の形式で指定する必要があります。ここで、m の 1 桁の数字は組み合わせの要素を示します。残りの (nm) 桁の値はゼロです。 明らかに、この形式の表記法では、組み合わせが異なれば単位の配置も異なるはずで、n ビットのバイナリ セットに m 個の 1 または (nm) 個の 0 を配置するには C (n, m) 通りの方法しかありません。 たとえば、次の表は、任意のセット (E 1 、E 2 、E 3 、E 4 ) の 4 つの要素の 2 によるすべての組み合わせに対して 4 ビット 2 進数を提供する 6 つのバイナリの組み合わせをすべてリストしています。


一般的なケースでは、このようなバイナリの組み合わせを列挙するタスクは、m 個のシングル ビットと (nm) 個のゼロ ビットの異なる配置を持つすべての n ビット バイナリ セットを体系的に列挙することになります。 最も単純な形式では、このような列挙は、シフトを使用して隣接する数字を転置するさまざまな方法 (転置シフト アルゴリズム) によって実装されます。 これらは反復アルゴリズムであり、その名前は各ステップで実行される操作の性質を反映しています。 トランスポジティブ シフト アルゴリズムの反復手順は、バイナリ セットで始まり、すべての 1 が下位ビット (右側) に集中し、すべての 1 が上位ビット (左側) にあるときに終了するバイナリの組み合わせのシーケンスを形成します。



最初と最後の組み合わせで一致するこれらのシーケンスは、中間バイナリ セットの列挙順序が異なります。 ただし、すべての場合において、次のバイナリの組み合わせは、対応する転置演算とシフト演算を実行した結果、前のバイナリの組み合わせに従って形成されます。 同時に、さまざまな転置シフト アルゴリズムは、転置用の 1 対の数字とシフト用の数字のグループの選択方法が異なります。 この特異性は、左シフトと右シフトを伴う転置アルゴリズムに関して以下で考慮されます。


各ステップで左シフトを行う転置アルゴリズムでは、左端のビットのペア 01 を 10 (転置) に置き換え、先頭の単一ビットのグループ (存在する場合) をその近くにシフトすることにより、現在のバイナリの組み合わせから取得されます。転置(シフト)後に得られるペア 10。 この場合、現在のバイナリの組み合わせの最上位ビットに 1 が存在しない場合、たとえこのステップでの転置後に先頭の単位が得られたとしても、シフトは実行されません。 転置後に得られる 10 のペアの前の上位ビットに 0 がない場合も、シフトは実行されません。 考慮されたアクションは、このアルゴリズムの 2 つの連続した反復を実行する次の例で示されています。1 つの反復 (15) では転置 (T") のみが実行され、もう 1 つの反復 (16) では転置がシフトによって補足されます。 (T"+S"):


右シフト転置アルゴリズムでは、概念的に同様のアクションが各ステップで実行されます。 転置によってのみ、01 の右端のビットが (左端のビットではなく) 10 に置き換えられ、その右側にあるすべての単位が下位ビットにシフトされます。 前と同様に、右にシフトできるユニットがある場合にのみシフトが実行されます。 考慮されたアクションは、このアルゴリズムの 2 つの連続した反復の実行の次の例で示されています。1 つの反復 (3) では転置 (T") のみが実行され、もう 1 つの反復 (4) では転置が次のによって補足されます。シフト (T"+S"):

バイナリの組み合わせが基数 2 の整数として解釈される場合、両方のアルゴリズムの反復は加法形式で記述できることに注意してください。特に、右シフトを伴う転置アルゴリズムの場合、次の各バイナリの組み合わせ (B) " n ,…B" j , …B" 1) は、次の加法式を使用して整数加算演算を実行することにより、現在の組み合わせ (B n ,…B j ,…B 1) から常に取得できます。



この加法式では、2 の指数 f と t は、それぞれ、現在の 2 進数の組み合わせの 0 の数と、その左側に連続する 1 の数を示します。 たとえば、n=6 ビットの 4 番目のバイナリの組み合わせ (001110) の場合、f =1 および t =3 です。 したがって、反復 5 での加算式による次の 2 値の組み合わせの計算では、次の結果が得られます。これは、転置演算とシフト演算を実行するのと同じです。



検討中の左シフトと右シフトによる転置アルゴリズムを比較分析するには、反復時に生成されるバイナリの組み合わせのシーケンスを比較することをお勧めします。 次の表は、それぞれ左 (TSL) シフト アルゴリズムと右 (TSR) シフト アルゴリズムによって取得された、4 要素 x 2 のバイナリ組み合わせの 2 つのシーケンスを示しています。

これら 2 つのシーケンスを比較すると、反転ミラーリングであることがわかります。 これは、シーケンスの相互に反対側の端から同じ距離にある 2 つのバイナリの組み合わせが互いに鏡像であること、つまり、それらのいずれかのビットの逆インデックスに変更すると一致することを意味します。 たとえば、TSL シーケンスの先頭から 2 番目のバイナリ パターン (0101) は、TSR シーケンスの最後から 2 番目のバイナリ パターン (1010) の鏡像です。 一般に、あるシーケンスの番号 i を持つバイナリの組み合わせは、別のシーケンスの番号 (ni + 1) を持つバイナリの組み合わせの鏡像になります。 これらのシーケンスのこのような比率は、バイナリの組み合わせを列挙するために考慮された 2 つのアルゴリズムにおける転置とシフトの操作の対称的な性質の結果です。


バイナリ形式は、要素の繰り返しを含む組み合わせを記述するためにも使用できることに注意してください。 これを行うには、繰り返しを含む組み合わせと、次のように構成されるバイナリの組み合わせとの間に 1 対 1 の対応を確立する必要があります。 繰り返しを含む任意の組み合わせがあるとします。これは、生成セットの n 要素から任意に異なる m 個の要素を選択することによって得られます。 目的の対応関係を確立するには、まず生成セットのすべての要素を組み合わせに付加し (cat)、次に、すべての同一の要素が近くになるように結果の連結を並べ替える (sort) 必要があります。 結果は、(n+m) 個の要素のシーケンスになります。ここで、n 個の同一要素のグループが得られます。 要素間には合計 (n+m1) 個のギャップがあり、その中には同一要素のグループ間に (n1) 個のギャップがあり、グループ内の要素間には m 個のギャップがあります。 わかりやすくするために、指定した間隔に文字「|」を配置できます。 そしてそれに応じて。 ここで 1 をグループ間のギャップ (|) にマップし、0 を他のすべてのギャップ () にマップすると、バイナリの組み合わせが得られます。 これは、(n+m1) 桁のバイナリ セットで形成されます。(n1) は 1 と m 個の 0 の桁で、その位置は要素 n から m までの繰り返しによる元の組み合わせに一意に対応します。 考慮されている変換手法は、繰り返しとの組み合わせ (BBD) によってバイナリの組み合わせ (1001101) を構築する次の例で示されています。その要素は、最初の 5 つのラテン文字の生成セットから選択されます。


一般に、このようなバイナリ セットの数によって、(n+m1) 個の 2 進数に (n1) 個の 1 (または m 個の 0) を配置する方法の数が決まります。 この値は明らかに、(n+m1) から (n1) または m を超える組み合わせの数、つまり C(n+m1,n1) または C(n+m1,m) に等しく、 n 個の要素を m 個繰り返す f( n,m) の組み合わせの数。 したがって、繰り返しを含む組み合わせとバイナリの組み合わせの間に 1 対 1 の対応があるため、たとえば、左または右シフトを伴う転置アルゴリズムを使用して、繰り返しを含む組み合わせの列挙をバイナリの組み合わせの列挙に減らすことは正当です。 後は、取得したバイナリの組み合わせから、目的の組み合わせを繰り返して復元するだけです。 これは、次の修復技術を適用することでいつでも行うことができます。


必要に応じて異なる要素を m 回繰り返すことによって要素の組み合わせが形成される主集合を、その各要素が 1 から n までの特定のシリアル番号を持つように任意に順序付けするとします。 (n+m1) 個の 2 進数の 2 進数の組み合わせの列挙も実装します。ここで、(n1) は 1 桁で、m 個のゼロの桁です。 結果として得られる各 2 進数の組み合わせの左側に架空の単位桁を追加することができ、すべての単位桁に 1 から n までの整数を使って左から右に番号を付けることができます。 この場合、バイナリの組み合わせの各 i 番目の単位の後に連続するゼロの数は、繰り返しを含む対応する組み合わせにおけるメイン セットの i 番目の要素のインスタンスの数と等しくなります。 検討されている手法は、次の例で説明されています。バイナリの組み合わせ (1001101) は、BBD の繰り返しを含む組み合わせを復元します。その要素は、アルファベット順に書かれた最初の 5 つのラテン文字の生成セットから選択され、上線は、この組み合わせに存在しない要素は次のとおりです。

この例の条件で同様のアクションを実行すると、4 つの 1 と 3 つのゼロからなる 7 ビット バイナリ セットを形成する 35 個のバイナリの組み合わせをすべてリストし、5 要素 x 3 の繰り返しで対応する組み合わせを復元できます。

冬が近づいていたので、コーマとゴーファーはエンドウ豆を買いだめすることにしました。 一日中、彼らは納屋に走って、いくつかのさやを引きずりました:コーマは4匹、ゴーファーは2匹でした。 夕方までに、彼らは持ってきたすべてのサヤを数え、これらのエンドウ豆を今どのように分割するかを考えました。 コーマは、一度にゴーファーの2倍の量を引きずれば、2倍のエンドウ豆が得られるはずだと主張した。 ゴーファーは、第一に、コーマのスピードがゴーファーよりも著しく遅い、そして第二に、おそらくコーマが逃げたのは一度か二度だけで、残りの時間は何もしていなかったのではないかと、これに合理的に反対しました...

友達がこの困難な状況を理解できるよう、少しでも手伝ってください。 Gopher が持ってきたポッドの数と Homa の数について考えられるすべてのオプションを決定します。

入力データ

最初の行には、偶数の整数 M (盗まれたポッドの数、2 ≤ M ≤ 1000) が含まれています。

出力

Gopher と Khoma によってもたらされるポッドの数のすべての可能な組み合わせ (1 行につき 1 つの組み合わせ)。 各組み合わせはスペースで区切られた 2 つの非負の整数です。最初の数値は Gopher によってもたらされたポッドの数、2 つ目は Homa によってもたらされたポッドの数です。 組み合わせを最初の番号の降順に並べ替えます。

テスト

入力データ 出力
6 \\ 6 \; 0 \\ 2 \; 4
11 \\ 11\;0 \\ 7\;4 \\ 3\;8
18 \\ 18\;0 \\ 14\;4 \\ 10\;8 \\ 6\;12 \\ 2\;16

プログラムコード

#含む

名前空間 std を使用します。

int main()(

int a 、 b = 0 ;

シン >> a ;

while (a >= 0 ) (

コート<< a << " " << b << "\n" ;

a -= 4 ; b += 4 ;

0 を返します。

問題の解決策

Homa が持ってきたポッドの数を a、Gopher が持ってきたポッドの数を b とします。 問題の条件によれば、Khoma が運んだポッドは 4 つだけなので、Gopher と Khoma によってもたらされたポッドの数の考えられるすべての組み合わせを分類するために、a = a-4 および b = b + 4 を考慮します。 ループも使ってます その間\geq 0 になるまで上記のアクションを繰り返します。答えでは、友人が持ち込んだポッドの数の考えられるすべての組み合わせを 1 行に 1 つずつ出力し、最初の数値の降順に並べ替えます。

組み合わせアルゴリズムは非常に頻繁に使用されます。 インターネットでは、組み合わせアルゴリズムに関する多くの情報を見つけることができます。 ただし、ロシア語を話すインターネットは一般に、組み合わせオブジェクトをサイクルで継続的に列挙 (生成) するという最も単純なタスクを発行します。 例えば:

// 52 個中 3 個の組み合わせ for (int i1 = 0; i1< 50; ++i1) for (int i2 = i1+1; i2 < 51; ++i2) for (int i3 = i2+1; i3 < 52; ++i3) // ...

組み合わせインデックス

各組み合わせ、順列、配置、その他の組み合わせオブジェクトはインデックスに関連付けることができます。インデックスは、このアルゴリズムを反復処理するときに表示される番号です。

ここでは、Runet では解決策が見つからなかった、より複雑なタスクを検討します (ただし、1 つのリンクを示しますが、その式は明らかに間違っています) - 組み合わせ自体 (この場合は 3 つのセット) に基づいて数値)そのインデックスを見つけます。

ブルートフォースオプションがあります。 組み合わせカウンターをオンにし、上記のアルゴリズムを使用し、目的のオプションに到達するまですべてを並べ替えます。 このオプションは時間の複雑さが非常に大きいため、このオプションは破棄します。
入力に数値 i1、i2、i3 があるとします。 まず第一に、それらを昇順に並べる必要があります (「組み合わせ」という概念そのものが任意の順序を意味しますが、上記の生成アルゴリズム自体は常に順序付けされた形式で出力することに注意してください)。

明確にするために、i1 = 3、i2 = 7、i3 = 12 を注文した後だとします。
これは、i1 が 0、1、2 に等しいすべての組み合わせを「通過」したことを意味します。
i1 = 0 の場合、インデックス i1、i2 は 51 個の数値のうち 2 つのすべての組み合わせを実行するため、C(2, 51) の組み合わせを実行します。
i1 = 1 の場合、C(2, 50) の組み合わせを実行しました。
i1 = 2 の場合、C(2, 49) の組み合わせを実行しました。
合計で、SUM (n = 0 から n = i1-1) C (2, 51-n) を実行しました。
i1 = 3 の場合、インデックス i2 (i2 = i1+1 = 4 から始まります) を実行する、既に実行した組み合わせを考えてみましょう。
i2 = 4 の場合、C(1, 47) の組み合わせが合格、i2 = 5 の場合、C(1, 46) の組み合わせが合格、i2 = 6 の場合、C(1, 45) の組み合わせが合格。
完全に類推すると、i2 = 7 の場合、インデックス i3 が実行した組み合わせを考慮します。
次の一般式が得られます。
希望する組み合わせインデックス = SUM (n = 0 ~ i1-1) C(2, 51-n) + SUM (n = i1+1 ~ i2-1) C(1, 51-n) + SUM (n より) = i2+1 by i3-1) C(0, 51-n)。

サブセットインデックス

組み合わせ論には、サブセットへの分割という、より複雑なオブジェクトもあります。 たとえば、52 個の要素セットを、それぞれ 2、3、47 個の要素で構成される 3 つのサブセットに分割します。各サブセット内の要素の順序は重要ではありません。 (ちなみに、52 個のうち 2 個の組み合わせは、それぞれ 2 個の要素と 50 個の要素の 2 つのサブセットに分割する特殊なケースにすぎません)。

一般的な生成アルゴリズムでは、52 個のうち 2 個の組み合わせを生成し、ネストされたループ内の各組み合わせについて、50 個のうち 3 個の組み合わせを生成し、ネストされた組み合わせ内のインデックス (i3、i4、i5) が外側の組み合わせのインデックス (i1、i2) と一致しません。

C++ コード

// 外部結合 for (int i1 = 0; i1< 51; ++i1) for (int i2 = i1+1; i2 < 52; ++i2) // ВНУТРЕННЕЕ СОЧЕТАНИЕ for (int i3 = 0; i3 < 50; ++i3) if (i3 != i1 && i3 != i2) for (int i4 = i3+1; i4 < 51; ++i4) if (i4 != i1 && i4 != i2) for (int i5 = i4+1; i5 < 52; ++i5) if (i5 != i1 && i5 != i2) // ...


繰り返しますが、そのような各パーティションには独自のインデックスがあります。
結合インデックスを見つけるためのアルゴリズムを変更して、分割インデックスを見つけることができることがわかりました。
最初の 2 つは関係なく、「外部組み合わせ」i1、i2 のインデックス同士、およびインデックス i3、i4、i5 のインデックス同士を順序付ける必要があることに注意してください。
また、「ネストされた組み合わせ」では、実際には 50 要素のセットを操作していますが、インデックス i3、i4、i5 が以前から変わらないように、特定の方法で「シフト」する必要があることにも注意してください。 0 ~ 51、ただし 0 ~ 49:

C++ コード

if (i3 >= i1) --i3; if (i3 >= i2) --i2; // i4、i5 も同様


(いわば、52 要素セットからインデックス i1、i2 を切り出し、残りのセットをシフトして穴を塞ぎ、インデックス i3 ~ i5 はシフトされます)。
それぞれの「外側」の組み合わせの中に、ちょうど C(3, 50) 個の「ネストされた」組み合わせがあることを考慮する必要があります。
その後、アルゴリズムは次のように簡略化されます。
COMBINATION_INDEX (52 のうちの i1、i2) * COMBINATION_IN_3_FROM_50 + COMBINATION_INDEX (インデックス シフト後の 50 のうちの i3、i4、i5)。

アルゴリズムを常に複雑にする

たとえば、i1 = 0 (n = 0 から -1 までの合計を計算します) または i2 = 1 (1 から 0 までの合計を計算します) の場合、式に「エラー」が発生することにすぐに注意する必要があります。 。 実際、そのような場合、対応する金額はゼロに等しいと見なされ、結果は正しいものになります。
また、アルゴリズムの時間計算量にも注意を払う必要があります。C を定数時間とみなすと、アルゴリズムは線形計算量になります。 これはすでに総当たりよりもはるかに優れています。
でも実は (私たちのケースでは 52) アルゴリズムを一定の複雑さまで減らすことを妨げるものは何もありません。 これを行うために、数学の知識を適用し、すべての合計を分析的に計算します。
たとえば、式の形式で「開く」と、組み合わせの数 C(2, K) K! / ((K-2)! * 2!) は 2 次の多項式に変換されます。 そして、それが和記号の下にあるので、自然数列の数値の N 乗の和の公式を適用して (Wikipedia を参照)、3 次の単一の多項式を取得できます。 これは明らかに一定の時間計算量を持ちます。 (さらに、小見出しの冒頭で私が引用した「間違い」は、いかなる形でも現れず、公式は正しいままです)。
繰り返しますが、これは 基本セットの固定寸法の場合。 ただし、メタプログラミングの助けを借りて、コンパイラーにこの作業を行うように「教える」ことができると確信しています。

インデックスを 2、3、47 で分割するサンプル コード

int get_split_2_3_47_index(int i1, int i2, int i3, int i4, int i5) ( // 52 のうち 2 を C(3, 50) で乗算した組み合わせのインデックス int offset = ((52*51 - (51) -i1) *(52-i1)) / 2 + (i2 - i1 - 1)) * 19600; // (i3 >= i1) の場合、番号付けが 0...49 になるように内部グループを「再インデックス」します - -i3; if (i3 >= i2) --i3;if (i4 >= i1) --i4;if (i4 >= i2) --i4;if (i5 >= i1) --i5;if (i5 >= i2) --i5; // ここで、3 の組み合わせインデックスを追加します // 0: // n = 0 の i3-1 の合計 COMBINATIONS (2, 49-n) // = m = 50-i3 の合計49 (m * (m-1) / 2) オフセット += (19600 - (((49-i3)*(50-i3)*(99-2*i3)) / 6 - ((49-i3)* (50-i3 )) / 2) / 2); // 1: // i4-1 に対する n = i3+1 の合計 組み合わせ (1, 49-n) offset += (((48-i3)*( 49-i3) - (49-i4)*(50-i4)) / 2); // 2: // n = i4+1 over i5-1 (1) オフセット += (i5 - i4 - 1) の合計); オフセットを返します ;)

あとがき

私のポーカー シミュレーター (テキサス ホールデム) では、ハンド カード (2 枚) とすべてのフロップ カード (テーブル上の 3 枚のカード) のすべての可能な組み合わせの勝利確率を事前計算して保存したいと考えていました。これはスプリットに相当します。 52 セットを 2、3、47 のサブセットに分割します。
計算されて保存されます。
しかし、特定の組み合わせについてファイルからデータを読み取る段階になったとき、そこで長時間何かを計算したり、ギガバイトのファイルを検索したりしたくありませんでした。 ここでは、ファイル内のオフセットを決定し、必要なものを直接読み取るだけです。

一般に、組み合わせアルゴリズムを次のクラスに分類します。

  • 単一サイクルでの組み合わせオブジェクトの生成 (ここではすべてが単純で、例を示しました)。
  • 前のオブジェクト (C ++ で表現される、一種の前方/後方イテレータ) を知った上で、次 (または前) の組み合わせオブジェクトに移動します。ここで、一定時間のアルゴリズムを提供する T. I. Fedoryaeva によるチュートリアルに注目してください。順列の複雑さ、およびその他の例は RuNet で見つけることができますが、順列のみですが、他の組み合わせオブジェクトについても同様のアルゴリズムを見るのは興味深いでしょう。
  • オブジェクトのインデックスを検索します。 Fedoryaeva によるマニュアルを除いて、線形複雑さの例はまったくなく、順列のみです。
  • インデックスによるオブジェクトの検索。
順列、組み合わせ、配置、サブセット、繰り返しとの組み合わせ、繰り返しとの配置など、すべての組み合わせオブジェクトの組み合わせアルゴリズムのガイドがあれば興味深いでしょう。

組み合わせ数

組み合わせから nによる kセットと呼ばれる kデータから選ばれた要素 n要素。 要素の順序のみが異なるセット (構成は異なります) は同じとみなされます。これが、組み合わせと配置の違いです。

明示的な式

からの組み合わせの数 nによる k 二項係数に等しい

固定値の場合 nからの繰り返しを含む組み合わせの数の生成関数 nによる kは:

繰り返しのある組み合わせの数の 2 次元の母関数は次のとおりです。

リンク

  • R・スタンレー列挙的な組み合わせ論。 - M.: ミール、1990 年。
  • オンラインで組み合わせ数を計算する

ウィキメディア財団。 2010年。

他の辞書で「組み合わせの数」が何であるかを確認してください。

    70 70 67 68 69 70 71 72 73 40 50 60 70 80 90 100 因数分解: 2×5×7 ローマ字表記: LXX 二進数: 100 0110 ... ウィキペディア

    光の数、外部をユニークに表現する条件付きの数。 撮影時の条件(通常は被写体の明るさや使用される写真材料の感度)。 E.h.の任意の値を複数選択できます。 F値の組み合わせ…… 大きな百科事典のポリテクニック辞典

    単一のオブジェクトと複数のオブジェクトの両方に関して 2 つのオブジェクトを区別する数値の形式。 この形式は現代ロシア語には存在しませんが、その影響の名残は保存されています。 したがって、2 つのテーブルの組み合わせ (cf. 複数形 ... ... 言語用語辞典

    組み合わせ数学、組み合わせ論。特定の、通常は有限の、所定のルールに従って設定された要素の選択と配置の問題を解決することに特化した数学の一分野。 このような各ルールは構築方法を決定します…… 数学百科事典

    組み合わせ論では、 by の組み合わせは、異なる要素を含む特定のセットから選択された要素のセットです。 要素の順序のみが異なる(構成は異なる)セットは同じとみなされ、これらの組み合わせは ... ... ウィキペディア

    何が起こったかは定かではない出来事の研究に取り組んでいます。 これにより、あるイベントの発生を他のイベントと比較して予測することの合理性を判断できますが、イベントの確率に数値を帰すことは多くの場合冗長です... コリアー百科事典

    1) 数学的な組み合わせ分析と同じ。 2) 与えられた有限のオブジェクトのセットから構成できる、特定の条件に従う組み合わせの数の研究に関連する初等数学のセクション ... ... ソビエト大百科事典

    - (ギリシャのパラドクソ、予期せぬ、奇妙) 広い意味: 一般に受け入れられ確立された意見と鋭く対立する声明、「間違いなく正しい」と思われるものの否定。 より狭い意味では、2 つの相反するステートメント、つまり ... ... 哲学事典

    - (または包含の除外の原理) 有限数の有限集合の和集合の累乗を決定できる組み合わせ公式。一般に互いに交差する可能性があります... ウィキペディア

    特定のオブジェクトを既知の順序で配布するさまざまな方法の数を決定することに関係する数学理論。 方程式理論と確率理論において特に重要です。 この種の最も単純なタスクは次のとおりです。 百科事典 F.A. ブロックハウスと I.A. エフロン

  • 英語の教科書。 2部構成。 パート 2、N. A. ボンク、G. A. コティ、N. A. ルキアノバ。 この本は『The English Textbook』の第 2 部です。 20 レッスン、レッスン文法リファレンス、リファレンス文法表で構成されています。 新しい語彙の範囲…