pythonで例えば
リストの各要素の上限が決まっており,その中にnを振り分ける方法はどのようにすればよいのでしょうか.
例:
python
1max = [0,5,4,3,4,1] 2n = 10
#リストの要素の総和がnになるような組み合わせ [0,5,4,1,0,0] [0,5,4,0,1,0] [0,5,4,0,0,1] … [0,0,2,3,4,1]
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/11 01:56
2019/11/11 02:05 編集
2019/11/11 02:09 編集
2019/11/11 02:14
回答4件
0
ベストアンサー
データサイズにもよりますが再起呼び出しを使えばいいんではないでしょうか
Python
1def f(res, max_array, n, work_array): 2 3 i = len(work_array) 4 s = sum(work_array) 5 6 # 組み合わせ配列の長さが最大値配列の長さに達したか? 7 if (i == len(max_array)): 8 # 組み合わせ配列の合計は目的の値か? 9 if s == n: 10 # 組み合わせ配列を結果用配列に追加 11 res.append(work_array) 12 else: 13 # 残りの数値または対象要素の数値の小さいほうでループ 14 for v in range(min(max_array[i], n-s)+1): 15 w = work_array[:] 16 # 選択した値を組み合わせ配列に追加する 17 w.append(v) 18 # 再起呼び出し 19 f(res, max_array, n, w) 20 21 22max_array = [0,5,4,3,4,1] 23n = 10 24 25res = [] 26work_array = [] 27 28f(res, max_array, n, work_array) 29 30 31for _ in res: 32 print(_)
投稿2019/11/10 11:10
総合スコア1627
0
この程度のループなら、全組み合わせ(product)を生成してから、合計10のものだけにする(filter)という方針でもいいような気がします。
参考程度にどうぞ。
python
1m = [0,5,4,3,4,1] # max は変数名として使うべきではないので 2n = 10 3 4from itertools import product 5 6range_argments = [x + 1 for x in m] # => [1, 6, 5, 4, 5, 2] 7answer = list(filter(lambda x: sum(x) == 10, product(*map(range, range_argments)))) 8 9print(answer)
plain
1[(0, 0, 2, 3, 4, 1), (0, 0, 3, 2, 4, 1), (0, 0, 3, 3, 3, 1), (0, 0, 3, 3, 4, 0), (0, 0, 4, 1, 4, 1), (0, 0, 4, 2, 3, 1), 2 (0, 0, 4, 2, 4, 0), (0, 0, 4, 3, 2, 1), (0, 0, 4, 3, 3, 0), (0, 1, 1, 3, 4, 1), (0, 1, 2, 2, 4, 1), (0, 1, 2, 3, 3, 1), 3 (0, 1, 2, 3, 4, 0), (0, 1, 3, 1, 4, 1), (0, 1, 3, 2, 3, 1), (0, 1, 3, 2, 4, 0), (0, 1, 3, 3, 2, 1), (0, 1, 3, 3, 3, 0), 4 (0, 1, 4, 0, 4, 1), (0, 1, 4, 1, 3, 1), (0, 1, 4, 1, 4, 0), (0, 1, 4, 2, 2, 1), (0, 1, 4, 2, 3, 0), (0, 1, 4, 3, 1, 1), 5 (0, 1, 4, 3, 2, 0), (0, 2, 0, 3, 4, 1), (0, 2, 1, 2, 4, 1), (0, 2, 1, 3, 3, 1), (0, 2, 1, 3, 4, 0), (0, 2, 2, 1, 4, 1), 6 (0, 2, 2, 2, 3, 1), (0, 2, 2, 2, 4, 0), (0, 2, 2, 3, 2, 1), (0, 2, 2, 3, 3, 0), (0, 2, 3, 0, 4, 1), (0, 2, 3, 1, 3, 1), 7 (0, 2, 3, 1, 4, 0), (0, 2, 3, 2, 2, 1), (0, 2, 3, 2, 3, 0), (0, 2, 3, 3, 1, 1), (0, 2, 3, 3, 2, 0), (0, 2, 4, 0, 3, 1), 8 (0, 2, 4, 0, 4, 0), (0, 2, 4, 1, 2, 1), (0, 2, 4, 1, 3, 0), (0, 2, 4, 2, 1, 1), (0, 2, 4, 2, 2, 0), (0, 2, 4, 3, 0, 1), 9 (0, 2, 4, 3, 1, 0), (0, 3, 0, 2, 4, 1), (0, 3, 0, 3, 3, 1), (0, 3, 0, 3, 4, 0), (0, 3, 1, 1, 4, 1), (0, 3, 1, 2, 3, 1), 10 (0, 3, 1, 2, 4, 0), (0, 3, 1, 3, 2, 1), (0, 3, 1, 3, 3, 0), (0, 3, 2, 0, 4, 1), (0, 3, 2, 1, 3, 1), (0, 3, 2, 1, 4, 0), 11 (0, 3, 2, 2, 2, 1), (0, 3, 2, 2, 3, 0), (0, 3, 2, 3, 1, 1), (0, 3, 2, 3, 2, 0), (0, 3, 3, 0, 3, 1), (0, 3, 3, 0, 4, 0), 12 (0, 3, 3, 1, 2, 1), (0, 3, 3, 1, 3, 0), (0, 3, 3, 2, 1, 1), (0, 3, 3, 2, 2, 0), (0, 3, 3, 3, 0, 1), (0, 3, 3, 3, 1, 0), 13 (0, 3, 4, 0, 2, 1), (0, 3, 4, 0, 3, 0), (0, 3, 4, 1, 1, 1), (0, 3, 4, 1, 2, 0), (0, 3, 4, 2, 0, 1), (0, 3, 4, 2, 1, 0), 14 (0, 3, 4, 3, 0, 0), (0, 4, 0, 1, 4, 1), (0, 4, 0, 2, 3, 1), (0, 4, 0, 2, 4, 0), (0, 4, 0, 3, 2, 1), (0, 4, 0, 3, 3, 0), 15 (0, 4, 1, 0, 4, 1), (0, 4, 1, 1, 3, 1), (0, 4, 1, 1, 4, 0), (0, 4, 1, 2, 2, 1), (0, 4, 1, 2, 3, 0), (0, 4, 1, 3, 1, 1), 16 (0, 4, 1, 3, 2, 0), (0, 4, 2, 0, 3, 1), (0, 4, 2, 0, 4, 0), (0, 4, 2, 1, 2, 1), (0, 4, 2, 1, 3, 0), (0, 4, 2, 2, 1, 1), 17 (0, 4, 2, 2, 2, 0), (0, 4, 2, 3, 0, 1), (0, 4, 2, 3, 1, 0), (0, 4, 3, 0, 2, 1), (0, 4, 3, 0, 3, 0), (0, 4, 3, 1, 1, 1), 18 (0, 4, 3, 1, 2, 0), (0, 4, 3, 2, 0, 1), (0, 4, 3, 2, 1, 0), (0, 4, 3, 3, 0, 0), (0, 4, 4, 0, 1, 1), (0, 4, 4, 0, 2, 0), 19 (0, 4, 4, 1, 0, 1), (0, 4, 4, 1, 1, 0), (0, 4, 4, 2, 0, 0), (0, 5, 0, 0, 4, 1), (0, 5, 0, 1, 3, 1), (0, 5, 0, 1, 4, 0), 20 (0, 5, 0, 2, 2, 1), (0, 5, 0, 2, 3, 0), (0, 5, 0, 3, 1, 1), (0, 5, 0, 3, 2, 0), (0, 5, 1, 0, 3, 1), (0, 5, 1, 0, 4, 0), 21 (0, 5, 1, 1, 2, 1), (0, 5, 1, 1, 3, 0), (0, 5, 1, 2, 1, 1), (0, 5, 1, 2, 2, 0), (0, 5, 1, 3, 0, 1), (0, 5, 1, 3, 1, 0), 22 (0, 5, 2, 0, 2, 1), (0, 5, 2, 0, 3, 0), (0, 5, 2, 1, 1, 1), (0, 5, 2, 1, 2, 0), (0, 5, 2, 2, 0, 1), (0, 5, 2, 2, 1, 0), 23 (0, 5, 2, 3, 0, 0), (0, 5, 3, 0, 1, 1), (0, 5, 3, 0, 2, 0), (0, 5, 3, 1, 0, 1), (0, 5, 3, 1, 1, 0), (0, 5, 3, 2, 0, 0), 24 (0, 5, 4, 0, 0, 1), (0, 5, 4, 0, 1, 0), (0, 5, 4, 1, 0, 0)]
投稿2019/11/11 02:28
編集2019/11/11 03:40総合スコア11231
0
リストの先頭要素から順に1つずつ計算する方式で作ってみました。
n=10くらいであれば、十分高速に動作すると思います。
python
1def solve(n, limits): 2 stack = [(n, sum(limits), [])] 3 ans = [] 4 while stack: 5 rem, t, picks = stack.pop() # 合計でnにするために必要な残り、 実現可能な最大値、 これまで選択した数値のリスト 6 if len(picks) == len(limits) - 1: 7 if 0 <= rem <= limits[-1]: 8 ans.append(picks + [rem]) 9 else: 10 for i in range(max(rem-t, 0), min(rem+1, limits[len(picks)]+1)): 11 stack.append((rem-i, t-limits[len(picks)], picks + [i])) 12 return ans 13 14 15limits = [0, 5, 4, 3, 4, 1] 16n = 10 17 18ans = solve(n, limits) 19print(*ans, sep='\n') 20print(len(ans)) # 141通り
投稿2019/11/10 12:16
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
1. 配列a[]の要素数をsとして 2. N > 0 である間: 3. i=0~s-1の乱数 3. a[i] が上限に満たなければ: a[i] += 1 N -= 1
...と、こんなんでいかがでしょ。
投稿2019/11/10 11:27
編集2019/11/10 11:30総合スコア16612
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。