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

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

詳細はこちら
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1220閲覧

Python 配列から要素をランダムに抽出し、クラス分けしたときの制約条件の作り方 組み合わせNG

krkr

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1グッド

1クリップ

投稿2020/01/07 02:48

編集2020/01/07 03:24

前提・実現したいこと

ユーザー数人をいくつかのクラスに分けるプログラムを作成しています(今回は19人を3クラスに分けてます)。
random.sampleにより(7人、6人、6人の)3クラスに分けました。

ここで、同じクラスにはしてはいけない組み合わせ、といった制約条件を設けたいと思っているのですが、上手くいきません。
(例:no12はno11と同じクラスにしてはいけない)

また、組み合わせNGの対象となる情報は、ユーザーの情報とした配列の4つ目の要素を使用したいと思っています。([(配列としての)ID、制約条件1、制約条件2、組み合わせNG])

現時点では、すべて組み合わせNGという結果になってしまいます。

pythonは始めたばかりで勉強している最中なのですが、どのように組み合わせNGを表せばいいのか分からず、困っています。
何卒宜しくお願い致します。

該当のソースコード (python)

html

1**[(配列としての)ID、制約条件1、制約条件2、組み合わせNG]** 2import numpy as np 3for z in range(5): 4 import random 5 6**ユーザーの情報の読み込み** 7 no1 = [0,0,1,[1]] 8 no2 = [1,0,0,[2]] 9 no3 = [2,0,1,[3]] 10 no4 = [3,0,0,[4]] 11 no5 = [4,1,0,[5]] 12 no6 = [5,1,0,[6]] 13 no7 = [6,0,0,[7]] 14 no8 = [7,1,0,[8]] 15 no9 = [8,0,0,[9]] 16 no10 = [9,0,1,[10]] 17 no11 = [10,0,0,[11]] 18 no12 = [11,0,0,[12,11]] 19 no13 = [12,0,0,[13,11]] 20 no14 = [13,0,0,[14]] 21 no15 = [14,0,1,[15]] 22 no16 = [15,0,0,[16,3]] 23 no17 = [16,0,0,[17]] 24 no18 = [17,0,0,[18]] 25 no19 = [18,0,0,[19,9]] 26 27**カウントの定義** 28 count2 = 0 29 count3 = 0 30 count4 = 0 31 count5 = 0 32 count6 = 0 33 count7 = 0 34 count8 = 0 35 count9 = 0 36 count10 = 0 37 count11 = 0 38 count12 = 0 39 count13 = 0 40 count14 = 0 41 42**ユーザーの中から、1組に入れる7人をランダムに選ぶ** 43 user = [no1,no2,no3,no4,no5,no6,no7,no8,no9,no10,no11,no12,no13,no14,no15,no16,no17,no18,no19] 44 Class1 = random.sample(user,7) 45 46** ユーザーの中から、1組に入れた人を引く** 47**2人目 ** 48 for i in range(1): 49 if Class1[i][0] < Class1[1][0]: 50 count2 = count2 + 1 51 else: 52 ount2 = count2 53**3人目 ** 54 for i in range(2): 55 if Class1[i][0] < Class1[2][0]: 56 count3 = count3 + 1 57 else: 58 count3 = count3 59**4人目** 60 for i in range(3): 61 if Class1[i][0] < Class1[3][0]: 62 count4 = count4 + 1 63 else : 64 count4 = count4 65**5人目 ** 66 for i in range(4): 67 if Class1[i][0] < Class1[4][0]: 68 count5 = count5 + 1 69 else: 70 count5 = count5 71**6人目** 72 for i in range(5): 73 if Class1[i][0] < Class1[5][0]: 74 count6 = count6 + 1 75 else: 76 count6 = count6 77**7人目** 78 for i in range(6): 79 if Class1[i][0] < Class1[6][0]: 80 count7 = count7 + 1 81 else: 82 count7 = count7 83 84**引く** 85 del user[(Class1[0][0])] 86 del user[(Class1[1][0]) - (count2)] 87 del user[(Class1[2][0]) - (count3)] 88 del user[(Class1[3][0]) - (count4)] 89 del user[(Class1[4][0]) - (count5)] 90 del user[(Class1[5][0]) - (count6)] 91 del user[(Class1[6][0]) - (count7)] 92 93**残りのユーザーの中から、2組に入れる6人をランダムに選ぶ** 94 Class2 = random.sample(user,6) 95 96**ユーザーの中から、2組に入れた人を引く** 97**8人目** 98 for i in range(7): 99 if Class1[i][0] < Class2[0][0]: 100 count8 = count8 + 1 101 else: 102 count8 = count8 1039人目 104 for i in range(7): 105 if Class1[i][0] < Class2[1][0]: 106 count9 = count9 + 1 107 else: 108 count9 = count9 109 for j in range(1): 110 if Class2[j][0] < Class2[1][0]: 111 count9 = count9 + 1 112 else: 113 count9 = count9 114**10人目** 115 for i in range(7): 116 if Class1[i][0] < Class2[2][0]: 117 count10 = count10 + 1 118 else: 119 count10 = count10 120 for j in range(2): 121 if Class2[j][0] < Class2[2][0]: 122 count10 = count10 + 1 123 else: 124 count10 = count10 125**11人目** 126 for i in range(7): 127 if Class1[i][0] < Class2[3][0]: 128 count11 = count11 + 1 129 else: 130 count11 = count11 131 for j in range(3): 132 if Class2[j][0] < Class2[3][0]: 133 count11 = count11 + 1 134 else: 135 count11 = count11 136**12人目** 137 for i in range(7): 138 if Class1[i][0] < Class2[4][0]: 139 count12 = count12 + 1 140 else: 141 count12 = count12 142 for j in range(4): 143 if Class2[j][0] < Class2[4][0]: 144 count12 = count12 + 1 145 else: 146 count12 = count12 147**13人目** 148 for i in range(7): 149 if Class1[i][0] < Class2[5][0]: 150 count13 = count13 + 1 151 else: 152 count13 = count13 153 for j in range(5): 154 if Class2[j][0] < Class2[5][0]: 155 count13 = count13 + 1 156 else: 157 count13 = count13 158 159**引く** 160 del user[(Class2[0][0]) - (count8)] 161 del user[(Class2[1][0]) - (count9)] 162 del user[(Class2[2][0]) - (count10)] 163 del user[(Class2[3][0]) - (count11)] 164 del user[(Class2[4][0]) - (count12)] 165 del user[(Class2[5][0]) - (count13)] 166 167**残りのユーザーの中から、3組に入れる6人をランダムに選ぶ** 168 Class3 = random.sample(user,6) 169 170**各組に入っている人の内訳が、制約条件1が1人以下かつ、制約条件2が2人以下のとき、** 171 if Class1[0][1] + Class1[1][1] + Class1[2][1] + Class1[3][1] + Class1[4][1] + Class1[5][1] + Class1[6][1] < 2 and Class1[0][2] + Class1[1][2] + Class1[2][2] + Class1[3][2] + Class1[4][2] + Class1[5][2] + Class1[6][2] <=2 and Class2[0][1] + Class2[1][1] + Class2[2][1] + Class2[3][1] + Class2[4][1] + Class2[5][1] < 2 and Class2[0][2] + Class2[1][2] + Class2[2][2] + Class2[3][2] + Class2[4][2] + Class2[5][2] <=2 and Class3[0][1] + Class3[1][1] + Class3[2][1] + Class3[3][1] + Class3[4][1] + Class3[5][1] < 2 and Class3[0][2] + Class3[1][2] + Class3[2][2] + Class3[3][2] + Class3[4][2] + Class3[5][2] <=2 : 172 print('OK') 173 174print ('------------------------------') 175# 組み合わせNGがいないか 176 if Class1[0][3] != Class1[1][3] != Class1[2][3] != Class1[3][3] != Class1[4][3] != Class1[5][3] != Class1[6][3] and Class1[0][2] != Class1[1][2] != Class1[2][2] != Class1[3][2] != Class1[4][2] != Class1[5][2] != Class1[6][2] and Class2[0][3] != Class2[1][3] != Class2[2][3] != Class2[3][3] != Class2[4][3] != Class2[5][3] and Class2[0][2] != Class2[1][2] != Class2[2][2] != Class2[3][2] != Class2[4][2] != Class2[5][2] and Class3[0][3] != Class3[1][3] != Class3[2][3] != Class3[3][3] != Class3[4][3] != Class3[5][3] and Class3[0][2] != Class3[1][2] != Class3[2][2] != Class3[3][2] != Class3[4][2] != Class3[5][2]: 177 print('組み合わせはOK') 178 else: 179 print('組み合わせはNG') 180print ('------------------------------') 181 else: 182 print ('NG') 183 184print(Class1) 185print(Class2) 186print(Class3)
JayJ👍を押しています

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

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

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

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

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

