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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Python

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

Q&A

解決済

3回答

1128閲覧

トーナメントの全ての組み合わせについて

Lycoris

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Python

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

1グッド

0クリップ

投稿2020/06/04 16:16

編集2020/06/05 07:34

8人トーナメントでの全ての組み合わせを出力したいのですが、いいアイデアが思いつきません。順列から徐々に減らしていこうとも思いましたが、非効率だなと思いました。総数は315であることはわかっています。pythonかc言語で回答してくださると嬉しいです。よろしくお願いします。
追記

python

1import itertools 2i=0 3list2=[] 4list3=[] 5list4=[] 6list5=[] 7list6=[] 8l = [1,2,3,4] 9list1=list(itertools.permutations(l,4)) 10#print(list1) 11print() 12 13for i in range(24): 14 list2+=[[list1[i][:2],list1[i][2:4]]] 15#print(list2) 16print() 17 18for k in range(24): 19 for l in range(2): 20 list3+=sorted(list2[k][l]) 21#print(list3) 22print() 23 24for n in range(0,24*4-3,4): 25 list4+=[((list3[n],list3[n+1]),(list3[n+2],list3[n+3]))] 26#print(list4) 27print() 28 29for m in range(24): 30 list5+=sorted(list4[m]) 31#print(list5) 32print() 33 34for o in range(0,45,2): 35 list6+=[(list5[o],list5[o+1])] 36#print(list6) 37set(list6)

python

1import itertools 2list2=[] 3list3=[] 4list4=[] 5list5=[] 6list6=[] 7list7=[] 8list8=[] 9list9=[] 10list10=[] 11list11=[] 12list12=[] 13a = [1,2,3,4,5,6,7,8] 14list1=list(itertools.permutations(a,8)) 15#print(list1) 16print() 17 18for i in range(40320): 19 list2+=[[list1[i][:4],list1[i][4:8]]] 20#print(list2) 21print() 22 23for k in range(40320): 24 for l in range(2): 25 list3+=[[list2[k][l][:2],list2[k][l][2:4]]] 26#print(list3) 27 28for s in range(80640): 29 for t in range(2): 30 list4+=sorted(list3[s][t]) 31#print(list4) 32 33for x in range(0,40320*8-7,8): 34 list5+=[([(list4[x],list4[x+1]),(list4[x+2],list4[x+3])],[(list4[x+4],list4[x+5]),(list4[x+6],list4[x+7])])] 35#print(list5) 36 37for p in range(40320): 38 for q in range(2): 39 list6+=sorted(list5[p][q]) 40#print(list6) 41 42for g in range(0,40320*4-3,4): 43 list7+=[(list6[g],list6[g+1]),(list6[g+2],list6[g+3])] 44#print(list7) 45 46for s in range(40320*2): 47 for t in range(2): 48 for u in range(2): 49 list8+=[list7[s][t][u]] 50#print(list8) 51 52for y in range(0,40320*8-7,8): 53 list9+=[((list8[y],list8[y+1],list8[y+2],list8[y+3]),(list8[y+4],list8[y+5],list8[y+6],list8[y+7]))] 54#print(list9) 55 56for h in range(40320): 57 list10+=sorted(list9[h]) 58#print(list10) 59 60for s in range(40320*2): 61 for t in range(4): 62 list11+=[list10[s][t]] 63#print(list11) 64 65for z in range(0,40320*8-7,8): 66 list12+=[((list11[z],list11[z+1]),(list11[z+2],list11[z+3]),(list11[z+4],list11[z+5]),(list11[z+6],list11[z+7]))] 67#print(list12) 68set(list12)

一応プログラムとしては4人の場合を考えて、無理やり8人に変えたのを製作しています。しかし、あまりにも無理やりで汚すぎたので、投稿してみました。

退会済みユーザー👍を押しています

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

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

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

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

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

dodox86

2020/06/04 17:01

質問者さんが思い付いたアイデアについて、「良い/悪い」、「効率的/非効率的」は置いておいて、まずはとにかく目的のものを作ってみてはいかがでしょうか。「このように作って動いていますが、こういう問題がでました。」とのような質問になれば丸投げにもならず、また、回答もあろうかと思います。
Lycoris

2020/06/05 10:21

自分で考えたプログラムが無理やり過ぎたので、質問してみました。
dodox86

2020/06/05 10:28

質問への追記、ありがとうございます。既にご自分のプログラムも追記で提示され、複数の回答もいただいているのでよろしいのではないかと思います。
guest

回答3

0

ベストアンサー

こんにちは

以下のように、トーナメント参加者を、A から H とします。

イメージ説明

上記のような場合を,リスト ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] で表すとします。

