分支算法循环赛日程表课程设计

合集下载

Java 循环比赛日程表 附有结果

Java 循环比赛日程表 附有结果

Java 循环比赛日程表附有结果//输出表格a[i][j](i =1,2,…,n;j=2,3,…,n)表示第i号选手在第j-1天的对手public class CirCompete {public void Table(int k,int[][]a){int n=1;for(int i=1;i<=k;i++){//假设k=个运动员要进行循环比赛n2n *=2; //通过k计算n值,实际是通过参赛人数计算出k值的}for(int i=1;i<=n;i++){a[1][i]=i; //打印出第一行即选手1的赛程表}int m=1;//控制每次填充表格i(i表示行)和j(j表示列)的起始填充位置for(int s=1;s<=k;s++){n/=2;//将问题分成k部分for(int t=1;t<=n;t++) {//对每一部分进行划分for(int i=m+1;i<=2*m;i++){ //控制行for(int j=m+1;j<=2*m;j++){//控制列a[i][j +(t - 1) * m *2] = a[i - m][j + (t - 1) * m * 2 - m];//右下角等于左上角a[i][j + (t - 1) * m * 2 -m] = a[i - m][j + (t - 1) * m * 2];//左下角等于右上角} }}m*=2;} }public static void main(String[] args) {CirCompete circompete = new CirCompete();int[][] a=new int[9][9];circompete.Table(3,a);//求8n个选手时候的比赛日程表23==for(int i=1;i<9;i++) {for(int j=1;j<9;j++) {System.out.print(a[i][j]+" ");}System.out.println();}}}运行结果:1 2 3 4 5 6 7 82 1 43 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 46 5 87 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1。

分治法赛程安排实验论文

分治法赛程安排实验论文

附件二【学生用】《算法分析与设计》综合训练实习报告题目:利用分治思想设计循环赛日程表学号姓名专业班级指导教师实践日期目录一、综合训练目的与要求 (1)二、综合训练任务描述 (1)三、算法设计 (1)四、详细设计及说明 (5)五、调试与测试 (5)六、实习日志 (8)七、实习总结 (8)八、附录:核心代码清单 (8)一、综合训练目的与要求本综合训练是软件工程专业重要的实践性环节之一,是在学生学习完《算法分析》课程后进行的综合练习。

本课综合训练的目的和任务:1. 巩固和加深学生对算法分析课程基本知识的理解和掌握;2. 培养利用算法知识解决实际问题的能力;3. 掌握利用程序设计语言进行算法程序的开发、调试、测试的能力;4. 掌握书写算法设计说明文档的能力;5. 提高综合运用算法、程序设计语言、数据结构知识的能力。

二、综合训练任务描述有n个运动员要进行网球循环赛,设计比赛日程表:(1)每个选手必须与其他n-1个选手赛一次;(2)每个选手一天只能赛一次;(3)当n是偶数时,循环赛进行n-1天;当n是奇数时,循环赛进行n天;(4)要求掌握分治法或者多边形方法;(5)设计一个界面,显示产生的日程表;(6)编程语言不限;三、算法设计(1) 文字描述按分治策略,可以将所有的选手对分为两组(如果n是偶数,则直接分为n/2每组,如果n是奇数,则取(n+1)/2每组),n个选手的比赛日程表就可以通过为(n/2或(n+1)/2)个选手设计的比赛日程表来决定。

递归地用这种一分为二的策略对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。

这时只要让这两个选手进行比赛就可以了。

下图给出的是六个选手的比赛日程表,其中第一列表示1-6个选手,第二列到第六列表示各个选手在第一天到第五天的所遇到的选手。

(2)框图比赛人数nNNYNYNYYNYint i=1i<=Ni++a[1][i]=ii++m=1s=1s<=k?N=N/2int t=1t<=N?int i=m+1i<=2*mj=m+1j<=m+1a[i][j+(t-1)*m*2] = a[i-m][j+(t-1)*m*2-m] a[i][j+(t-1)*m*2-m] = a[i-m][j+(t-1)*m*2]j++i++t++s++ m=m*2k+=1伪代码public static void copy(int n) {int m = n / 2;for (int i = 1; i <= m; i++)for (int j = 1; j <= m; j++) {a[i][j + m] = a[i][j] + m;a[i + m][j] = a[i][j + m];a[i + m][j + m] = a[i][j];}}public static void tournament(int n) {if (n == 1) {a[1][1] = 1;return;}if (odd(n)) {tournament(n + 1);}tournament(n / 2);makecopy(n);}public static boolean odd(int n) {return (n & 1) != 0;}public static void makecopy(int n) // makecopy 与copy算法类似,但是要区分n/2为奇数或偶数的情形{if (n / 2 > 1 && odd(n / 2))copyodd(n);elsecopy(n);}public static void copyodd(int n) // 实现n/2为奇数时的复制{int b[] = new int[size];int m = n / 2;for (int i = 1; i <= m; i++) {b[i] = m + i;b[m + i] = b[i];}for (int i = 1; i <= m; i++) // 这个循环比较难看懂,试着在纸上走走n=6时的情形,就能明白为什么要这么写 { for (int j = 1; j <= m + 1; j++) { if (a [i][j] > m) { a [i][j] = b[i];a [m + i][j] = (b[i] + m) % n; } elsea [m + i][j] = a [i][j] + m;}for (int j = 2; j <= m; j++) { a [i][m + j] = b[i + j - 1]; a [b[i + j - 1]][m + j] = i; }}}}四、详细设计及说明1.输入数字n 判断n 的奇偶性,根据情况进行分治法,安排赛程。

