少なくともN個の有効な番号を得るために、再生する宝くじのチケットを最小限に抑えます


11

これはかなり複雑ですが、非常に興味深い数学の主題(「問題をカバーする」として知られています)、

そして、それを実装するためにあなたの助けが欲しい。

宝くじゲームを想像してください。各宝くじは、50個の数字(1〜50)から5つの乱数を選択する必要があります。

チケットが当選する確率、または1、2、3、または4個の良い数字を獲得する確率を知るのは非常に簡単です。

また、1、2、3、4個の適切な番号を持つすべてのチケットを「生成」するのは非常に簡単です。

私の質問(およびコードチャレンジ)はこれに関連していますが、少し異なります。

少なくとも 1つのチケットに3つの良い番号が含まれているなど、いくつかの宝くじ(可能な限り少ない数)を購入したい。

チャレンジ

目標は、次のような汎用ソリューションを(プログラムまたは単なる関数として)任意の言語で実装することです。

// Input: 3 prameters
min_lottery_tickets(total_numbers_to_choose_from, how_many_numbers_to_choose, how_many_good_numbers_i_want)

上記の例では、以下を呼び出すだけです:

min_lottery_tickets(50, 5, 3)

プログラムはこの目標を達成するためにプレイするチケットの最小セットを生成します。


例:

 min_lottery_tickets(10, 5, 2)

次のような7つのチケットを出力します。

1   2   3   4   5
5   6   7   8   9
10  1   2   6   7
10  3   4   8   9
3   4   6   7   8
1   2   3   8   9
1   4   9   5   10

そのようなチケットは1から10までの数字のペアをカバーするのに十分だからです。


出力

テキスト、チケットごとに1行、数字の間の表またはスペース


誰が勝ちますか

最も効率的なプログラムが勝ちます(つまり、上記のパラメーターに対して最も少ないチケットを生成するプログラム):

min_lottery_tickets(50, 5, 3)


ありがとう!



4
この質問にはさまざまな説明が必要です。あなたはプログラム、機能、またはそのどちらを望んでいますか?出力形式は重要ですか?番号は1からインデックス付けする必要がありますか、それとも0からインデックス付けできますか?そして、客観的な勝利条件は何ですか?
ピーターテイラー

3
@xemこれは、Math SEにほぼ属します。彼らはおそらく数字はあなたの好意(いくつかのジャックポット数STが存在しないにもかかわらず、それが購入のチケットの価値がある)ではないことをあなたに証明するところ
たけた

2
良い数字は何ですか?
DavidC

2
このようなプログラムで出力されたチケットを実際に買いに行くと、多額のお金を失うことになることは確かです。
マイケルハンプトン

回答:


1

私はそれ最適はないことを知っていますが、ここにnode.jsのコードがあります:

function min_lottery_tickets(total_numbers_to_choose_from, how_many_numbers_to_choose, how_many_good_numbers_i_want) {
    c(function(result) {
        var other = result[result.length - 1];
        while (result.length < how_many_numbers_to_choose) {
            other++;
            var already = false;
            for (var i = 0; i < result.length; i++) {
                if (other === result[i]) {
                    already = true;
                    break;
                }
            }
            if (!already) {
                result.push(other);            
            }
        }
        if (other <= total_numbers_to_choose_from) {
            // Print results
            console.log(result);
        }
    }, total_numbers_to_choose_from, how_many_good_numbers_i_want);
}

function c(next, total_numbers, length, start, results) {
    if (!start) start = 1;
    if (!results) results = [];

    for (var i = start; i <= total_numbers + 1 - length; i++) {
        var resultsNew = results.slice(0);
        resultsNew.push(i);
        if (length > 1) {
            c(next, total_numbers, length - 1, i + 1, resultsNew);
        } else {
            next(resultsNew);
        }
    }
}

結果の例:

> min_lottery_tickets(5, 3, 2)
[ 1, 2, 3 ]
[ 1, 3, 4 ]
[ 1, 4, 5 ]
[ 2, 3, 4 ]
[ 2, 4, 5 ]
[ 3, 4, 5 ]

その他:

