Excel VBAfunction解决不可能的循环赛比赛名单与场地的限制

我真的很难以下列条件产生一个循环赛的名单:

  • 10队(队1 – 10)
  • 5场(场A-E)
  • 9轮(第1 – 9轮)
  • 每个团队都必须一次玩所有其他团队。
  • 一次只有两支球队可以在场上打球。 (即所有5个领域始终在使用)
  • 任何球队不得在任何特定领域上打两次以上。 < – 这是问题!

我多年来一直试图解决这个问题,但没有成功。 所以,一劳永逸,我想在Excel VBA中生成一个函数来testing每个组合,以certificate这是不可能的。

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

有没有人可以解决一个多汁的代码?

编辑:感谢下面的布赖恩Camire的方法,我已经能够包括进一步可取的约束,仍然得到一个解决scheme:

  • 没有球队连续两次打同一场
  • 在重复之前,一个球队应该在所有的场上打球

解决scheme如下。 我应该问几年前! 再次感谢Brian – 你是个天才!

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 

我想我已经发现至less有一个解决scheme的问题:

  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插件(因为内置的求解器function的问题太大)。 步骤是这样的:

  1. build立一个包含2025行代表可能匹配的表格 – 也就是说,可能的轮次,字段和队伍组合(带有上表中的列),再加上一个额外的列,它将是一个二进制(0或1)指示是否select匹配的决定variables。
  2. build立公式,使用决策variables来计算:a)每轮比赛中每场比赛的数量相匹配,b)每队比赛的数量,c)每队每场比赛的比赛数量, d)每个队伍在每场比赛中的比赛数量。
  3. build立一个公式来使用决策variables来计算匹配总数。
  4. 使用OpenSolver来解决一个模型,其目标是通过改变来自步骤1的决策variables使得来自步骤3的公式的结果最大化,受限于决策variables必须是二进制的,来自步骤2.a的公式的结果)到c)必须等于1,并且来自步骤2.d)的公式的结果必须小于或等于2。

详情如下…

对于第1步,我build立了我的表格,使得A,B,C和D列分别代表回合,字段,队伍1和队伍2,列E代表决策variables。 第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中build立了1到9组的垂直列表,单元格J12到R12中的对手组2到10的水平列表,以及一系列计算匹配次数的公式=SUMIFS($E$2:$E$2026,$C$2:$C$2026,$I13,$D$2:$D$2026,J$12) )开始的单元格J13至R21(包括对angular线)的“右上angular三angular形一半” =SUMIFS($E$2:$E$2026,$C$2:$C$2026,$I13,$D$2:$D$2026,J$12)在单元格J13中,然后复制粘贴。

对于步骤2.c),我在单元格I24到I33中设置了1到10的垂直列表,单元格J23到R23中的1到9的水平列表以及一系列公式来计算所播放的匹配数=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)每个团队在每一轮中的单元格J24到R33 =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)在单元格J24中,然后复制粘贴。

对于步骤2.d),我在单元格I36到I45中设置了1到10组的垂直列表,单元格J35到N45中的字段A到B的水平列表以及一系列计算公式=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)在单元格J36中,然后复制粘贴。

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

对于第4步,在OpenSolver模型对话框(可从Data,OpenSolver,Model)中,我将Objective Cell设置为$ G $ 2,variables单元为$ E $ 2:$ E $ 2026,并添加了约束条件,对不起,这些约束没有按照我描述的顺序列出):

OpenSolver模型对话框

请注意,对于步骤2.b)中描述的约束条件,我需要为每一行分别添加约束条件,因为如果约束条件在“左下三angular半”中包含了空白单元格,OpenSolver会产生一条错误消息。

build立模型后,OpenSolver突出显示目标,variables和约束单元格,如下所示:

使用突出显示的单元格设置工作表

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

来吧…这是一个简单的手动解决scheme;-)

 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:再次删除轮次分配,因为它是错误的。