Python算法之比赛安排

Python算法之比赛安排

问题:一共有n个选手要进行循环比赛,需要安排一个比赛选手表:

  • 每位选手必须与其他n-1个选手各比赛一次;
  • 每个选手一天只能比赛一次;
  • 当n是偶数时循环比赛进行n-1天,当n是奇数时循环比赛进行n天。

代码:

from numpy import *


def competition(n, mymat):
    if n == 2:
        mymat[0, 0] = 1
        mymat[0, 1] = 2
        mymat[1, 0] = 2
        mymat[1, 1] = 1
        return      #分治迭代至只有两位选手
    if n % 2 == 1:
        t = int((n + 1) / 2)
        n += 1
    else:
        t = int(n / 2)
    competition(t, mymat) #分治迭代
    #在原先的基础上,扩展矩阵
    if n % 4 == 0:#n为偶数
        for i in range(int(n / 2)):
            for j in range(int(n / 2)):
                thevalue = mymat[i][j]
                mymat[i + t][j] = thevalue + t
                mymat[i][j + t] = thevalue + t
                mymat[i + t][j + t] = thevalue
    #n为奇数
    else:
        for i in range(int(n / 2)): #获取部分子问题的解
            for j in range(int(n / 2) + 1):
                thevalue = mymat[i][j]
                if thevalue > t: #子问题中假设出的选手
                    #用以下两行解决奇数个选手时矩阵的左半部分
                    mymat[i + t][j] = i + 1 #假设左下部分恰好为i+1
                    mymat[i][j] = i + t + 1#新假设出的选手正好为i+t+1
                    #需要处理矩阵k列开始的右半部分
                    c = i + t + 2 #第一个是5
                    k = int(n / 2) + 1 #第一个是4
                    while k < n:
                        if c > n:
                            c -= t
                        mymat[i][k] = c #右
                        mymat[c - 1][k] = i + 1 #右下
                        c += 1
                        k += 1
                else:
                    mymat[i + t][j] = thevalue+t #向下拓展
    return mymat


def main():
    a = int(input('请输入需要进行循环赛的人数:'))
    if a % 2 == 0:
        b = zeros([a, a])
        competition(a, b)
    else:
        b = zeros([a + 1, a + 1])
        competition(a + 1, b)
        for i in range(a + 1):
            for j in range(a + 1):
                if b[i][j] > a:
                    b[i][j] = 0
                if i == a:
                    b[i][j] = 0
    print(b)


if __name__ == '__main__':
    main()

运行结果:

请输入需要进行循环赛的人数:6
[[1. 2. 3. 4. 5. 6.]
 [2. 1. 5. 3. 6. 4.]
 [3. 6. 1. 2. 4. 5.]
 [4. 5. 6. 1. 3. 2.]
 [5. 4. 2. 6. 1. 3.]
 [6. 3. 4. 5. 2. 1.]]

说明:第一列表示选手的编号,第二列表示第一天要比赛的选手,第三列表示则表示第二天需要比赛的选手,其余以此类推。其中如果出现0,则表示当天该选手没有对手放假休息。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章