生成没有重复项的配对组,php和mysql

生成没有重复项的配对组,php和mysql,php,mysql,Php,Mysql,我花了一年的时间试图弄明白这一点。我正在尝试建立一个支架跑步系统,用于跑保龄球支架 我有一个带有ID列和BowlerID列的表,称之为bowling\u bracket\u条目。ID是唯一的,但同一BowlerID可以有多个条目,范围从8到1个条目。我想做的是从BowlerID行中进行配对,但不要重复同一对,然后从这些配对中,将它们分成4对一组,在这4对中没有BowlerID重复 bowling.bracket_条目表的结构 ID | BowlerID 766 151 767 230 7

我花了一年的时间试图弄明白这一点。我正在尝试建立一个支架跑步系统,用于跑保龄球支架

我有一个带有ID列和BowlerID列的表,称之为bowling\u bracket\u条目。ID是唯一的,但同一BowlerID可以有多个条目,范围从8到1个条目。我想做的是从BowlerID行中进行配对,但不要重复同一对,然后从这些配对中,将它们分成4对一组,在这4对中没有BowlerID重复

bowling.bracket_条目表的结构 ID | BowlerID

 766    151
767 230
768 201
769 202
770 140
771 205
772 62
773 75
774 56
775 140
759 129
760 60
761 165
762 223
763 145
764 131
765 145
704 197
705 230
706 202
707 167
708 223
709 205
710 217
711 217
712 56
713 60
714 141
715 60
716 193
717 181
718 217
719 75
720 218
721 151
722 223
723 202
724 197
725 140
726 220
727 203
728 56
729 62
730 218
731 160
732 205
733 141
734 167
735 165
736 151
737 205
738 224
739 203
740 142
741 181
742 60
743 60
744 218
745 217
746 224
747 160
748 218
749 223
750 203
751 193
752 202
753 62
754 60
755 142
756 201
757 151
758 203
我尝试随机选择2个BowlerID,并将它们与一个分隔符(ie 22~100)放在一起,然后插入一个配对表,然后拉下一个配对(ie 36~92),创建该配对的变量反转(ie 92~36),并检查配对表中是否有匹配的值,如果没有找到,则插入,从Entries表中删除这些Bowlerid的ID并重复,直到值用完为止。问题是有时我会让一个保龄球和它自己配对。偶尔,我会得到一个完整的列表,没有与他们配对的BowlerID's

SELECT bracket_entries.ID, bracket_entries.BowlerID FROM bracket_entries ORDER BY rand() LIMIT 2
然后把它们放在一起,形成一对(即36~68)

如果找不到任何内容,则将配对插入配对表,然后继续下一个2

保龄球桌结构

    1 203~218
2 193~218
3 217~129
4 201~60
5 60~141
6 141~165
7 197~202
8 230~203
9 220~167
10 60~62
11 151~140
12 151~230
13 193~205
14 60~140
15 217~223
16 203~142
17 60~205
18 197~151
19 205~201
20 218~62
21 56~223
22 217~167
23 56~202
24 217~75
25 224~223
26 160~203
27 151~60
28 131~145
29 140~205
30 202~75
31 62~160
32 142~181
33 224~181
34 145~223
35 165~56
36 218~202

SELECT
PairingID, SUBSTRING_INDEX(Pairing, '~', 1) AS entry1,
SUBSTRING_INDEX(SUBSTRING_INDEX(Pairing, '~', 2), '~', -1) AS entry2
从括号_对

然后使用while循环在括号中显示配对,并将每个条目推入4对的数组中,直到其已满,然后进行比较以确保没有重复任何用户

while(($pairings=$rsEntries->fetch_assoc())&&($loop < 5)){
    $thisBowlerID1 = $pairings['entry1'];
    $thisBowlerID2 = $pairings['entry2'];

    if((!in_array($thisBowlerID1, $thisBracket)) || (!in_array($thisBowlerID2, $thisBracket))){
    while($players=$rsPlayers->fetch_assoc()){
            if($players['BowlerID'] == $thisBowlerID1){
                echo $players['BowlerID'].'<br>';
                //echo $players['Name'].'('.$players['CurrentAvg'].')<br>';
            } 
    } mysqli_data_seek($rsPlayers, 0);
    array_push($thisBracket, $thisBowlerID1);

    while($players=$rsPlayers->fetch_assoc()){
        if($players['BowlerID'] == $thisBowlerID2){
            echo $players['BowlerID'].'<br><br>';
            //echo $players['Name'].'('.$players['CurrentAvg'].')<br><br>';
    } 
    } mysqli_data_seek($rsPlayers, 0);
    array_push($thisBracket, $thisBowlerID2);

    $removeSQL="DELETE FROM bracket_pairings WHERE bracket_pairings.PairingID = ".$pairings['PairingID'];
    $removePairing = $connAdmin->query($removeSQL);
    $loop++;
    }
    $thisBracket = array();
}
}
如您所见,结果是保留8个未填充项