循环赛日程表_分治法

循环赛日程表_分治法

循环赛⽇程表_分治法题⽬: 设有n=2^k个运动员要进⾏⽹球循环赛。

现要设计⼀各满⾜⼀下要求的⽐赛⽇程表: 1、每个选⼿必须与其他n-1个选⼿各⽐赛⼀次。

2、每个选⼿⼀天只能赛⼀次。

3、循环赛⼀共进⾏n-1天。

按照此要求可以将⽐赛⽇程表设计成⼀个n*n的⼆维表,第⼀列表⽰选⼿,接下来的每⼀列依次表⽰将要⽐赛的每⼀天选⼿。

下⾯以8个选⼿为例:思路: 按照分治法,可将所有选⼿进⾏⼆分,n个选⼿的⽐赛安排可通过n/2个选⼿的⽇程表来决定。

递归地⽤这种⼀分为⼆的策略对选⼿进⾏分割,知道只剩两个选⼿,⽇程表显然直接安排即可。

下图为8个选⼿的⽐赛⽇程表: 图1算法步骤: 1、利⽤⼀个for循环初始化选⼿1的⽇程安排,即图1中的第⼀⾏。

2、根据选⼿1的⽇程安排来安排选⼿2。

此刻为最⼩规模,以相邻的每两天即四个最⼩单元为⼀组,例如选⼿⼀第⼀天要跟选⼿2⽐赛,那么相应选⼿2也要跟选⼿1⽐赛,所以将图1中的第⼀⾏第⼀列序号抄到第⼆⾏第⼆列,将第⼀⾏第⼆列序号抄到第⼆⾏第⼀列。

依次,第3、4列,第5、6列,第7、8列也是。

3、根据选⼿1、2的⽇程安排可以按照左上⾓数据抄到右下⾓,右上⾓数据抄到左下⾓安排出选⼿3、4的⽇程。

4、最后根据前四选⼿,可以将所有⼈的⽇程表都安排出来。

下⾯是java实现完整代码:1package competition;23import java.util.Scanner;45public class Com {6private static Scanner scanner;78public static void main(String [] args) {9int k; //注意,n才是选⼿的⼈数,k只是问题要划分的⼦问题规模数,即n=2^k10 System.out.println("输⼊k:");11 scanner = new Scanner(System.in);12 k=scanner.nextInt();13int a[][]=new int[pow(2,k)+1][pow(2,k)+1];14 table(k, a);15for(int i=1; i<pow(2,k)+1; i++){16for(int j=1; j<pow(2,k); j++){17 System.out.print(a[i][j]+" ");18 }19 System.out.println(a[i][pow(2,k)]);20 }21 }2223static void table(int k, int [][]a){24int n=pow(2,k);25for(int i=1; i<=n; i++) a[1][i]=i;26int m=1;//定义M为记录每⼀次填充时i、j的起始填充位置27for(int s=1; s<=k; s++){//分治规模28 n/=2;29for(int t=1; t<=n; t++)//t是每⼀层分治中进⾏对称的单位的个数30for(int i=m+1; i<=2*m; i++)//控制⾏31for(int j=m+1; j<=2*m; j++){//控制列32 a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];//右下⾓的值等于左上⾓的值33 a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];//左下⾓的值等于右上⾓的值34 }35 m*=2;36 }37 }3839static int pow(int a, int n) {//幂函数40int res=1;41for(int i=0; i<n; i++)42 res*=a;43return res;44 }45 }。

循环赛日程表

循环赛日程表

//n/2为奇数
代码实现
❖ void copyodd(int n) // n/2为奇数的合并
{
int m=n/2;
for(int i=0;i<m;i++)
{
b[i]=m+i;
b[m+i]=b[i];
}
//未完

代码实现
for(i=0;i<m;i++){
for(int j=0;j<m+1;j++)
}
时间复杂度分析
1. N/2为奇数 T(n)=O(4k)
有2个循环结构 基本语句是循环体内的赋值语句 T(n)=2+(+2)=0(4k),
2.N/2为偶数T(n)=O(4k)
有2个循环结构 基本语句是循环体内的赋值语句 T(n)=3=0(4k),

调试运行
N=4 N=3
3
0
1
3
2
1
0
第输一天出要求<0,(n=4时) 第二天 1>=
0
1
A
1
0
<2, 3>= B<1

第一天
0>=
A
B
B
A
第三天
2
3
A
<3
3
2

A
B
B
A
2>=
B
输第一出天 要第二求天 (第三n天=4时)
0
1
2
3
1
0
3
2
2
3
0
1
3
2
1
0
AC BD

分支算法循环赛日程表课程设计

分支算法循环赛日程表课程设计

摘要分治算法在实际中有广泛的应用,例如,对于n个元素的排序问题,当n = 1 时,不需任何计算;当n = 2 时,只要做一次比较即可排好序;当n = 3时只要做两次比较即可……而当n 较大时,问题就不容易那么处理了。

要想直接解决一个较大的问题,有时是相当困难的。

分治算法的基本思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

如果原问题可分割成k 个子问题,1 < k < n+1,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治算法就是可行的。

由分治算法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。

在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易求出其解。

由此自然引出递归算法。

分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

本次课程设计正是采用分治算法来解决循环赛日程表的安排问题。

根据算法的设计结果,采用 c 语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

关键词:分治算法目录摘要 (I)1问题描述 (1)2问题分析 (2)3算法设计 (3)4算法实现 (8)5测试分析 (12)结论 (13)参考文献 (14)1问题描述设有n 位选手参加网球循环赛,n=2k,循环赛共进行n-1 天,每位选手要与其他n-1 位选手比赛一场,且每位选手每天比赛一场,不能轮空,按以下要求为比赛安排日程,1)每位选手必须与其他n-1 格选手格赛一场;2)每个选手每天只能赛一场;3)循环赛一共进行n-1 天;请按此要求将比赛日程表设计成有n 行和n-1 列的一个表。

