[[20170612232436]] 『スポーツの試合と審判』(mafiruvn542ktx) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『スポーツの試合と審判』(mafiruvn542ktx)

あるスポーツを全部で9チームあります。試合は1チーム対1チームで行うときの対せん表を作りたいと思います。そこで質問です。1チーム3試合で審判は当然試合をしてないチームがやります。コートは2コート。どう組んだらいいですか?エクセルでうまくできますか?

< 使用 Excel:unknown、使用 OS:Windows7 >


間違えました。試合は総当たりです。全部のチームと1試合づつでした。
(mafiruvn542ktx) 2017/06/12(月) 23:32

 4チームが試合中は5チームが余るわけだから、
 手書きでもなんでもできると思いますけど?
 「うまく」とは何を指しているのですか?

(稲葉) 2017/06/13(火) 06:35


mafiruvn542ktxさん

これは、結局1チーム余るのではないでしょうか?
チーム数が9チームで4試合なら組み合わせができると思いますが、
3試合だとどこかが1試合足りないか、多いかしないと組み合わせができない気がします。
証明は難しすぎてできませんが。。。。

(パオ〜〜ン) 2017/06/13(火) 10:29


 パオ〜〜ンさん
 (mafiruvn542ktx)さん 2017/06/12(月) 23:32
 の投稿で「総当たり」って書いてあると思うので、単純に9c2=36通りでいいんでないでしょうか?

(稲葉) 2017/06/13(火) 11:11


Sub main()
    Dim team As Variant, eflg As Boolean, ctr As Integer, i As Integer, j As Integer, x As Integer, y As Integer, c As Range
    team = Array("aチーム", "bチーム", "cチーム", "dチーム", "eチーム", "fチーム", "gチーム", "hチーム", "iチーム") '実際に即して編集
    Do
        Randomize
        eflg = False
        ctr = 0
        Cells.Clear
            For i = 0 To 8
                For j = i + 1 To 8
                    Do
                        x = Int(Rnd * 2) + 1
                        y = Int(Rnd * 18) + 1
                        If Cells(y + 1, x + 1) = "" Then
                            If x = 1 Then
                                If comp(Cells(y + 1, 3).Value, team(i) & "<VS>" & team(j)) Then Cells(y + 1, x + 1) = team(i) & "<VS>" & team(j): eflg = True: Exit Do
                            End If
                            If x = 2 Then
                                If comp(Cells(y + 1, 2).Value, team(i) & "<VS>" & team(j)) Then Cells(y + 1, x + 1) = team(i) & "<VS>" & team(j): eflg = True: Exit Do
                            End If
                        End If
                        ctr = ctr + 1
                        If ctr > 10000 Then Exit Do
                    Loop
                Next j
            Next i
        If WorksheetFunction.CountA(Range("B1:C19")) = 36 Then
            Range("B1").Value = "第1コート"
            Range("C1").Value = "第2コート"
            For Each c In Range("A2:A19")
                c.Value = "第" & c.Row - 1 & "試合"
            Next c
            Exit Do
        End If
    Loop
End Sub

Function comp(arg1, arg2)

    If arg1 = "" Then comp = True: Exit Function
    If Split(arg1, "<VS>")(0) <> Split(arg2, "<VS>")(0) And Split(arg1, "<VS>")(0) <> Split(arg2, "<VS>")(1) And Split(arg1, "<VS>")(1) <> Split(arg2, "<VS>")(0) And Split(arg1, "<VS>")(1) <> Split(arg2, "<VS>")(1) Then comp = True
End Function
(mm) 2017/06/13(火) 13:17

稲葉さん

