質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

python 組み合わせの数を減らしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,352

score 12

組み合わせの数を減らしたいです.
1から520の数字の中から6つの数字の組み合わせをリストとして入 手したいです.

この方法として

for u in range(1, 521):
    list_num.append(u)
loca_share = []
for i in range(len(list_num)):
    for j in range(i + 1, len(list_num)):
        for k in range(j + 1, len(list_num)):
            for s in range(k + 1, len(list_num)):
                for t in range(s + 1, len(list_num)):
                    for u in range(t + 1, len(list_num)):
                        loca_share.append([list_num[i], list_num[j], list_num[k], list_num[s], list_num[t], list_num[u]])

for u in range(1, 521):
    list_num.append(u)

loca_share=list(itertools.combinations(list_nums,6)

①②の方法を考えたのですが,リストの要素(loca_share)の数が多すぎてパソコンのメモリが不足してしまいます.
リストを分割するなど工夫できることがあれば教えてください.お願いいたします.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hayataka2049

    2019/03/02 06:26

    質問を再編集し、https://teratail.com/tour を参考にコードをシンタックスハイライト・マークダウンの中に入れて綺麗に表示されるようにしてください。

    キャンセル

  • d1205cherish

    2019/03/02 06:37

    すみません.これで大丈夫でしょうか.

    キャンセル

  • tiitoi

    2019/03/02 12:33

    そもそもなぜそのようなことをやりたいと思ったのかという背景を記載いただくと代替案があるかもしれません

    キャンセル

  • wwbQzhMkhhgEmhU

    2019/03/02 12:50

    一応正確な組み合わせの数だけ書いておきますね。
    520C6なので、520!/(520-6)!/6!という計算になります。つまり。。。
    >>> 520 * 519 * 518 * 517 * 516 * 515 / 6 / 5 / 4 / 3 / 2
    26675676287260.0
    >>>
    およそ27兆通りくらいです。
    Python内でストリーミングせずに扱うなら27 * [1要素のバイト数]PB 程度の(仮想)メモリは最低限必要です。
    ファイルに落とすにしても、そのサイズが入るストレージが必要になります。

    キャンセル

回答 3

+5

「組み合わせ」ですね。勘違いして書いていたので修正します。

仮にすべて列挙するとすると、520C6の組み合わせは2.7*10^13通りになります。

520通りの数字を表すのに10bit使ったとして(pythonだともっと要るけど)、組み合わせ一つあたり60bitになります。面倒なので64bit=8byteということにして、2.7*10^13をかけるとおよそ2*10^14 byte = 200テラバイト。メモリどころかHDDにも収まりません。200テラビットあれば表現できなくはないと考えても、かなり困難でしょう。

なので、そういうことをやろうとするのがそもそも間違いということになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+5

仮に処理対象のデータを保管せずにイテレータ等で処理したとしても、
519^6 という数の10進数での桁数は log10(519^6) = 6 × log10(519) ≒ 16.3 です。
だいたい10^16.3回のループが必要ということ。
仮に1秒間に1000万件処理できたとして、かかる時間は 519^6 / 10^7 ≒ 10^16.3 / 10^7 = 10^9.3 秒です。
1日が86400秒でこれを簡単に10^5としても、10^4.3日=50年以上かかります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/02 09:50

    こういう計算はどっかで間違ってないかいつも不安……

    キャンセル

  • 2019/03/02 15:10

    あ、ちゃんと読んでなかったな。組み合わせですね。

    キャンセル

checkベストアンサー

+2

本当に組合わせの一覧全部がほしいのでしょうか?

組合わせ一一覧に個数なら python で 520 ** 6 とすれば 19770609664000000 が得られます。

これの 1 番目は [1,1,1,1,1,1], 最後は [520,520,520,520,520,520] です。
i 番目は 
[ (i / (520 ** 5)) % 520 + 1, (i / (520 ** 4)) % 520 + 1, (i / (520 ** 3)) % 520 + 1, 
(i / (520 ** 2)) % 520 + 1, (i / 520) % 520 + 1, i % 520 + 1] 
で得られます。

[a,b,c,d,e,f] が何番目かは 
(a - 1) * 520**5 + (b - 1) * 520**4 + (c - 1) * 520**3 + (d - 1) * 520**2 + (e - 1) * 520 + f
で得られます。

どんな処理をしたいのかを提示すると、一覧全体無しで処理する方法が回答として得られると思います。

注:
半角 ** は うまく表示されない(強調表示に解釈されてしまう) ので、 全角**で書き直しました。

追記

import itertools

# [1, 2, 3, 4] から3つを撰ぶ順列一覧で idx 番目の順列を求める                                                     
for idx in range(24):
    nums = [1, 2, 3, 4]

    a = nums[idx // 6]
    nums.remove(a)
    b = nums[idx % 6 // 3]
    nums.remove(b)
    c = nums[idx % 2]

    print("{:2d}: {}".format(idx, [a, b, c]))

# [a, b, c] が [1, 2, 3, 4] から 3 つを撰ぶ順列一覧で何番目かを求める                                        
for x in itertools.permutations([1, 2, 3, 4], 3):
    nums = [1, 2, 3, 4]

    a = nums.index(x[0])
    nums.remove(x[0])
    b = nums.index(x[1])
    nums.remove(x[1])
    c = nums.index(x[2])
    print("{}:  {:2d}:".format(x, a * 6 + b * 2 + c))


イメージ説明
イメージ説明

追記
組合せの場合を示します。
eee.py

import itertools

nums = [1, 2, 3, 4]
# [1, 2, 3, 4] から3つを撰ぶ組合せ一覧で idx 番目の組合せを求める                                                 
for idx in range(4**3):
    print("{:2d}: {}".format(
        idx, [nums[idx // (4 * 4)], nums[(idx // 4) % 4], nums[idx % 4]]))

# [a, b, c] が [1, 2, 3, 4] から 3 つを撰ぶ組合せ一覧で何番目かを求める                                            
for a in nums:
    for b in nums:
        for c in nums:
            print("{}:  {:2d}:".format(
                [a, b, c], ((a - 1) * 4 + (b - 1) ) * 4 + (c - 1)))


イメージ説明
イメージ説明
イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/04 09:34

    追記ありがとうございます.順列でなく組み合わせの場合を知りたいです.

    キャンセル

  • 2019/03/04 12:21

    何度もすみません.

    キャンセル

  • 2019/03/04 21:24

    組み合わせの場合を回答に追記しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る