在表中的第i 行和第j 列处填入第i 个选手在第j 天所遇到的选手,其中1≤i ≤n,1≤j ≤n-1 。

2问题分析运用分治法,将原问题划分为较小问题,然后由较小问题的解得出原问题的解。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。

关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

问题的规模越小,越容易求解,所需的计算时间也越少。

分治法是计算机科学中经常使用的一种算法。

设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11&&odd(n/2)) copyodd(n);else copy(n);}void copyodd(int n){int m=n/2;for(int i=0;i=m){a[i][j]=b[i];a[m+i][j]=(b[i]+m)%n;}else a[m+i][j]=a[i][j]+m;}for(j=1;j<m;j++){a[i][m+j]=b[i+j];a[b[i+j]][m+j]=i;}}}分析算法的时间性能:当n/2为奇数时,基本语句的执行次数是:当n/2为偶数时,基本语句的执行次数是:综上,时间复杂度为O(4k )。

2.3 运行结果及分析当输入n为2时,输出:0 11 0在上面n=2时的日程表(二维表)中,左边第一列表示球队编号,第二列表示在某天碰到的对手球队的编号。

推广之,对于n行n列的二维日程表,那么,a[0][0],a[1][0],……,a[n-1][0]表示参加循环赛的n支球队的编号;a[0][1],a[0][2],……,a[0][n-1]表示球队a[0][0]在第1,2,……,n-1天碰到的对手球队编号。

a[i][j](i,j<n)表示编号为a[i][0]的球队在第j日遇到的对手球队的编号。

以下同。

循环赛问题分析与C语言代码-分治法

循环赛问题分析与C语言代码-分治法

问题描述:设有n个运动员要进行网球循环赛。

设计一个满足以下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次;(2)每个选手一天只能赛一次;(3)当n是偶数时,循环赛进行n-1天。

当n是奇数时,循环赛进行n天。

分析过程:这个问题的解搜索空间是一个n的全排列。

要求的解是其中的n个排列,满足条件:第1列n个元素值按增序排列;每行每列没有相同的数。

也是一个幻方(除对角线的和不作要求)的问题。

1.n=11)2. n=2(表2)3.n=3,(1) 添加一个虚拟选手4#,构成n+1=4(2) 4/2=2,分两组,每组各自安排(1 2),(3 4)(3)每组跟另一组分别比赛(拷贝)这是四个人比赛的安排(4)把虚选手置为0(表4)3人赛程这是三个人比赛的安排4. n=4, 见表35. n=5, (1)加一个虚选手,n+1=6。

安排好6个人的比赛后,把第6个人用0表示即得5人的。

(2) 分成两组(1 2 3) (4 5 6),各3名选手(3) 依照表4,安排第1组;按表5安排第2组(除0元素外,都加3)(表5)(4) 把表5排于表4下方(5) 把同一天都有空的两组安排在一起比赛(按这种安排,肯定每天只有一对空组,?)。

(6) 第一组的(1 2 3)和第2组的(4 5 6)分别比赛。

但是由于(1,4), (2, 5), (3 6)已经比赛过了,所以在后面的安排中不能再安排他们比赛。

1 2 34 5 6首先,1#只能和5#或6#比赛。

(a)若1#-5#,由于3#和6#已经比赛过,所以只能安排: 2#-6#,3#-4#(b)若1#-6#,由于2#和5#已经比赛过,只能安排:2#-4#,3#-5#这样安排后前三行的后两列,后三行的后两列由上面的三行来定:表8就是6名选手的比赛日程安排。

将其中的6号作为虚拟选手,把6换成0,即得5名选手的赛程安排表:(表9)5人赛程6 n=6,见表8。

7 n=7, 添加1,n+1=8。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表作者:王猛来源:《科技经济市场》2008年第07期摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。

关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

问题的规模越小,越容易求解,所需的计算时间也越少。

分治法是计算机科学中经常使用的一种算法。

设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11.1.2分解所得到的子问题与原问题具有相似的结构,便于利用递归或循环机制;1.1.3合并各个子问题的解,就是原问题的解。

1.2 分治法的一般步骤1.2.1分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;1.2.2求解子问题:若子问题规模较小而容易解决则直接解,否则再继续分解为更小的子问题,直到容易解决;1.2.3合并:将已求解的各个子问题的解,合并为原问题的解。

2 循环赛分治算法2.1 问题描述有n支球队参加循环赛,设计一个满足下面要求的比赛日程表:2.1.1每支球队必须与其他n-1支球队各赛一次;2.1.2每支球队一天只能比赛一次;2.1.3当n为偶数时,比赛进行n-1天;当n为奇数时,比赛进行n天。

2.2 算法分析当n=2k (k=1、2、3、4……)时,比较简单。

按照分治的策略,可将所有参赛的选手分为两部分,n=2k 个选手的比赛日程表就可以通过为n/2=2k-1 个选手设计的比赛日程表来决定。