以下是未包含的剩余内容:

5   197~218
10  60~223
15  181~62
20  203~60
25  160~217
30  151~151
35  145~224

不知道为什么每五分之一都会跳过。我认为我的思路是正确的,但任何帮助或想法都会很好地解决我遇到的问题。

好的,首先:不要将配对保存为类似“203~60”的字符串。当您必须始终合并/拆分这些值时,使用数据库会更加困难。你的桌子应该在里面

第二:当您仍在构建配对时,不要将配对保存在数据库中。将它们保存在php的内存中,以避免任何不必要的数据库调用,只是为了查看是否已经添加了配对,这样会更快

也就是说,有一些算法你可以查找你的问题。您应该检查以下链接:

  • 在softwareengineering.stackexchange.com上发布他们的相关问题(这可能是一个更好的提问场所,但请检查重复项)
我可以想出一些算法,但在某些情况下会失败。算法的工作原理如下: 您可以使用上的算法为9个团队(每个团队有8名成员)创建日程安排。假设它们被称为“a”到“i”。配对将如下所示:

abcd  aibc  ahib  aghi afgh
hgfe  gfed  fedc  edcb dcbi

aefg  adef  acde  bcfg
cbih  bihg  ihgf  dehi
aaaaaabb
ccccddde
fffffggg
hhiijjjj
kkkkklll
mmmmnnnn
ooopppqq
rrrrrsss
ttuuvvww
aaaaaaaa
bbbbbbbb
cccccccj
dddddddj
eeeeeeej
fffffffj
gggggggj
hhhhhhhj
iiiiiiij
通过将“a”团队固定在适当的位置,并围绕桌子/配对旋转其余团队,您可以获得这种播种。但是,你必须跳过一个队,因为你有9个队有4*2个可能的种子。在第九组中,“a”组缺失,它包含剩余的“b”到“i”种子

当我们有9个团队,每个团队有8名成员时,他们可以表示为:

aaaaaaaa
bbbbbbbb
cccccccc
dddddddd
eeeeeeee
ffffffff
gggggggg
hhhhhhhh
iiiiiiii
当你有9个以上的团队时,你应该试着把他们组合在一起,就像他们属于一个8号的伪团队一样。可以这样看:

abcd  aibc  ahib  aghi afgh
hgfe  gfed  fedc  edcb dcbi

aefg  adef  acde  bcfg
cbih  bihg  ihgf  dehi
aaaaaabb
ccccddde
fffffggg
hhiijjjj
kkkkklll
mmmmnnnn
ooopppqq
rrrrrsss
ttuuvvww
aaaaaaaa
bbbbbbbb
cccccccj
dddddddj
eeeeeeej
fffffffj
gggggggj
hhhhhhhj
iiiiiiij
由于这些团队将在“同一”伪团队中,因此它们彼此不匹配,算法仍然有效

但是,如果无法将团队放入大小为8的伪团队中,则该算法将失败。假设您有两个团队,每个团队由8名成员组成,8个团队规模为7人。
伪团队如下所示:

abcd  aibc  ahib  aghi afgh
hgfe  gfed  fedc  edcb dcbi

aefg  adef  acde  bcfg
cbih  bihg  ihgf  dehi
aaaaaabb
ccccddde
fffffggg
hhiijjjj
kkkkklll
mmmmnnnn
ooopppqq
rrrrrsss
ttuuvvww
aaaaaaaa
bbbbbbbb
cccccccj
dddddddj
eeeeeeej
fffffffj
gggggggj
hhhhhhhj
iiiiiiij
在这种情况下,“c”排的“第8”名球员最终可能会与“d”排的“第8”名球员比赛,但他们实际上是在同一队。您可能会尝试将“c”行中的“第8位”玩家移动到“c”行中的其他位置。但是,当你在这条修复的道路上时,你无论如何都可以使用回溯算法


通过回溯,您可以强制执行所有组合,并在发现解决方案不起作用时跳过一个组合。检查上面的URL以了解回溯(动画gif可能会有帮助)。

请编辑您的问题,使其确实包含表格
条目
配对
的完整表格规范。特别是因为您谈论的是列
UserID
,但您的查询使用的是
BracketId
。此外,描述和SQL查询之间的表名似乎不相同。另外,添加72个条目的完整示例,以及如何在9个括号中填充它们。并解释72个初始条目是如何填写的。可能还会在9个括号中显示另一个填充,其中包含相同的72个条目,但它们配对错误(并标记该行)。我更新了问题,希望它能澄清一点。谢谢你的帮助