Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何自动生成体育联赛时间表_.net_Algorithm_Logic - Fatal编程技术网

.net 如何自动生成体育联赛时间表

.net 如何自动生成体育联赛时间表,.net,algorithm,logic,.net,Algorithm,Logic,首先,我要说,我知道这个话题很复杂,可能没有一个简单的答案。如果这很容易,那么每个人都会这么做。话虽如此 我被要求构建一个应用程序来管理一个体育联盟。除此之外,大多数概念都很容易理解:如何生成一个没有重叠的比赛时间表(一个队同时打两个队),一个分区的一个队打两次自己的队,但打一次其他分区的队,并确保时间表上没有漏洞(每个队每周都打一次) 现在,这个过程是使用rosetta stone类型的电子表格手动完成的,我已经构建了这个电子表格来实现这个目的,但是它只适用于为其设计的团队数量。我为30支球队

首先,我要说,我知道这个话题很复杂,可能没有一个简单的答案。如果这很容易,那么每个人都会这么做。话虽如此

我被要求构建一个应用程序来管理一个体育联盟。除此之外,大多数概念都很容易理解:如何生成一个没有重叠的比赛时间表(一个队同时打两个队),一个分区的一个队打两次自己的队,但打一次其他分区的队,并确保时间表上没有漏洞(每个队每周都打一次)

现在,这个过程是使用rosetta stone类型的电子表格手动完成的,我已经构建了这个电子表格来实现这个目的,但是它只适用于为其设计的团队数量。我为30支球队、24支球队和28支球队做了一些变化。与其不断地尝试重新调整我的翻译表,我希望能够将这种逻辑编成代码,并调整这个过程


思考?

在国际象棋比赛中,有一种非常简单的系统被称为循环赛

这个想法是把球员分成一张桌子的两边。其中一个玩家被指定为“中心”(因为缺少更好的词)。比赛以球员面对面比赛开始。第一轮比赛后,除中心外,所有人都向前移动一把椅子,然后切换白色/黑色(运动中的主场/客场)顺序。当选手们坐在原来的位置上时,整个循环赛就结束了。如果你想让每个人都玩两次,就再玩一次

包括实施细节

在你的特殊情况下,我会尝试做一次循环赛,包括所有团队。然后对每个分区执行相同的操作一次,并确保分区内的团队在主场和客场各进行一次比赛,从第一轮比赛开始检查团队在该轮比赛中的表现

当然,不利的一面是,在锦标赛结束之前,你将参加所有的分区间比赛(因为最近的n-1场比赛是针对分区内球队的[n=分区内球队的数量])。如果这是一个问题,您可以简单地交换一点匹配

实际上,我编写了一个简单的Python脚本来实现这一点。它不需要很多行代码,并产生了相当好的结果。这将创建一个时间表,在该时间表中,每个团队在其分区内与每个团队进行两次比赛,并与其他分区的团队进行一次比赛。然而,没有任何检查来确保两支球队以同一支球队在家的方式相遇两次。但是,这段代码应该提供一个关于如何创建自己的调度代码的好主意

#!/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()

<>我将把这些约束编码为布尔公式,并使用一些SAT求解器来获得解决方案(例如,McISAT为C++,SAT4J为java,甚至可以编写自己的简单求解器)。这些解算器的输入由DIMACS标准化

另见
“社交高尔夫球手问题的SAT编码”和类似问题的SAT编码的“基于SAT的比赛日程安排程序”。

这里是一个实现的快照

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 :)
公共接口ITeam
{
布尔·普莱森(日期时间日期);
boolcanplay(ITeam);//如果两个队之间的比赛合法(玩一次/两次),则返回true
//已经有了相同的、不同的划分和其他适用的规则
}
IEnumerable teams=null;//替换为初始化
IEnumerable reversed=team.Reverse();
IEnumerable gameDays=null;//替换为初始化
var count=teams.count();
foreach(var日期,以游戏日为单位)
{

对于(int i=0;i有两种算法,一种用于奇数团队,另一种用于偶数团队,以确保循环赛的进行

如果可以的话,我将为您生成一个图形

奇数队

算法是顺时针旋转所有团队。如果我们有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 2
3 4
5
团队的偶数

当我们有偶数个团队时,你会做同样的轮换,除了你将团队1固定在固定位置,并以顺时针方式将所有其他团队围绕团队1旋转。因此,如果我们有4个团队

1 2 --> 1 3 --> 1 4 
3 4     4 2     2 3 
这将是一个完整的循环赛…下一场比赛将是

1 2 
3 4 
从编程的角度来看,有几种方法可以实现这一点。也许上面发布的代码也可以做到同样的事情