递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单,只要让这2个选手进行比赛就可以了。

再逐步合并子问题的解即可得到原问题的解。

算法如下:void tourna(int n){if(n==1){a[0][0]=1;return;}tourna(n/2);copy(n);}void copy(int n){int m=n/2;for(int i=0;ifor(int j=0;j{a[i][j+m]=a[i][j]+m;a[i+m][j]=a[i][j+m];a[i+m][j+m]=a[i][j];}基本语句的执行次数是:T(n)=3=O(4k ),所以算法的时间复杂度为O( 4k)。

【算法-分治策略应用】循环赛日程表问题

【算法-分治策略应用】循环赛日程表问题

【算法-分治策略应⽤】循环赛⽇程表问题⼀、分治策略基本思想1、Divide将原始问题划分或者归结为规模较⼩的⼦问题(多数情况下是划分成2个)2、Conquer递归或迭代求解每个⼦问题3、Combine将⼦问题的解综合得到原问题的解注意:1、⼦问题与原始问题性质完全⼀样2、⼦问题之间可彼此独⽴地求解3、递归停⽌时⼦问题可直接求解⽐较典型的应⽤例⼦是“归并排序法”和“快速排序法”,详细可以参考屈婉玲等编著的《算法设计与分析》(第2版)P26和P37,此处不再赘述。

⼆、题⽬分析和建模1. 问题描述设有n=2k个选⼿要进⾏⽐赛,设计的⽐赛⽇程表需要满⾜以下要求:1)每个选⼿必须与其他n-1个选⼿各赛⼀次;2)每个选⼿⼀天只能赛⼀次;3)整场循环赛⼀共进⾏n-1天。

2. 题⽬建模将⽐赛⽇程表设计成n⾏×n-1列的⼀个表,表中第i⾏第j列的元素表⽰第i个选⼿在第j天所遇到的选⼿。

(1)⾸先看只有两个选⼿的⽇程表(k=1,n=2,2⾏×1列表格,循环赛进⾏1天):表1 循环赛⽇程表(2⼈)(2)四个选⼿的⽇程表(k=2,n=4,4⾏×3列表格,循环赛进⾏3天):⾸先n=22,所以应该退化到求解两个2⼈循环赛的问题,⽇程表构建如下:表1 循环赛⽇程表(2⼈) 表2 循环赛⽇程表(2⼈)将表2抄在表1右侧构成表1*,将表1抄在表2右侧构成表2*,将表1*与表2*按次序上下拼接,构成表3:表3 循环赛⽇程表(4⼈)由于表1和表2中运动员完全不同,拼接之后每⼀⾏和每⼀列都不会存在两个相同号码,也就是说拼接后不会产⽣⼀个选⼿在同⼀天和另外⼀个选⼿⽐赛两次的情况,说明这种拼接是合理的。

(3)⼋个选⼿的⽇程表(k=3,n=8,8⾏×7列表格,循环赛进⾏7天)n=23,⾸先应该退化到4⼈循环赛问题,再退化到2⼈循环赛问题,4⼈退化到2⼈已在(2)中详细描述,此处只说明如何退化到4⼈问题:表3 循环赛⽇程表(4⼈) 表4 循环赛⽇程表(4⼈)拼接⽅法与(2)中相同,构成表5:表5 循环赛⽇程表(8⼈)三、算法设计(1)设计思想:设n=2k采⽤分治策略,将所有参加⽐赛的选⼿分成两部分,n=2k个选⼿的⽐赛⽇程表就可以通过两个n=2k-1个选⼿的⽐赛⽇程表来决定。

分治法——循环赛日程表

分治法——循环赛日程表

分治法——循环赛⽇程表1、问题描述:有n=2^k个远动员选⼿,设计⽐赛⽇程表实现:(1)每个选⼿必须与n-1个选⼿⽐赛(2)每个选⼿⼀天只⽐赛⼀场(3)⽐赛共进⾏n-1天输⼊:n⼈输出:n⾏n-1列,第i⾏第j列表⽰第i个选⼿第j天遇到的对⼿,不包含第⼀列表⽰为选⼿编号举例:2⼈1 22 12、问题分析通过化⼤为⼩,分⽽治之的思想,将多⼈的⽐赛⽇程缩⼩为2⼈的⽇程。

以此倒推所有⼈的⽇程。

注意多⼈⽇程规律:以四⼈为例:1 2 | 3 42 1 | 4 3----------3 4 | 1 24 3 | 2 1这样⼀个矩阵分为四个区,左上和右下⼀样,左下和右上⼀样,且右上是左上对应的数字加了n/2.3、代码实现1 #include <stdio.h>2 #include <string.h>34#define N 1285int matrix[N][N] = {0};67void fun(int n)8 {9int i;10int j;11if (n<=0)12 {13return;14 }15if (n>2)16 {17 fun(n/2);18for (i=1;i<=n/2;i++)19 {20for (j=n/2+1;j<=n;j++)21 {22 matrix[i][j] = matrix[i][j-n/2] + n/2;23 }24 }25for (i=n/2+1;i<=n;i++)26 {27for (j=1;j<=n/2;j++)28 {29 matrix[i][j] = matrix[i-n/2][j+n/2];30 }31 }32for (i=n/2+1;i<=n;i++)33 {34for (j=n/2+1;j<=n;j++)35 {36 matrix[i][j] = matrix[i-n/2][j-n/2];37 }38 }39 }40else41 {42 matrix[1][1] = 1;43 matrix[1][2] = 2;44 matrix[2][1] = 2;45 matrix[2][2] = 1;46 }47 }4849void main()50 {51 fun(8);5253int i,j;54for (i=1;i<=8;i++)55 {56for (j=1; j<=8; j++)57 {58 printf("%d ",matrix[i][j]);59 }60 printf("\n");61 }62 }。

