Dot-Net

如何自動生成體育聯賽時間表

  • July 11, 2021

我首先要說,我知道這個話題很複雜,而且可能沒有一個簡單的答案。如果這很容易,那麼每個人都會這樣做。話雖如此…

我被要求建構一個應用程序來管理一個體育聯盟。除了這個之外,大多數概念都相當容易理解:如何生成沒有重疊的比賽時間表(球隊一次比賽 2 支球隊),其中一個分區中的球隊與其球隊比賽兩次,但比賽的球隊來自其他部門一次,並確保賽程中沒有漏洞(每支球隊每週比賽)

現在,該過程是使用我為此目的而建構的 Rosetta Stone 類型的電子表格手動完成的,但它僅適用於為其設計的團隊數量。我為 30 個團隊、24 個團隊和 28 個團隊做了變化。與其不斷嘗試重新調整我的翻譯表,我希望能夠編纂該邏輯並調整該過程。

想法?

在國際象棋錦標賽中使用了一個非常簡單的系統,稱為循環賽。

這個想法是將玩家分成桌子的兩側。其中一名玩家被指定為“中心”(為了更好的詞)。比賽開始時讓球員面對面比賽。在第一輪之後,除了輪轂之外的每個人都向前移動一把椅子,然後切換白色/黑色(運動中的主場/客場)順序。當選手坐在原位時,整個循環賽就結束了。如果你想讓每個人都玩兩次,那就再做一次。

帶有實現細節的維基百科文章。

在您的特殊情況下,我會嘗試一次包括所有團隊的循環賽。然後你為每個分區做一次同樣的事情,並確保分區內的球隊在主場和一次客場比賽中互相比賽,從第一輪循環中檢查球隊在該輪比賽中的表現。

當然,不利的一面是,您將在錦標賽結束之前參加所有分區間的比賽(因為最後的 n-1 場比賽是針對分區內的球隊)

$$ n=number of teams in division $$)。如果這是一個問題,您可以簡單地交換一下匹配項。 我實際上編寫了一個簡單的 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()

有兩種算法,一種用於奇數隊,一種用於偶數隊,以確保循環賽發生。

如果可以的話,我將為您生成一個圖形。

奇數#團隊

該算法是順時針旋轉所有團隊。如果我們有 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 

以程式方式,有幾種方法可以解決這個問題。也許上面發布的程式碼做同樣的事情大聲笑..

引用自:https://stackoverflow.com/questions/1037057