运动员最佳配对问题实验报告

实验内容:

一、算法实现题:

1、问题描述:

羽毛球队有男女运动员各n人,给定2n×n矩阵PQP[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势;Q[i][j]则是女运动员i和男运动员j配合的女运动员竞赛优势。

由于技术配合和心理状态等各种因素的影响,P[i][j]不一定等于Q[j][i]。男运动员i和女运动员j配对组成混合双打的男女双方竞赛优势为P[i][j]*Q[j][i]。设计一个算法,计算男女运动员的最佳配对法,使各组男女双方竞赛优势的总和达到最大

 

2、编程任务:

设计一个算法,对于给定的男女运动员竞赛优势,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。

 

3、数据输入:

由文件input.txt给出输入数据;第一行有1个正整数n(1n20);接下来的2n行,每行n个数,前n行是P,后n行是Q

 

4、结果输出:

将计算的男女双方竞赛优势的总和的最大值输出到文件output.txt

           输入文件示例               输出文件示例

               intput.txt                   output.txt

               3                          52

               10 2 3

               2 3 4

               3 4 5

               2 2 2

               3 5 3

               4 5 1

二、解题思路

1、求问题的解空间

   对于n个男运动员,从第1个开始搭配女运动员:第1个有n种搭配方法,第2个有n-1种搭配方法……第n个有n-(n-1)种搭配方法;根据问题给出的示例:输入n的值为3,表示男女运动员各有3名;

男运动员 1 2 3按顺序搭配女运动员,他们分别对应的女运动员可以是:

女运动员 1 2 31 3 22 1 32 3 13 1 23 2 1

所以其解空间是{(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)},整个问题可看成是1,2,3的全排列问题,将解空间组织成一棵排列树如下

A

B

C

D

E

F

G

H

J

I

K

L

M

N

P

O

1

1

1

1

1

2

3

3

2

3

2

3

3

2

2

运动员最佳配对问题解空间树

男运动员3------>

男运动员2------>

男运动员1------>

解空间树的第i层到第i+1层边上的标号给出了变量的值。从树根到叶的任一路径表示解空间中的一个元素。

2、用深度优先的搜索策略搜索整个解空间

   用一个数组x记录可行解,并且赋初值为{0,1,2n}x[i]表示第i个男生配对的女生号;所以第i个男生与第x[i]个女生双方竞赛优势为P[i-1][x[i]-1]*Q[x[i]-1][i-1]

   t表示递归深度,初值为1,表示第1个男生开始搭配;t可以由n来控制。

   t>n时,表示算法已搜索到叶子结点,此时根据x的记录计算男女双方竞赛优势的总和s,算法如下:

   P[j][x[j+1]-1]*Q[x[j+1]-1][j]表示第j+1个男运动员与第x[j+1]个女运动员配对组成混合双打的男女双方竞赛优势

    int s=0;             //记录当前男女双方竞赛优势总和,计算前值为0

    for(int j=0;j<n;j++)

           s=s+P[j][x[j+1]-1]*Q[x[j+1]-1][j];

并判断s是否大于当前记录的男女双方竞赛优势的总和的最大值sum,若s>sum,则给sum赋值s

   t<=n时,表示还没有搜索到叶子结点,则需要继续往下搜索,从i=t开始搜索至i=n

for(int i=t;i<=n;i++){

       Swap(&x[t],&x[i]);      //交换x[t]x[i]的值,第t和第i个男运动员交换搭档

    //没有约束函数和限界函数

       Backtrack(t+1);         //进行第t+1个男运动员配对

       Swap(&x[t],&x[i]);      //交换回来它们的值,以便于与另外的另外的男运动员交换

}

三、算法描述 

#include "fstream.h"

 

ifstream fin("input.txt");

ofstream fout("output.txt");

 

int **P=NULL;

int **Q=NULL;

int *x=NULL;

int sum=0;                           //记录男女双方竞赛优势的总和的最大值  

int n;

//交换两个数

void Swap(int *b,int *y)

{       

       int z;

       z=*b;

       *b=*y;

       *y=z;

}

//求男女双方竞赛优势总和最大值函数

void Sum() 

{

    int s=0;                        //记录当前男女双方竞赛优势总和

       for(int j=0;j<n;j++)

              s+=P[j][x[j+1]-1]*Q[x[j+1]-1][j];

       if(s>=sum) sum=s;               //输出值

}

//回溯法搜索排列树

void Backtrack(int t)

{

       if(t>n) Sum();                  //当到叶子节点时

       else

              for(int i=t;i<=n;i++)

              {

                     //没有约束函数和限界函数的全排列问题

                     Swap(&x[t],&x[i]);

                     Backtrack(t+1);         //进行第t+1个男运动员配对

                     Swap(&x[t],&x[i]);

              }

}

void main()

{

       int i,j;

       int t=1;

       fin>>n;

    if(n<1||n>20)

       {

              fout<<"请输入正确的n的值!";

              return;

       }

       //动态分配数组空间

       x=new int[n+1];

       for(i=0;i<n+1;i++)

              x[i]=i;

    //P,Q分配nn列:从第00列到第n-1行第n-1

       P=new int*[n];      

       for(i=0;i<n;i++)

              P[i]=new int[n];

    Q=new int*[n];      

       for(i=0;i<n;i++)

              Q[i]=new int[n];

      

       for(i=0;i<n;i++)

              for(j=0;j<n;j++)

                     fin>>P[i][j];

    for(i=0;i<n;i++)

              for(j=0;j<n;j++)

                     fin>>Q[i][j];

       Backtrack(t);

       fout<<sum;                     //输出男女双方竞赛优势的总和的最大值

    //释放空间

    for(int k=0;k<n;k++)       

       {

              delete[] P[k];

          P[k]=NULL;

       }

    for(k=0;k<n;k++)       

       {

              delete[] Q[k];

          Q[k]=NULL;

       }

       fin.close();

    fout.close();

    return;

}

数据记录和计算:

 

序号

输入文件(input.txt)

输出文件(output.txt)

1.

3

10 2 3

2 3 4

3 4 5

2 2 2

3 5 3

4 5 1

52

2.

5

50 43 1 58 60

87 22 5 62 71

62 98 97 27 38

56 57 96 73 71

92 36 43 27 95

2 95 80 28 33

4 51 97 61 1

26 15 90 94 32

29 19 71 35 84

22 85 39 30 80

36077

3.

8

63 69 21 15 42 59 42 86

1 75 77 31 52 24 98 73

40 49 58 4 7 82 39 82

40 30 64 63 27 5 8 58

98 46 16 49 31 48 79 92

53 17 4 82 77 95 71 68

45 44 31 73 38 62 62 98

25 7 39 95 3 75 47 75

74 74 80 93 55 75 21 78

7 87 61 50 29 13 4 59

9 22 64 48 34 66 56 26

60 51 79 2 91 40 89 45

80 65 51 65 84 9 90 32

82 58 13 68 62 30 80 54

20 6 53 16 38 79 9 45

36 1 75 17 6 41 1 14

40653

4.

10

84 39 87 86 86 61 8 48 35 65

8 87 57 8 94 98 88 51 89 49

52 57 36 19 22 77 56 94 7 37

88 98 53 39 33 90 5 96 68 67

21 14 40 32 71 86 77 25 17 31

87 13 22 94 9 52 85 25 19 22

10 54 43 34 37 39 47 14 69 23

2 98 77 98 6 82 23 29 51 74

16 12 95 60 4 51 51 7 57 9

66 7 84 57 93 71 6 36 53 62

65 92 53 32 2 47 60 15 36 1

48 30 72 34 38 51 40 14 57 73

19 50 75 96 51 98 7 37 77 34

85 46 3 90 89 99 41 75 14 42

29 81 99 21 87 86 87 1 86 65

14 76 71 63 56 15 69 74 45 27

37 96 89 88 32 23 61 77 39 63

99 85 80 89 80 44 68 6 91 4

47 18 15 86 64 79 46 73 64 22

70 2 57 92 86 30 82 50 35 63

62502

5.

10

2 36 94 52 17 19 93 40 43 90

63 45 21 58 91 85 83 79 54 69

71 36 28 55 43 1 65 48 22 59

90 42 43 63 47 58 39 92 88 87

62 67 31 35 78 49 3 53 44 1

85 22 32 29 2 28 30 65 72 17

77 12 29 55 6 96 51 68 67 15

21 9 89 21 65 90 74 14 39 99

90 91 58 21 25 79 25 40 17 39

70 38 64 34 84 80 55 90 23 8

8 86 64 30 100 75 77 18 95 28

54 65 52 53 5 50 17 23 89 88

17 25 16 99 60 16 43 76 79 20

75 82 95 56 35 30 75 3 72 99

56 87 100 46 75 27 54 44 94 8

60 50 83 45 44 51 85 78 65 34

86 15 3 52 56 94 85 25 98 90

81 1 68 50 1 39 26 46 56 57

87 61 34 21 22 71 86 8 4 11

94 16 58 8 96 25 96 42 83 92

65487

6.

12

27 73 61 86 92 53 36 82 71 14 85 68

25 35 91 10 59 74 21 96 18 15 32 93

58 27 31 15 9 95 4 6 89 70 34 60

58 65 9 43 15 62 67 21 56 4 32 97

3 93 87 13 49 89 89 45 87 86 43 51

34 81 42 61 9 69 37 99 63 52 100 35

57 13 4 45 43 80 39 27 40 38 69 89

92 64 10 42 85 47 80 74 22 97 74 82

5 53 81 71 99 24 89 85 16 9 66 39

14 40 68 13 99 6 44 30 46 96 63 55

80 99 58 52 47 65 12 43 85 9 4 84

92 39 54 22 81 41 52 90 22 22 73 73

58 87 21 19 5 92 69 67 96 42 52 66

48 95 85 86 89 20 89 55 100 85 22 96

36 100 90 31 35 65 86 10 60 69 38 62

88 20 79 71 63 24 13 99 100 45 2 27

88 7 85 58 69 94 94 92 10 29 5 59

56 43 97 43 53 19 6 88 94 98 28 51

69 33 79 9 85 25 100 33 34 57 69 93

84 15 1 8 15 87 56 80 99 74 66 1

42 88 92 89 3 74 32 3 5 28 68 84

31 95 77 44 59 52 40 16 56 8 88 84

6 98 85 25 53 78 23 66 44 65 80 5

42 82 43 77 93 98 100 35 21 78 37 10

 

84593

结论(结果):

   这次实验是用回溯法来解决运动员最佳配对问题,程序成功通过编译,在起初调试的时候总是出现应用程序错误,“"0x00401057"指令引用的"0x00000000"内存不能为"written"。要终止程序,请单击"确定"。”后来经过单目调试,一步步解决了内存问题,至能正常运行,并得到正确的输出结果。

小结:

   通过这次实验,基本上掌握了用回溯法解题的算法框架,首先要理解问题,找出问题的解空间;其次是根据解空间画出解空间树;最后按照深度优先的搜索策略来搜索整棵树来得到最优解。

   实验让我更进一步地理解了回溯法的深度优先搜索策略,从根结点出发,根结点成为活结点,成为当前的扩展结点,搜索向纵深方向移至一个新结点,这个新结点会成为新的活结点,在当前扩展结点处不能再向纵深方向移动,当前扩展结点就成为死结点;此时往回移动至最近的一个活结点,就这样递归地在解空间中搜索,直到找到所要求的解或解空间中已无活结点为止。

 

 

自己以前的作业,做一下收藏而已

  • 20
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值