循环赛日程表的分治算法实现实验报告_gxl

循环赛日程表的分治算法实现实验报告_gxl
对于N为奇数的情况可以虚拟多一个选手,使其编程N+1个选手的日程表,最然后忽略虚拟运动员参与的比赛。对于分割时候N/2的情况也做特殊处理,前n/2轮比赛空选手与下一个未参赛的选手进行比赛。
四、模型求解
4.1程序设计(方案)说明(如:你如何实现矩阵划分、矩阵结果的合并)
4.2主要源代码(主要函数功能、变量、语句进行注释)
通过本设计性实验,理解递归算法以及分治算法的基本思想。理解Strassen矩阵乘法的理论分析或循环赛日程表的分治算法以及编程实现。掌握多项式乘积的分治方法。能对递归算法以及分治算法进行设计、分析。
本课程实验目的是验证、巩固和补充课堂讲授的理论知识。培养学生初步具备独立设计算法和对给定算法进行复杂性分析的能力,为后继课程和实际工作打下基础。
a[b[i+j-1]][m+j]=i;
}
}
}
4.3程序使用说明(如:矩阵阶数n由用户输入)
4.4模型的解(含运行结果截图)
当n=偶数时
当n=奇数时
4.5测试及结果分析
(如:
1.对传统定义矩阵乘积、Strassen矩阵乘积给出计算结果对比;
2.进行执行时间统计的对比并讨论算法性能的比较)
五、实验总结及自我评价(可含个人心得体会)
(对实验中遇到的问题、难点及解决方法进行总结:自己在实验中的有哪些体会;对个人能力的评价。)
整个赛程,当N为偶数的时候,N-1天能够结束。
而当N为奇数的时候,只能在至少N天结束。
比如N=3的时候,每场必须有两个人,则每天只能有一场比赛,假设是1和2比赛,则3号运动员没有对象比赛,所以一天最多一场比赛,这个比赛需要的比赛场数C=3场,则整个比赛需要的天数为C/1=3天。
题目2具体要求:

要求:编写程序,用分治法求解循环赛日程表。

要求:编写程序,用分治法求解循环赛日程表。

要求:编写程序,用分治法求解循环赛日程表。

一、实验目的与要求1、掌握网球循环赛日程表的算法;2、初步掌握分治算法二、实验题:问题描述:有n=2^k个运动员要进行循环赛。

