python应用——分治法实现循环赛
2018-03-10 20:34
225 查看
一.要求
用分治法实现循环赛:
一共有n个选手要进行循环赛,请设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)当n 是偶数,循环赛进行n-1天,当n是奇数,循环赛进行n天。
按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。这时只要让这2个选手进行比赛就可以了。
当有偶数个选手参加比赛时需要进行n-1天比赛。当有奇数个选手时会出现轮空现象,考虑n+1个选手参加比赛的日程安排,最后将多出来的选手对应的比赛轮空,一共需要进行(n+1)-1天比赛。由此推测,不论参加选手人数为偶数还是奇数,统一处理为偶数考虑。
当n/2为偶数时,通过对子问题矩阵元素的平移即可得到。如下图所示:
当n/2为奇数时,首先将子问题处理为n/2+1的情况,再扩充矩阵,以六名选手为例,如下图所示:
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名选手的比赛。运行结果和预先的思路相符。
用分治法实现循环赛:
一共有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名选手的比赛。运行结果和预先的思路相符。
相关文章推荐
- 双端队列(Deque)的python实现及应用
- 用Python实现fib数列的几个方法(yield的应用)
- Python设计模式中单例模式的实现及在Tornado中的应用
- 最近在研究enigma2的代码,那叫个庞大,C/C++写中间件,上层应用全部用python实现,可以学习一下plugin的实现机制了.
- 算法导论:分治法,python实现合并排序MERGE-SORT
- python数据结构与算法 10 栈的应用之中缀转后缀表达式算法的实现
- 神经网络(BP)算法Python实现及简单应用
- 神经网络(BP)算法Python实现及应用
- NLP︱高级词向量表达(一)——GloVe(理论、相关测评结果、R&python实现、相关应用)
- 支持向量机SVM算法应用【Python实现】
- 教你如何用python实现语音控制报表及电脑应用
- Python应用 ---- Mac环境下Flask+Nginx+FastCGI实现Python应用部署
- 决策树 (Decision Tree) 进阶应用 CART剪枝方法及Python实现方式
- 队列(Queue)的python实现及其应用
- python数据结构与算法 21 递归的实现和应用
- leetcode 2. Add Two Numbers python实现的理解,结点,单链表的应用,大数,进位的问题
- 神经网络算法应用举例【Python实现】
- 基于esky实现python应用的自动升级
- python解释器实现及其嵌入式应用:实现语法支持
- 决策树算法实现应用【基于Python语言实现】