🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

2277閲覧

総組み合わせのアルゴリズム

mermer

総合スコア16

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/10/18 06:45

前提・実現したいこと

pythonで要素を5つもつリストに10をそれぞれ振り分けた総組み合わせを出すアルゴリズムが書けません.
何かお知恵をお貸しいただけないでしょうか?
お恥ずかしながら,私は全くの初心者で今回の問題に最初の一歩もコードが書けておりません.

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

python

1a = [0,0,0,0,0]

ほしい結果:

[10,0,0,0,0]
[9,1,0,0,0]
[9,0,1,0,0]



[8,2,0,0,0]
[8,1,1,0,0]
[8,1,0,1,0]



[0,0,0,1,9]
[0,0,0,0,10]

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

■■■■■■■■■■
の、■の間と、両端に4枚の仕切り板をどこかに入れる問題です(1箇所に何枚入れてもいい)。

||||■■■■■■■■■■
なら
0, 0, 0, 0, 10

■|■■■|■■|■■|■■
なら
1, 3, 2, 2, 2

に対応します。


「仕切り板の位置」をitertools.combinations_with_replacementを使って列挙します。

||||■■■■■■■■■■
なら仕切り板の位置のタプルは
(0, 0, 0, 0)

■|■■■|■■|■■|■■
なら仕切り板ののタプル位置
(1, 4, 6, 8)
です。

python

1from itertools import combinations_with_replacement 2 3result = [] 4for x in combinations_with_replacement(range(11), 4): 5 st = 0 6 seq = [] 7 for i in x: 8 seq.append(i - st) 9 st = i 10 seq.append(10 - i) 11 result.append(seq)

となります。

列挙の順番は順序は逆ですが。


python

1result = [] 2for x in combinations_with_replacement(range(11), 4): 3 result.append([ed - st for st, ed in zip((0,) + x, x + (10,))])

でも。

投稿2019/10/18 07:55

編集2019/10/19 04:47
quickquip

総合スコア11231

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mermer

2019/10/18 09:02

問題を数学的に捉えるいい訓練になりました. 良い回答をありがとうございます.
guest

0

問題はこういうことですか?

  • a + b + c + d + e = 10 となる、a, b, c, d, e (それぞれ >= 0 の整数)の組み合わせを全て出力せよ
  • a, b, c, d, e の値は重複しても構わない

題意から、a,b,c,d,e は、0 ~ 10 の範囲の値しか取り得ません。

ですので、強引な力業としては、

a を 0~10 までループ b を 0~10までループ c を 0~10までループ d を 0 ~10 までループ e = 10-(a+b+c+d) e>=0 かつ e <= 10 なら、a,b,c,d,e を出力

でもできることはできますね。

投稿2019/10/18 07:06

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/18 07:22

総当りして合致したものを拾う。。。コンピュータの得意なやつですねw この問題だと力技って言っちゃうのも分かりますが、ごく普通のアプローチでもあると思います。
tacsheaven

2019/10/18 07:26 編集

中のループの終端は10でなくてもよい、とか、いくつか小技はあるとは思いますが、まあ愚直もよいかと(w
mermer

2019/10/18 09:04

総当たりで合致したものを拾うのは考えていなかったです. 最初からスマートに書こうとするものじゃないですね. 勉強になりました.
guest

0

リストの生成・追加

生成されるリストの順番を考慮しなくてよいのであれば、単純に5重ループを回して全探索すればよいと思います。

python

1lst = [] # 最初に空っぽのリストを作成しておきます 2 3for a in range(0, 11): # aは0~10までループします 4 for b in range(0, 11): # bは0~10までループします 5 for c in range(0, 11): # cは0~10までループします 6 for d in range(0, 11): # dは0~10までループします 7 for e in range(0, 11): # eは0~10までループします 8 if a+b+c+d+e == 10: # 和が10のとき、lstの末尾にリストを追加します 9 lst.append([a, b, c, d, e]) 10 11# 確認のため、lstの中身を一つずつ出力します 12for l in lst: 13 print(l)

output

1[0, 0, 0, 0, 10] 2[0, 0, 0, 1, 9] 3[0, 0, 0, 2, 8] 4[0, 0, 0, 3, 7] 5[0, 0, 0, 4, 6] 6[0, 0, 0, 5, 5] 7[0, 0, 0, 6, 4] 8...

また、eの値は必ずe = 10 - (a+b+c+d)なので、簡単にループをひとつ減らすことができます(計算量を減らして高速化することができます)。

python

1lst = [] # 最初に空っぽのリストを作成しておきます 2 3for a in range(0, 11): 4 for b in range(0, 11): 5 for c in range(0, 11): 6 for d in range(0, 11): 7 e = 10 - (a+b+c+d) 8 if e >= 0: # eが0以上なら、リストに追加する 9 lst.append([a, b, c, d, e]) 10 11 12# 確認のため、lstの中身を一つずつ出力します 13for l in lst: 14 print(l)

#リストのソート
Pythonではリストをソートすることができます。

python

1# 昇順にソート 2lst.sort()

output

1[0, 0, 0, 0, 10] 2[0, 0, 0, 1, 9] 3[0, 0, 0, 2, 8] 4[0, 0, 0, 3, 7] 5[0, 0, 0, 4, 6] 6[0, 0, 0, 5, 5] 7...

質問の並び順の場合、降順にソートすればよいかもしれません。

python

1# 降順にソート 2lst.sort(reverse=True)

output

1[10, 0, 0, 0, 0] 2[9, 1, 0, 0, 0] 3[9, 0, 1, 0, 0] 4[9, 0, 0, 1, 0] 5[9, 0, 0, 0, 1] 6[8, 2, 0, 0, 0] 7[8, 1, 1, 0, 0] 8[8, 1, 0, 1, 0] 9...

投稿2019/10/18 07:36

編集2019/10/18 07:51
takey

総合スコア312

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問