现要设计一个满足以下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次(2)每个选手一天只能赛一次(3)循环赛一共进行n-1天三、实验代码#include <stdio.h>#include <stdlib.h>#define MAX 1024int a[MAX][MAX];void Copy(int tox, int toy, int fromx, int fromy, int n){ int i, j;for (i=0; i<n; i++){ for (j=0; j<n; j++){ a[tox + i][toy + j] = a[fromx + i][fromy + j];}}}void Table(int k, int a[][MAX]){ int i, n = 1 << k;for (i=0; i<n; i++){ a[0][i] = i + 1;}for (int r=1; r<n; r<<=1){ for (i=0; i<n; i+=2*r){ Copy(r, i + r, 0, i, r);Copy(r, i, 0, i + r, r);}}}void Out(int a[][MAX], int n){ int i, j;for (i=0; i<n; i++){ for (j=0; j<n; j++){ printf("%3d", a[i][j]);} printf("\n");} printf("\n");}int main(){ int i;for (i=0; i<5; i++){ int len = 1 << i;Table(i, a);Out(a, len);} return 0;}四、实验结果。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表
{r et ai n n&1;
} voi d ma kee opy ( i n t m
{遗( rl /2) >1&&odd∽))c opyodd( n);
els e c opy( n); l voi d eop yodd ( i nt n) {i n t m=n/2; f or ( int i- -O;i<m;i ++)
el se a[m+i 】【j 】-a 【i 】【j 】+m; l f or O=l ;j <m;j ++) {a [i l[m+j 】- b[ i+j 】; a【b“+j 】Ⅱm+j 】- i ; }
l 1
分析算法的 时间性能: 当n/2为 奇数时,基本 语句的执行次 数是:
T∞=∑2+∑( ∑+∑2) =0( 42)
算法如下: voi d t o uma( i nt n) {if ( n==1) {a[ O][ 0]=1;r et urn;J tour ed(n/2); copy( n); J voi d copy( hat I n {i n t re =n /2 ;
f or (hat i -- O;i <m;i ++) f or (i nt j =0.j<玎嘶++)
随着计算机技术的蓬勃发展计算机教学将面临新的挑战机房管理也将越来越受到学校的重视在以后的工作中机房管理人员应不断总结积累经验提高工作效率提高自身的管理水平和技术水平更好地为学校教育教学服务
煎垫壅进查塑
÷
…}
ቤተ መጻሕፍቲ ባይዱ
垫查±鱼
利用分治法设计 循环赛日程表

循环赛问题分析与C语言代码分治法

循环赛问题分析与C语言代码分治法
6
7
8
9
6
7
8
9
0
1
5
4
3
2
7
6
0
8
2
9
1
5
4
3
8
3
6
7
9
0
2
1
5
4
9
0
4
6
8
7
3
2
1
5
0
9
7
5
6
8
4
3
2
1
由上面的分析,可以总结出如下算法:
n名选手的赛程安排问题:
1如果n为偶数,可分为两个n/2人的组,分别比赛,然后两组间比赛。
1.1如果n/2为偶数,左下角为左上角加n/2来得到,然后左下角拷贝到右上角;左上角拷贝到右下角;
6
0
4
5
0
3
2
1
(4)把表5排于表4下方
(表6)
1
2
3
0
2
1
0
3
3
0
1
2
4
5
6
0
5
4
0
6
6
0
4
5
(5)把同一天都有空的两组安排在一起比赛(按这种安排,肯定每天只有一对空组,?)。
(表7)
1
2
3
4
2
1
5
3
3
6
1
2
4
5
6
1
5
4
2
6
6
3
4
5
(6)第一组的(1 2 3)和第2组的(4 5 6)分别比赛。但是由于(1,4), (2, 5), (3 6)已经比赛过了,所以在后面的安排中不能再安排他们比赛。

分治法解决循环赛日程表的递归方程)

分治法解决循环赛日程表的递归方程)

分治法解决循环赛日程表的递归方程)分治法是一种解决问题的算法思想,它将一个大问题划分为若干个小问题,并分别解决这些小问题,最后将小问题的解合并得到原问题的解。

这种思想在循环赛日程表的递归方程中也可以得到应用。

循环赛日程表是指参赛团队之间进行循环对战的赛程安排表。

在一个参赛团队数量为n的循环赛中,每个团队需要与其他n-1个团队进行比赛,总共进行了(n-1) * n / 2场比赛。

解决循环赛日程表的递归方程可以分为三个步骤:1. 将参赛团队分为两个子集,分别是左侧子集和右侧子集。

如果参赛团队数量为奇数,可以将最后一个团队放入左侧子集。

2. 分别为左侧子集和右侧子集构造循环赛日程表。

这可以通过递归调用解决循环赛日程表的递归方程来实现。

递归的终止条件是子集中只有一个团队,此时不需要进行比赛。

3. 将左侧子集和右侧子集的日程表合并得到整个循环赛日程表。

合并的过程是将左侧子集的日程表和右侧子集的日程表进行对应位置的合并,合并后的结果即为整个循环赛日程表。

通过以上三个步骤,我们可以递归地构造出循环赛日程表。

这种分治法的思想能够将原问题划分为多个小问题来解决,从而提高问题的解决效率。

在实际应用中,分治法可以有效地解决循环赛日程表的问题。

通过将问题划分为若干个小问题,并逐步解决这些小问题,最后再将小问题的解合并得到原问题的解,可以高效地构造出循环赛日程表。

分治法是一种解决问题的有效算法思想,它可以应用于循环赛日程表的递归方程。

通过将问题划分为若干个小问题,并逐步解决这些小问题,最后将小问题的解合并得到原问题的解,可以高效地构造出循环赛日程表。

这种算法思想能够提高问题的解决效率,是解决循环赛日程表问题的一种有效方法。

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

《算法设计与分析》课程设计报告题目:循环赛日程表院(系):信息科学与工程学院专业班级:软工学生姓名:学号:指导教师:2018 年 1 月 8 日至 2018 年 1 月 19 日算法设计与分析课程设计任务书目录1 常用算法 (1)1.1分治算法 (1)基本概念: (1)1.2递推算法 (2)2 问题分析及算法设计 (5)2.1分治策略递归算法的设计 (5)2.2 分治策略非递归算法的设计 (7)2.3 递推策略算法的设计 (8)3 算法实现 (9)3.1分治策略递归算法的实现 (9)3.2 分治策略非递归算法的实现 (10)3.3 递推策略算法的实现 (12)4 测试和分析 (15)4.1分治策略递归算法测试 (15)4.2分治策略递归算法时间复杂度的分析 (16)4.3 分治策略非递归算法测试 (16)4.4分治策略非递归算法时间复杂度的分析 (17)时间复杂度为:O(5^(n-1)) (17)4.5 递推策略算法测试 (17)4.6 递推策略算法时间复杂度的分析 (18)时间复杂度为:O(5^(n-1)) (18)4.7 三种算法的比较 (18)5 总结 (19)参考文献 (20)1 常用算法1.1分治算法基本概念:在计算机科学中,分治法是一种很重要的算法。

字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

问题的规模越小,越容易直接求解,解题所需的计算时间也越少。

例如,对于n个元素的排序问题,当n=1时,不需任何计算。

n=2时,只要作一次比较即可排好序。

n=3时只要作3次比较即可,…。

而当n较大时,问题就不那么容易处理了。

循环赛日程表分治算法(c语言)

循环赛日程表分治算法(c语言)

/**设有n=2k个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表:*每个选手必须与其他n-1个选手各赛一次;*每个选手一天只能参赛一次;*xx在n-1天内结束。

*数组a[i][j]第i个选手在第j天所遇到的选手。

*/#include<stdio.h>#include<math.h>void gametable(int k){int a[100][100];int n,temp,i,j,p,t;n=2;//k=0两个参赛选手日程可以直接求得a[1][1]=1;a[1][2]=2;a[2][1]=2;a[2][2]=1;for(t=1;t<k;t++)//迭代处理,依次处理2^n....2^k个选手的比赛日程{temp=n;n=n*2;//填左下角元素for(i=temp+1;i<=n;i++)for(j=1;j<=temp;j++)a[i][j]=a[i-temp][j]+temp;//左下角和左上角元素的对应关系for(i=1;i<=temp;i++)//将左下角元素抄到右上角for(j=temp+1;j<=n;j++)a[i][j]=a[i+temp][(j+temp)%n];for(i=temp+1;i<=n;i++)//将左上角元素抄到右下角for(j=temp+1;j<=n;j++)a[i][j]=a[i-temp][j-temp];}printf("参赛人数为:%d\n(第i行第j列表示和第i个选手在第j天比赛的选手序号)\n",n);for(i=1;i<=n;i++)for(j=1;j<=n;j++){printf("%d ",a[i][j]);if(j==n)printf("\n");}}void main(){int k;printf("比赛选手个数为n(n=2^k),请输入参数K(K>0):\n");scanf("%d",&k);if(k!=0)gametable(k);}。

算法设计与分析课程设计-实验指导书 -

算法设计与分析课程设计-实验指导书 -

算法设计与分析课程设计实验指导书一、运动员比赛日程表设有n=2k个运动员要进行网球比赛。

设计一个满足以下要求的比赛日程表:●每个选手必须与其它n-1个选手各赛一次●每个选手一天只能赛一次●循环赛一共进行n-1天1、运用分治策略,该问题的递归算法描述如下,根据算法编制程序并上机通过。

输入:运动员人数n(假定n恰好为2的i次方)输出:比赛日程表A[1..n,1..n]1. for i←1 to n //设置运动员编号2. A[i,1]←i3. end for4. Calendar(0,n) //位移为0,运动员人数为n。

过程Calendar(v, k) //v表示位移(v=起始行-1),k表示运动员人数。

1. if k=2 then //运动员人数为2个2. A[v+2,2]←A[v+1,1] //处理右下角3. A[v+1,2]←A[v+2,1]//处理右上角4. else5. Calendar(v,k/2) //假设已制定了v+1至v+k/2运动员循环赛日程表6. Calendar(v+k/2,k/2) //假设已制定了v+k/2+1至v+k运动员循环赛日程表7. comment:将2个k/2人组的解,组合成1个k人组的解。

8. for i←1 to k/29. for j←1 to k/210. A[v+i+k/2,j+k/2]←A[v+i,j] //沿对角线处理右下角11. end for12. end for13. for i←k/2+1 to k14. for j←1 to k/215. A[v+i-k/2,j+k/2]←A[v+i,j] //沿对角线处理右上角16. end for17. end for18. end if2、编制该问题的非递归算法,上机通过。

将如上文件保存在命名为“学号+姓名+实验一”的文件夹中并上传到指定的服务器。

二、最长公共子序列运用动态规划法最长公共子序列问题,给出最优值并输出最优解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

摘要分治算法在实际中有广泛的应用,例如,对于n个元素的排序问题,当n = 1 时,不需任何计算;当n = 2 时,只要做一次比较即可排好序;当n = 3时只要做两次比较即可……而当n较大时,问题就不容易那么处理了。

要想直接解决一个较大的问题,有时是相当困难的。

分治算法的基本思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

如果原问题可分割成k个子问题,1 < k < n+1,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治算法就是可行的。

由分治算法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。

在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易求出其解。

由此自然引出递归算法。

分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

本次课程设计正是采用分治算法来解决循环赛日程表的安排问题。

根据算法的设计结果,采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。

关键词:分治算法目录摘要 (I)1 问题描述 (1)2 问题分析 (2)3 算法设计 (3)4 算法实现 (7)5 测试分析 (11)结论 (12)参考文献 (13)1 问题描述设有n位选手参加网球循环赛,n=2k,循环赛共进行n-1天,每位选手要与其他n-1位选手比赛一场,且每位选手每天比赛一场,不能轮空,按以下要求为比赛安排日程,1)每位选手必须与其他n-1格选手格赛一场;2)每个选手每天只能赛一场;3)循环赛一共进行n-1天;请按此要求将比赛日程表设计成有n行和n-1列的一个表。

在表中的第i行和第j列处填入第i个选手在第j天所遇到的选手,其中1≤i≤n,1≤j≤n-1。

2 问题分析运用分治法,将原问题划分为较小问题,然后由较小问题的解得出原问题的解。

1.分治法:对于一个规模为n的问题,若该问题可以容易的解决(比如说规模n较小),则直接解决,否则将其分解为k个规模较小的子问题,这些子问题相互独立且与原问题形式相同,递归的解决这些子问题,然后将个子问题的解合并,得到原问题的解。

2.分治法的解题步骤(由三个步骤组成)✧划分(divide):将原问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。

✧解决(conquer):若子问题规模较小,则直接求解;否则递归求解各子问题。

✧合并(conbine):将各子问题的解合并为原问题的解假设n位选手顺序编号为1,2,3……n,比赛的日程表是一个n行n-1列的表格。

i行j列的表格内容是第i号选手在第j天的比赛对手。

根据分而治之的原则,可从其中以半选手的比赛日程,导出全体n位选手的的日程,最终细分到只有两位选手的比赛日程出发。

3 算法设计1.设计步骤:1)先设计主函数(main函数),然后设计两个函数,分别是安排赛事进行填制表格的函数(void Table(int n, int a[100][100])函数)和输出到屏幕函数(void Out(int n,int a[100][100]))。

