Excel VBA功能解决了场地约束不可能的循环赛锦标赛名单

时间:2014-12-23 12:03:56

标签: excel vba excel-vba

我在制作具有以下条件的循环赛锦标赛名单时遇到了困难:

  • 10个团队(团队1 - 10)
  • 5个字段(字段A-E)
  • 9轮(第1轮至第9轮)
  • 每支球队必须完成一次其他球队的比赛。
  • 任何时候只有两支球队可以在场上比赛。 (即所有5个字段始终在使用中)
  • 任何球队都不得在任何特定场地上比赛超过两次。 < - 这就是问题!

我一直在尝试多年来在纸上解决这个问题而没有成功。所以,一劳永逸,我想在Excel VBA中生成一个函数来测试每个组合以证明它是不可能的。

我开始创建一个非常混乱的代码片段,使用嵌套的if / while循环生成一个数组,但我已经可以看到它只是不起作用。

那里有没有人可以解决多少代码?

编辑:感谢Brian Camire的方法,我已经能够包含更多理想的约束并仍然可以获得解决方案:

  • 没有团队连续两次播放相同的字段
  • 在重复
  • 之前,团队应该在所有字段上播放一次

解决方案如下。几年前我应该问过!再次感谢布莱恩 - 你是个天才!

 Round     1      2      3      4      5      6      7      8      9
Field A   5v10   1v9    2v4    6v8    3v7    4v10   3v9    7v8    1v2
Field B   1v7    8v10   3v6    2v9    4v5    6v7    1v8    9v10   3v5
Field C   2v6    3v4    1v10   5v7    8v9    1v3    2v5    4v6    7v10
Field D   4v9    2v7    5v8    3v10   1v6    2v8    4v7    1v5    6v9
Field E   3v8    5v6    7v9    1v4    2v10   5v9    6v10   2v3    4v8

2 个答案:

答案 0 :(得分:2)

我想我已经找到了至少一个问题的解决方案:

Round    Field    Team 1   Team 2
1        A        3        10
1        B        7        8
1        C        1        9
1        D        2        4
1        E        5        6
2        A        8        10
2        B        1        5
2        C        2        6
2        D        3        7
2        E        4        9
3        A        1        4
3        B        2        3
3        C        8        9
3        D        5        7
3        E        6        10
4        A        6        7
4        B        4        10
4        C        2        8
4        D        5        9
4        E        1        3
5        A        2        9
5        B        3        8
5        C        4        7
5        D        1        6
5        E        5        10
6        A        3        9
6        B        4        5
6        C        7        10
6        D        6        8
6        E        1        2
7        A        5        8
7        B        6        9
7        C        1        10
7        D        3        4
7        E        2        7
8        A        4        6
8        B        2        10
8        C        3        5
8        D        1        8
8        E        7        9
9        A        2        5
9        B        1        7
9        C        3        6
9        D        9        10
9        E        4        8

