2009-06-24 17 views
7

このトピックは複雑で、おそらく簡単な答えではないことを理解しています。それが簡単だったら誰もがやっているだろう。それは言っている...スポーツリーグスケジュールを自動的に生成する方法

私はスポーツリーグを管理するためのアプリケーションを構築するように求められてきました。このコンセプトの大半は、重複がない場所(チームは2つのチームを一度に演じる)でスケジュールを生成する方法です。部門内のチームはチームを2回プレイしますが、 (各チームは毎週演奏します)

このプロセスは、私がこの目的に役立つように構築したrosetta stoneタイプのスプレッドシートを使用して手動で行われますが、それはそれが設計されたチームの数のためにのみ動作します。私は30チーム、24チーム、28チームのバリエーションを持っています。翻訳テーブルの再調整を継続的に試みるのではなく、その論理を体系化して、そのプロセスを調整することができるようにしたいと考えています。

思考?

答えて

10

非常に単純なシステムが使用されています。ラウンドロビンと呼ばれるチェストーナメント。

考え方は、プレーヤーをテーブルの両側に分けることです。選手の一人が「ハブ」として指定されています。トーナメントは、互いに向かい合っているプレーヤー同士が対戦することから始まります。最初のラウンドの後、ハブを除くすべての人が1つのチェアを前方に移動させ、白/黒(スポーツ/自宅)を切り替える。全ラウンドロビン競技は、プレイヤーが元の場所に座ったときに終了します。みんなが二度プレーするようにしたいのなら、同じことをやり直してください。

Wikipedia article実装の詳細。

あなたの特別なケースでは、すべてのチームを含むラウンドロビンを1回試してみます。その後、各部門で同じことを行い、部門内のチームが自宅で一度離れてプレーできるようにするために、最初のラウンドロビンからチームがそのラウンドでどのようにプレーしたかを確認します。

最後のn-1試合は、部門内チームとの対戦であるため、間違いなくすべての試合間試合が行われます(n =チーム内のチーム数分割])。これが問題であれば、単純にマッチを少しでも入れ替えることができます。

私は実際にこれを行う単純なPythonスクリプトを書いていました。それは多くのコード行を取っておらず、かなり良い結果を出しました。これにより、各チームがそれぞれの部門で2回、他の部門のチームと1回ずつ行われるスケジュールが作成されます。チームが同じチームが自宅にいるように2回お互いに会うことを確認するチェックはありません。しかし、このコードは、独自のスケジューリングコードを作成する方法についての良いアイデアを与える必要があります。

#!/usr/bin/python 

div1 = ["Lions", "Tigers", "Jaguars", "Cougars"] 
div2 = ["Whales", "Sharks", "Piranhas", "Alligators"] 
div3 = ["Cubs", "Kittens", "Puppies", "Calfs"] 

def create_schedule(list): 
    """ Create a schedule for the teams in the list and return it""" 
    s = [] 

    if len(list) % 2 == 1: list = list + ["BYE"] 

    for i in range(len(list)-1): 

     mid = int(len(list)/2) 
     l1 = list[:mid] 
     l2 = list[mid:] 
     l2.reverse()  

     # Switch sides after each round 
     if(i % 2 == 1): 
      s = s + [ zip(l1, l2) ] 
     else: 
      s = s + [ zip(l2, l1) ] 

     list.insert(1, list.pop()) 

    return s 


def main(): 
    for round in create_schedule(div1): 
     for match in round: 
      print match[0] + " - " + match[1] 
    print 
    for round in create_schedule(div2): 
     for match in round: 
      print match[0] + " - " + match[1] 
    print 
    for round in create_schedule(div3): 
     for match in round: 
      print match[0] + " - " + match[1] 
    print 
    for round in create_schedule(div1+div2+div3): 
     for match in round: 
      print match[0] + " - " + match[1] 
     print 

if __name__ == "__main__": 
    main() 
2

私はちょうどブール式としてこれらの制約をコード化し、解決策を得るために、いくつかのSATソルバーを使用する(C++、Java用SAT4Jため、例えばにおいてMiniSAT、そしてあなたも、あなたは簡単なソルバを所有して書くことができる)でしょう。これらのソルバへの入力は、DIMACSによって標準化されています。

類似の問題のSATエンコーディングについては、「ソーシャルゴルファー問題のSATエンコーディング」および「トーナメントスケジュールのSATベーススケジューラー」も参照してください。

2

ここで私は紙の上が、それは動作します私のセットアップのためにそれをテストしてみただけ実装

public interface ITeam 
{ 
    bool PlaysOn(DateTime date); 
    bool canPlay(ITeam); //returns true if a game between the teams is legal (played once/twice 
         //already, same different divisions and other applicable rules 
} 

IEnumerable<ITeam> teams = null; //replace with initialization 
IEnumerable<ITeams> reversed = team.Reverse(); 
IEnumerable<DateTIme> gameDays = null;//replace with initialization 
var count = teams.Count(); 

foreach(var date in gameDays) 
{ 
    for(int i = 0;i<count;i++) 
    { 
     var innerTeams = i % 2 == 0 ? teams : reversed; 
     var team = (from t in innerTeams 
        where !t.PlaysOn(date) 
        select t).First(); 
     var opp = (from t in teams 
       where !t.PlaysOn(date) && t.CanPlay(team) 
       select t).First(); 
     SetupGame(team,opp); 
    } 
} //lot of optimazation possible :) 

でショットです。チームリストの開始時からリストの最後までを交互に繰り返すことで、同じチームが同じチームを何度も何度も何度も演奏しなければならない状況(同じ日に繰り返し演奏する)可能なあらゆる出会いを異なる相手として表現しましたが、それは基本的にCanPlayメソッドが行うべきことです。 これは役に立っていますが、完全な解決策ではありませんが、これは役に立ちます。

6

奇数チーム用と偶数チーム用の2つのアルゴリズムがあり、ラウンドロビンが確実に行われます。

できる場合はグラフィックを生成します。チーム

アルゴリズムの

ODD#は時計回りに、すべてのチームを回転させることです。私たちは5つのチームが持っていた場合:この時点で

1 2 --> 3 1 --> 5 3 --> 4 5 --> 2 4 
3 4  5 2  4 1  2 3  1 5 
5  4  2  1  3 

を私たちは誰もが一度お互いを果たしている1ラウンドロビンを完了している...次のラウンドは再び..

1 2 
3 4 
5 

EVEN#のだろうチーム

チームが偶数の場合、チーム#1を一定の位置に保持し、他のすべてのチームを時計回りに#1の周りに回転させる以外は同じローテーションを行います。私たちは4つのチームに...

1 2 --> 1 3 --> 1 4 
3 4  4 2  2 3 

を持っていたのであれば、これは一つの完全なラウンドロビンだろう...次のマッチアップは次のようになります。..

プログラム
1 2 
3 4 

、あなたがアプローチ可能性がいくつかの方法がありますこの。たぶん上に掲載されたコードは同じことをする。

+1

はい、上記のコードの目的です。 –

+0

@Rune:その場合、+1 !!!! –

関連する問題