トーナメントの組み合わせを表すリストを、すべて列挙するコードの一例は以下です。(最後に、組み合わせの数も出力しています。)

python

1import itertools 2 3 4def get_matches(four_players): 5 matches = [] 6 for x in four_players[1:]: 7 m1 = [four_players[0], x] 8 m2 = [y for y in four_players[1:] if y != x] 9 matches.append([*m1, *m2]) 10 11 return matches 12 13 14if __name__ == '__main__': 15 16 players = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 17 18 count = 0 19 20 for block1 in itertools.combinations(players[1:], 3): 21 matches1 = get_matches(['A', *block1]) 22 23 block2 = [x for x in players[1:] if x not in block1] 24 matches2 = get_matches(block2) 25 26 for tournament in itertools.product(matches1, matches2): 27 print(sum(tournament, [])) 28 count += 1 29 30 print(count) 31

考え方としては、まず、「A は、一番左に置くことにする」と決めると分かりやすいです。

単にトーナメントの組み合わせの数を求めるのであれば、以下で算出できます。

python

1from scipy.special import comb 2 3result = comb(7, 3, exact=True) * comb(3, 1, exact=True) ** 2 4 5print(result) # => 315

追記

リストを回転させる関数 rotate

python

1def rotate(l, n): 2 return l[n:] + l[:n]

を作っておくと、 get_matches は以下のようにも書けます。

python

1def get_matches(four_players): 2 car, *cdr = four_players 3 return [[car, *rotate(cdr, i)] for i in range(len(cdr))]

投稿2020/06/05 00:38

編集2020/06/05 09:02
jun68ykt

総合スコア9058

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

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

Lycoris

2020/06/06 00:18

きれいで、丁寧な回答ありがとうございます。 一番に回答していただいたのでベストアンサーにさせていただきます。
jun68ykt

2020/06/06 01:12

どういたしまして???? 参考になれば幸いです。
guest

0

pythonかc言語

当方,pythonができない&順列の列挙処理をCで書くのが辛い → のでC++,
且つ,効率度外視のひどいアルゴリズムですが…

C++

1int main(void) 2{ 3 //※8人を表す値:それぞれが異なるbitが立っている値. 4 unsigned char Vals[] = { 1,2,4,8, 16,32,64,128 }; 5 6 //※関数Outputは Vals の状態に対応した出力を行う 7 Output( Vals ); //初期状態を出力 8 unsigned int N = 1; //※一応カウントしてみる用 9 10 //順列列挙ループ 11 while( std::next_permutation( std::begin(Vals), std::end(Vals) ) ) 12 {//条件:枝分かれ箇所の左側にいる人達の値の合計が,右側の人達の値の合計よりも小さいこと 13 //1回戦の段の判定 14 if( Vals[0] > Vals[1] )continue; 15 if( Vals[2] > Vals[3] )continue; 16 if( Vals[4] > Vals[5] )continue; 17 if( Vals[6] > Vals[7] )continue; 18 //2回戦の段の判定 19 if( (Vals[0]|Vals[1]) > (Vals[2]|Vals[3]) )continue; 20 if( (Vals[4]|Vals[5]) > (Vals[6]|Vals[7]) )continue; 21 //3回戦の段の判定 22 if( (Vals[0]|Vals[1]|Vals[2]|Vals[3]) > (Vals[4]|Vals[5]|Vals[6]|Vals[7]) )continue; 23 24 //ここまできたら,この並び順が新しいパターンである 25 Output( Vals ); //出力 26 ++N; //カウントアップ 27 } 28 std::cout << N; //※カウンタの値を見てみる. 315 と表示される 29 return 0; 30}

とりあえず
while( std::next_permutation( std::begin(Vals), std::end(Vals) ) )
の一文を除いては,Cだと思って見てもらえば,処理内容はわかるかと.
この一文は順列の列挙処理で,
「配列Valsの要素の並び順を,次の並び順に更新する」(次が無い時点でループを終了)
をやっています.

投稿2020/06/05 09:43

編集2020/06/05 10:26
fana

総合スコア11996

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

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

Lycoris

2020/06/06 00:15

このような考え方でもできるんですね。 ベストアンサーにしたいのですが、今回は最初に回答してくれた方をベストアンサーにさせてもらいます。回答ありがとうございました。
guest

0

単純に、8つを総当りで組み合わせを出し、重複がないのを確認するというコードを組んでみてください。

効率や良し悪しは、それからのおはなしとなります

投稿2020/06/05 00:39

y_waiwai

総合スコア88042

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

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

Lycoris

2020/06/05 10:19

それも考えたのですが、どうやって左端のトーナメントで試合した組み合わせに含むチームを隣の山で除外すれば良いのかがわかりませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問