> min_lottery_tickets(10, 5, 2)
[ 1, 2, 3, 4, 5 ]
[ 1, 3, 4, 5, 6 ]
[ 1, 4, 5, 6, 7 ]
[ 1, 5, 6, 7, 8 ]
[ 1, 6, 7, 8, 9 ]
[ 1, 7, 8, 9, 10 ]
[ 2, 3, 4, 5, 6 ]
[ 2, 4, 5, 6, 7 ]
[ 2, 5, 6, 7, 8 ]
[ 2, 6, 7, 8, 9 ]
[ 2, 7, 8, 9, 10 ]
[ 3, 4, 5, 6, 7 ]
[ 3, 5, 6, 7, 8 ]
[ 3, 6, 7, 8, 9 ]
[ 3, 7, 8, 9, 10 ]
[ 4, 5, 6, 7, 8 ]
[ 4, 6, 7, 8, 9 ]
[ 4, 7, 8, 9, 10 ]
[ 5, 6, 7, 8, 9 ]
[ 5, 7, 8, 9, 10 ]
[ 6, 7, 8, 9, 10 ]

その他:

> min_lottery_tickets(10, 5, 3)
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 4, 5, 6 ]
[ 1, 2, 5, 6, 7 ]
[ 1, 2, 6, 7, 8 ]
[ 1, 2, 7, 8, 9 ]
[ 1, 2, 8, 9, 10 ]
[ 1, 3, 4, 5, 6 ]
[ 1, 3, 5, 6, 7 ]
[ 1, 3, 6, 7, 8 ]
[ 1, 3, 7, 8, 9 ]
[ 1, 3, 8, 9, 10 ]
[ 1, 4, 5, 6, 7 ]
[ 1, 4, 6, 7, 8 ]
[ 1, 4, 7, 8, 9 ]
[ 1, 4, 8, 9, 10 ]
[ 1, 5, 6, 7, 8 ]
[ 1, 5, 7, 8, 9 ]
[ 1, 5, 8, 9, 10 ]
[ 1, 6, 7, 8, 9 ]
[ 1, 6, 8, 9, 10 ]
[ 1, 7, 8, 9, 10 ]
[ 2, 3, 4, 5, 6 ]
[ 2, 3, 5, 6, 7 ]
[ 2, 3, 6, 7, 8 ]
[ 2, 3, 7, 8, 9 ]
[ 2, 3, 8, 9, 10 ]
[ 2, 4, 5, 6, 7 ]
[ 2, 4, 6, 7, 8 ]
[ 2, 4, 7, 8, 9 ]
[ 2, 4, 8, 9, 10 ]
[ 2, 5, 6, 7, 8 ]
[ 2, 5, 7, 8, 9 ]
[ 2, 5, 8, 9, 10 ]
[ 2, 6, 7, 8, 9 ]
[ 2, 6, 8, 9, 10 ]
[ 2, 7, 8, 9, 10 ]
[ 3, 4, 5, 6, 7 ]
[ 3, 4, 6, 7, 8 ]
[ 3, 4, 7, 8, 9 ]
[ 3, 4, 8, 9, 10 ]
[ 3, 5, 6, 7, 8 ]
[ 3, 5, 7, 8, 9 ]
[ 3, 5, 8, 9, 10 ]
[ 3, 6, 7, 8, 9 ]
[ 3, 6, 8, 9, 10 ]
[ 3, 7, 8, 9, 10 ]
[ 4, 5, 6, 7, 8 ]
[ 4, 5, 7, 8, 9 ]
[ 4, 5, 8, 9, 10 ]
[ 4, 6, 7, 8, 9 ]
[ 4, 6, 8, 9, 10 ]
[ 4, 7, 8, 9, 10 ]
[ 5, 6, 7, 8, 9 ]
[ 5, 6, 8, 9, 10 ]
[ 5, 7, 8, 9, 10 ]
[ 6, 7, 8, 9, 10 ]

1
あなたmin_lottery_tickets(10, 5, 2)はOPよりもはるかに多くのソリューションを生成します。
グルー

@Grooは知っていますが、最適ではないことはわかっていましたが、これは私が持っていた最初の作業バージョンでした;)「冗長な」結果を削除する方法についての提案はありますか
グルーズ

こんにちはGroo、こんにちはgreuze、この最初の試みに感謝します。スコアは21です((10,5,2)に対して21のチケットを生成したため)。ただし、重複した結果を削除する方法がわかりません。そのため、このトピックを作成しました。この仕事をするのに最適なアルゴリズムはどのようなものか、まだ疑問に思っています。
xem 14年

ここではいくつかの良い測定値は被写体には:(1)dip.sun.ac.za/~vuuren/papers/lotery_artikel1oud.pdf、(2)goo.gl/Ex7Woa、(3)google.fr/...
XEM

1
これはNP完全な問題なので、魔法の解決策はないのではないかと心配しています。すべての可能なチケットの計算と、その番号のグループのそれぞれを他のすべてのチケットと比較することにより、冗長な人の排除を「強引に」行う必要があります。それには指数関数的な時間がかかります。
xem 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.