2)在主函数(main())里调用void Table()函数,对比赛日程进行安排,根据分而治之原则,绘制比赛日程表格,然后调voidOut()函数,将安排好的比赛日程输出到屏幕上。

2.关键数据结构1)运用一个二维数组a[i][j],对安排好的赛事日程进行排列和保存,并在屏幕上输出。

2)使用二维数组的原因:因为根据题目要求,比赛日程表是一个n行n-1列的表格,用a[i][j]代表第i号选手在第j天遇到的对手,所以用一个二维数组表示。

3.程序结构程序主要由三个函数组成:1)main()函数(主函数);2)void Table()函数(本程序的核心函数);3)Out()函数(输出函数)三个函数的程序结构如下所示:1) main()函数图 3-1 2) void Table ()函数 传值 调用void Table ()函数 int k; 输入k 值 main()计算参赛人数n 值 计算参赛人数n=2k 调用Out ()函数,输出到屏幕 结束图3-2void Table(int n, int a[100][100])N NY N Y N YYN Y int i=1i<=ni++a[1][i]=ii++ m=1s=1s<=k?n=n/2int t=1t<=n?int i=m+1i<=2*mj=m+1j<=m+1a[i][j+(t-1)*m*2] = a[i-m][j+(t-1)*m*2-m]a[i][j+(t-1)*m*2-m] = a[i-m][j+(t-1)*m*2] j++i++ t++s++ m=m*2 结束3) Out ()函数图3-3i++N N YY void Out(int n,int a[100][100])int i=1i<=nint j=1j<=nj++printf(“%4d ”,a[i][j]); printf(“\n ”);结束4 算法实现关键程序功能及程序的说明如下:1. main()函数(1)函数功能:在屏幕上输入k值,计算参赛人数n,然后调用void Table()函数和Out()函数。