失礼しました。総当りと訂正されていました。(^^;;;
(パオ〜〜ン) 2017/06/13(火) 13:19


Excelすら使わない、手書きの場合の考え方なぞ。 9チームをA〜Iチームと命名します。
1試合に必要なチームは、A-Bで審判Cのように、3チームで考えます。審判をやる回数も、平等にしたいですよね。2コート同時なので、18試合必要。

まず、1コートに3チーム向かったとして、交代で試合すれば、3試合で総当たりできますよね。これを基本とすると、以下。
ABC DEF GHI (1コート、2コート、無試合ですが、無試合分も同じ規則で並べています)
ACB DFE GIH
BCA EFD IHG

あとはこれをダブらないように並べ変えていくと…。(それぞれの先頭同士とか、1-2-3番目で1セットとか)
ABC DEF
ACB DFE
BCA EFD
ADG CFI
AGD CIF
DGA FIC
BFG CDH
BGF CHD
FGB DHC
GHI AFH
GIH AHF
IHG FHA
AEI BEH
AIE BHE
EIA EHB
BDI CEG
BID CGE
DIB EGC

こんなかんじでいかがでしょうか。
(???) 2017/06/13(火) 13:46


自分で書いておきながら、検算してみると、10〜15試合目でEとHチームが重複していました。これは駄目な例! よくみると、後半9試合で絶対どこかが重複してしまうので、もうちょっと考えないと駄目なようです。
(???) 2017/06/13(火) 13:51

ちょっと調べてみたところ、総当たりを考える場合、「カークマンの組分け」という考え方があるそうです。 これを応用し、10チームの組合せを考え(10チーム目と当たったときは空欄にしてしまう)、それを2コートずつに分けてみたのが以下になります。審判まで含めた巴の考えでいきたかったのですが、なんか数学の法則を発見しそうな難易度に感じたため、諦めました…。

 AB DI
 EH FG
 AC BD
 FI GH
 AD CE
 BF HI
 AE DF
 CG BH
 AF EG
 DH CI
 AG FH
 EI BC
 AH GI
 BE CD
 AI BG
 CF DE
 BI CH
 DG EF

ちなみにこれ、審判の数が足りているならば、2行分同時開催すれば、9日間で終わる組合せです。
(???) 2017/06/13(火) 17:46


そんなに難しく考えなくてもいいような。
例えばこんな感じ。
for i=0 to 8
for j=1 to 4
ans1=(i+j+9)mod9
ans2=(i-j+9)mod9
debug.print ans1 & "/" & ans2
next
next
(日捲り熊五郎) 2017/06/13(火) 18:15

 ???さんの紹介サイト参考にどうすればいいのか考えてたら、もっと簡単なの出てたorz
 せっかく書いたので載せておきます。
    Sub 組み合わせ()
        Dim x(1 To 10)
        Dim m As Long
        Dim buf As String
        Dim ans
        Dim i As Long
        Dim ii As Long
        Dim y As Long
        Dim s As Long

        For i = 1 To UBound(x)
            x(i) = Mid("ABCDEFGHI JKLMNOPQRSTUVWXYZ", i, 1)
        Next i
        With CreateObject("Scripting.Dictionary")
            For ii = 1 To UBound(x) - 1

                '出力部
                .Item(ii & "回目") = ""
                .Item(x(1) & x(2)) = ""
                m = 3
                For y = UBound(x) - 3 To 1 Step -2
                    .Item(x(m) & x(m + y)) = ""
                    m = m + 1
                Next y

                'SWAP
                buf = x(2)
                For s = 2 To UBound(x) - 1
                    x(s) = x(s + 1)
                Next s
                x(UBound(x)) = buf
            Next ii
            ans = .keys
        End With
        Range("A1").Resize(UBound(ans)).Value = Application.Transpose(ans)
    End Sub
(稲葉) 2017/06/13(火) 19:45

日捲り熊五郎さんのコードは秀逸ですね! +1と-1で組むことで、カークマンの組分けの図で説明されていたことが、シンプルにマクロ化されてます。いろいろ応用できそうです。
(???) 2017/06/14(水) 10:06

ちなみに、巴戦で考えてみた、その後の結論なぞ。まず、3コート使って良ければ、以下のように簡単に巴戦が成立します。(12回36試合)
 ABC DEF GHI
 ADG BEH CFI
 AEI BFG CDH
 AFH BDI CEG

しかし、2コートとなると、まず ABC DEF を割り当て、次に残った GHI の相手を考えます。ところが、他の9種の中には、GHIどれかが必ず1つ含まれているのですよ。なので、同時開催できず、18回で36試合することは不可能となります。
移動の事も考えて巴戦重視でいくならば、2コートで12組24試合行い、残りは1コートで12試合が良いのではないかと思います。
(???) 2017/06/14(水) 11:15


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.