YUMA-NAGAO

2020/01/07 02:55

どのようにうまくいかないのかを具体的に教えていただきたいのと、Markdown記法を使って、見やすくしていただきたいです。 よろしくお願いいたします。
krkr

2020/01/07 03:31

ご回答ありがとうございます。 少し修正したのですが、現時点ではどの組み合わせもNGになってしまうため、組み合わせNGの人がいるときのみ、表示したいと思っています。 よろしくお願いいたします。
guest

回答1

0

ベストアンサー

こんな書き方はいかが?

python

1import random 2 3# ユーザーの情報の読み込み 4users = [ 5 (1,0,1,0), 6 (2,0,0,0), 7 (3,0,1,0), 8 (4,0,0,0), 9 (5,1,0,0), 10 (6,1,0,0), 11 (7,0,0,0), 12 (8,1,0,0), 13 (9,0,0,0), 14 (10,0,1,0), 15 (11,0,0,12), 16 (12,0,0,13), 17 (13,0,0,0), 18 (14,0,0,0), 19 (15,0,1,0), 20 (16,0,0,3), 21 (17,0,0,0), 22 (18,0,0,0), 23 (19,0,0,9), 24] 25 26# ユーザーをシャッフルにし、3クラスに分ける 27random.shuffle(users) 28c1 = len(users) * 1 // 3 29c2 = len(users) * 2 // 3 30classes = class1, class2, class3 = users[:c1], users[c1:c2], users[c2:] 31 32# クラス毎に、制約条件1が1人以下かつ、制約条件2が2人以下ならOK 33if all(sum(u[1] for u in c) <= 1 and sum(u[2] for u in c) <= 2 for c in classes): 34 print('OK') 35 # 組み合わせNGのメンバーがクラスにいなければOK 36 if all(all(u[3] != m[0] for m in c) for c in classes for u in c if u[3]): 37 print('組み合わせもOK') 38 else: 39 print('組み合わせはNG') 40else: 41 print('NG') 42 43print(class1) 44print(class2) 45print(class3)