(2)函数实现:①先定义一个k,然后在键盘上输入一个k值,并赋值给k(假设输入3);②运用for循环,计算参赛人数n的值for (int i=1;i<=k;i++)n *= 2;可得n=8,即有八个人参赛。

③然后调用void Table()函数和Out()函数,并传值。

2.void Table()函数(1)函数功能:对所有运动员的赛程进行安排,并将其存入数组内。

(2)函数实现:由main()函数得到k值为3,n值为8①用一个for循环输出日程表的第一行for(int i=1;i<=n;i++)a[1][i] = i;12345678②然后定义一个m值,m初始化为1,m用来控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置。

③用一个for循环将问题分成几部分,对于k=3,n=8,将问题分成3大部分,第一部分为,根据已经填充的第一行,填写第二行,第二部分为,根据已经填充好的第一部分,填写第三四行,第三部分为,根据已经填充好的前四行,填写最后四行。

for (int s=1;s<=k;s++) n/=2;④用一个for循环对③中提到的每一部分进行划分for(int t=1;t<=n;t++)对于第一部分,将其划分为四个小的单元,即对第二行进行如下划分:同理,对第二部分(即三四行),划分为两部分,第三部分同理⑤最后,根据以上for循环对整体的划分和分治法的思想,进行每一个单元格的填充。

填充原则是:对角线填充for(int i=m+1;i<=2*m;i++) //i控制行for(int j=m+1;j<=2*m;j++) //j控制列{ a[i][j+(t-1)*m*2] = a[i-m][j+(t-1)*m*2-m];/*右下角的值等于左上角的值*/a[i][j+(t-1)*m*2-m] = a[i-m][j+(t-1)*m*2];/*左下角的值等于右上角的值*/}例:由初始化的第一行填充第二行12345678 21436587由s控制的第一部分填完。

然后是s++,进行第二部分的填充12345678 21436587 34127856 43218765最后是第三部分的填充12345678 21436587 34127856 43218765 56781234 65872143 78563412 87654321⑥这样循环,直到填充完毕,a[][]数组被赋予新值。

3.Out()函数(1)函数功能:将安排好的赛事日程,即二维数组a[n][n-1]输出到屏幕。

(2)函数主要功能实现:函数主要运用一个for循环,将二维数组a[n][n-1]输出到屏幕。

for (i = 1; i<= n; i++){ for (j = 1; j<= n; j++){printf("%4d", a[i][j]);} printf("\n");} printf("\n");5 测试分析程序编译成功后,执行程序,在提示下输入k值,程序即可算出参赛的队员人数n(n = 2k),同时屏幕显示我们需要的循环赛日程表,程序运行结果如图5-1所示:图5-1结论程序主要运用了:数据输入、函数调用、函数传值、for循环以及二维数组等主要结构和功能。

根据分治算法,将本问题进行了由小规模到大规模的求解设计,程序设计的关键点在于如何对问题进行划分和填充公式的归纳。

在划分时,主要运用了两个for循环;在填充时,运用了两个for循环。

通过这次程序设计,加深了对分治算法的认识。

解决具体问题时,程序故重要,但一个好的算法更加重要。

本程序的得意之处在于,经过仔细研究,找到了划分的方法,并推导出了表格填充的两个公式。

不足之处也在此,即花费了很长时间来推导这个,对算法掌握还不够熟练。

参考文献[1] 王晓东.计算机算法设计与分析[M].北京:电子工业出版社,2007:102-121.[2] 严蔚敏吴伟民.数据结构(C语言版)[M].北京:清华大学出版社,1997:170-179.[3] 谭浩强.C程序设计(第三版) [M].北京:清华大学出版社,2005:1-378.[4] 王志刚李卫华著.需求工程导引[M].北京:人民邮电出版社,2003.[5] 陆惠恩著.实用软件工程[M].北京:清华大学出版社,2006.[6] 吕凤翥著.C++语言基础教程(第二版)[M].北京:清华大学出版社,2007.。

相关文档
最新文档