我发现它使用Excel的OpenSolver加载项(因为问题对于内置的Solver功能来说太大了)。步骤是这样的:

  1. 设置一个包含2025行的表,表示可能的匹配 - 也就是说,圆形,字段和一对团队的可能组合(如上表所示的列),以及一个将成为二进制的额外列(0或1)决定是否选择匹配的决策变量。
  2. 设置公式以使用决策变量来计算:a)每轮中每个球场的数量匹配,b)每对球队之间的比赛数量,c)每个球队每场比赛的比赛数量d)每个球队在每个球场的比赛次数。
  3. 设置公式以使用决策变量来计算匹配总数。
  4. 使用OpenSolver解决一个模型,其目标是通过更改步骤1中的决策变量来最大化步骤3中公式的结果,受制于决策变量必须为二进制的约束,来自步骤的公式的结果2.a)到c)必须等于1,步骤2.d)的公式结果必须小于或等于2.
  5. 详情如下......

    对于第1步,我设置了我的表,以便A,B,C和D列分别代表Round,Field,Team 1和Team 2,E列代表决策变量。第1行包含列标题,第2行到第2026行表示一个可能的匹配。

    对于步骤2.a),我在单元格I2到I10中设置了第1到第9轮的垂直列表,单元格J1到N1中的字段A到E的水平列表,以及用于计算数字的一系列公式在单元格J2到N10的每一轮中的每个字段中的匹配,从单元格J2中的=SUMIFS($E$2:$E$2026,$A$2:$A$2026,$I2,$B$2:$B$2026,J$1)开始,然后复制和粘贴。

    对于步骤2.b),我在单元格I13到I21中设置了一个队列1到9的垂直列表,单元格J12到R12中的对立队列2到10的水平列表,以及一系列公式来计算通过在单元格J13中以=SUMIFS($E$2:$E$2026,$C$2:$C$2026,$I13,$D$2:$D$2026,J$12)开始然后复制和粘贴,单元格J13到R21(包括对角线)的“右上三角半”中每对团队之间的匹配数。

    对于步骤2.c),我在单元格I24到I33中建立了一个队列1到10的垂直列表,单元格J23到R23中的第1到第9轮的水平列表,以及一系列计算数字的公式在J24到R33单元格中每个团队中的每个团队通过在单元格J24中以=SUMIFS($E$2:$E$2026,$C$2:$C$2026,$I24,$A$2:$A$2026,J$23)+SUMIFS($E$2:$E$2026,$D$2:$D$2026,$I24,$A$2:$A$2026,J$23)开始然后复制和粘贴来进行比赛。

    对于步骤2.d),我在单元格I36到I45中建立了一组1到10的垂直列表,单元格J35到N45中的字段A到B的水平列表,以及用于计算数量的公式数量的系列单元格J36到N45中每个团队在每个字段中播放的匹配,从单元格J36中的=SUMIFS($E$2:$E$2026,$C$2:$C$2026,$I36,$B$2:$B$2026,J$35)+SUMIFS($E$2:$E$2026,$D$2:$D$2026,$I36,$B$2:$B$2026,J$35)开始,然后复制和粘贴。

    对于第3步,我设置了一个公式,将单元格G2中的匹配总数计算为=SUM($E$2:$E$2026)

    对于步骤4,在OpenSolver模型对话框中(可从Data,OpenSolver,Model获得)我将Objective Cell设置为$ G $ 2,将Variable Cells设置为$ E $ 2:$ E $ 2026,并添加如上所述的约束和详细说明(抱歉,约束没有按照我描述的顺序列出):

    OpenSolver Model dialog

    请注意,对于步骤2.b)中描述的约束,我需要为每一行单独添加约束,因为如果约束包含“左下三角半”中的空白单元格,OpenSolver会引发错误消息。

    设置模型后,OpenSolver突出显示了目标,变量和约束单元格,如下所示:

    Set up worksheet with highlighted cells

    然后我使用OpenSolver解决了这个问题(通过Data,OpenSolver,Solve)。选定的匹配是E列中的1匹配。您可能会得到与我不同的解决方案,因为可能存在许多可行的匹配。

答案 1 :(得分:0)

来吧...这对于手动解决方案而言非常简单; - )

T1  T2  VE

1   2   A
1   3   A
1   4   B
1   5   B
1   6   C
1   7   C
1   8   D
1   9   D
1   10  E
2   3   A
2   4   B
2   5   B
2   6   C
2   7   C
2   8   D
2   9   D
2   10  E
3   4   C
3   5   C
3   6   D
3   7   D
3   8   E
3   9   E
3   10  B
4   5   C
4   6   D
4   7   D
4   8   E
4   9   E
4   10  A
5   6   E
5   7   E
5   8   A
5   9   A
5   10  D
6   7   E
6   8   A
6   9   A
6   10  B
7   8   B
7   9   B
7   10  A
8   9   B
8   10  C
9   10  C

至于我在同一场地上没有检查过两次以上的球队。请仔细检查。

将它分成几轮应该很容易。

编辑:这次只有5个场地: - )

编辑2:现在也有分配轮次: - )

编辑3:因为错误而再次删除了轮次分配。