コメントで質問された処理を展開:

python

1def conflict(classes): 2 for class_ in classes: 3 for user in class_: 4 if user[3] != 0: 5 for member in class_: 6 if user[3] == member[0] 7 return True 8 return False

ユーザ追加処理

python

1import random 2 3# ユーザーの情報の読み込み 4users = [ 5 (1,0,1,0), 6 (2,0,0,0), 7 (3,0,1,0), 8 (4,0,0,0), 9 (5,1,0,0), 10 (6,1,0,0), 11 (7,0,0,0), 12 (8,1,0,0), 13 (9,0,0,0), 14 (10,0,1,0), 15 (11,0,0,12), 16 (12,0,0,13), 17 (13,0,0,0), 18 (14,0,0,0), 19 (15,0,1,0), 20 (16,0,0,3), 21 (17,0,0,0), 22 (18,0,0,0), 23 (19,0,0,9), 24] 25no20 = (20, 0, 1, 0) 26users.append(no20) 27 28# ユーザーをシャッフルにし、3クラスに分ける 29random.shuffle(users) 30c1 = len(users) * 1 // 3 31c2 = len(users) * 2 // 3 32classes = class1, class2, class3 = users[:c1], users[c1:c2], users[c2:] 33 34# クラス毎に、制約条件1が1人以下かつ、制約条件2が2人以下ならOK 35if all(sum(u[1] for u in c) <= 1 and sum(u[2] for u in c) <= 2 for c in classes): 36 print('OK') 37 # 組み合わせNGのメンバーがクラスにいなければOK 38 if all(all(u[3] != m[0] for m in c) for c in classes for u in c if u[3]): 39 print('組み合わせもOK') 40 else: 41 print('組み合わせはNG') 42else: 43 print('NG') 44 45print(class1) 46print(class2) 47print(class3)

投稿2020/01/07 03:22

編集2020/01/08 07:12
shiracamus

総合スコア5406

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

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

krkr

2020/01/07 06:13

ご回答ありがとうございます。 コードの簡易化もとても参考になりました。 一つ質問があります。 if all(all(u[3] != m[0] for m in c) for c in classes for u in c if u[3]): この行はどのような意味かを教えて頂きたいです。 よろしくお願いいたします。
shiracamus

2020/01/07 07:49 編集

回答欄に処理を展開した内容を追記しました。 真偽値結果は逆になっています。
krkr

2020/01/08 07:07

処理の展開、ありがとうございます。理解することができました。 もう一つだけよろしいでしょうか。 ここで、新たに20人目のユーザーを加える処理を足してみたのですが、制約条件のところでエラーが出てしまい、解決方法が分からない状態です。 1人増やして出力できるようにすることは可能でしょうか。 --------------------足したコード部分--------------------------- no20 = (19,0,1,0), users.append(u19) --------------------error内容--------------------------- IndexError: tuple index out of range
shiracamus

2020/01/08 07:15 編集

閉じ括弧の後の カンマは不要です。カンマがあるとタプルのタプルになります。 no20 を定義したのに u19 をappendしているのが変です。 先頭要素を0ではない出席番号にしたので、 no20 = (20, 0, 1, 0) にしてください。 >>> (19,0,1,0) (19, 0, 1, 0) >>> (19,0,1,0), ((19, 0, 1, 0),)
shiracamus

2020/01/08 07:13

回答欄にコードを追加しました。
krkr

2020/01/08 07:22

カンマが不要だったのですね。 append内容は間違えてしまいました、申し訳ございません。 出力することが出来ました。丁寧にご回答いただき、誠にありがとうございます。
krkr

2020/01/12 04:31

度々申し訳ございません。 例えば、class1にno13とno15を入れておいて、残りのユーザーから同様にclassに6人(2人は既に確定)、7人、7人と振り分けることは可能でしょうか。
shiracamus

2020/01/12 04:45 編集

no13とno15の制約条件はどう定義したのですか? 「制約条件を満たす配列を作る」ということでしたら、別の問題になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問