您的位置:首页 > 编程语言 > Python开发

python应用——分治法实现循环赛

2018-03-10 20:34 225 查看
一.要求
用分治法实现循环赛:
一共有n个选手要进行循环赛,请设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)当n 是偶数,循环赛进行n-1天,当n是奇数,循环赛进行n天。
 
按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。这时只要让这2个选手进行比赛就可以了。
 

二.设计思路

总共需要进行n*(n-1)/2场比赛。
当有偶数个选手参加比赛时需要进行n-1天比赛。当有奇数个选手时会出现轮空现象,考虑n+1个选手参加比赛的日程安排,最后将多出来的选手对应的比赛轮空,一共需要进行(n+1)-1天比赛。由此推测,不论参加选手人数为偶数还是奇数,统一处理为偶数考虑。
当n/2为偶数时,通过对子问题矩阵元素的平移即可得到。如下图所示:


当n/2为奇数时,首先将子问题处理为n/2+1的情况,再扩充矩阵,以六名选手为例,如下图所示:


三.程序主体

# coding=utf-8
from numpy import *
def compettion(n,mymat):
    if n==2:
        mymat[0,0]=1
        mymat[0,1]=2
        mymat[1,0]=2
        mymat[1,1]=1
        return#分治迭代至只有2名运动员
    # if n%2==1:n+=1#奇数
    # t=int(n/2)
    if n % 2 == 1:
        t=int((n+1)/2)
        n+=1
    else:
        t=int(n/2)
    compettion(t,mymat)#分治迭代
    #在原先的基础上,扩展矩阵
    if n%4==0:#除以2为偶数个运动员
        [b]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
    else:#除以2为奇数个运动员
        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
                        #if(c==i+t)  c++;
                        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])
        compettion(a, b)
    else:#运动员人数为奇数
        b = zeros([a+1, a+1])
        compettion(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()
 

五.运行结果

2名选手:
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exeC:/Users/Administrator/PycharmProjects/untitled1/xunhuansai.py
输入需要进行循环赛的人数:2
[[ 1. 2.]
 [2.  1.]]
 
Process finished with exit code 0
3名选手:
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exeC:/Users/Administrator/PycharmProjects/untitled1/xunhuansai.py
输入需要进行循环赛的人数:3
[[ 1. 2.  3.  0.]
 [2.  1. 0.  3.]
 [3.  0. 1.  2.]
 [0.  0. 0.  0.]]
 
Process finished with exit code 0
4名选手:
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exeC:/Users/Administrator/PycharmProjects/untitled1/xunhuansai.py
输入需要进行循环赛的人数:4
[[ 1. 2.  3.  4.]
 [2.  1. 4.  3.]
 [3.  4. 1.  2.]
 [4.  3. 2.  1.]]
 
Process finished with exit code 0
5名选手:
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exeC:/Users/Administrator/PycharmProjects/untitled1/xunhuansai.py
输入需要进行循环赛的人数:5
[[ 1. 2.  3.  4. 5.  0.]
 [2.  1. 5.  3.  0.  4.]
 [3.  0. 1.  2.  4.  5.]
 [4.  5. 0.  1.  3.  2.]
 [5.  4. 2.  0.  1.  3.]
 [0.  0. 0.  0.  0.  0.]]
 
Process finished with exit code 0
6名选手:
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exeC:/Users/Administrator/PycharmProjects/untitled1/xunhuansai.py
输入需要进行循环赛的人数: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.]]
 
Process finished with exit code 0
 
 

六.结果分析

五名选手及六名选手的结果分别为:





其中第一列为选手序号,第二列为第一天进行比赛的对手,第三列为第二天进行比赛的选手。。。当对手序号为0时,表示当天该选手轮空。
    经过对比,5名选手的比赛安排是在6名选手的比赛安排上去掉涉及第6名选手的比赛。运行结果和预先的思路相符。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: