I’m trying to create a UEFA Champions League 24 ‘Swiss Model’ competition featuring 36 teams. Each team will compete against 8 unique opponents, resulting in a total of 144 matches. I have already created a list of matchups. Is there a way to sort every matchup so that each team can have an equal number (4 in this case) of home and away games? The first position in a matchup indicates the home team, while the second position indicates the away team.
I have attempted to check if the total number of home games for the first team exceeds 4 matches (since there are 8 rounds). If it does, it becomes the away team. However, the results are still not equally distributed.
const matchups = [
[
"35",
"36"
],
[
"36",
"34"
],
[
"12",
"36"
],
[
"36",
"28"
],
[
"36",
"3"
],
[
"36",
"19"
],
[
"36",
"16"
],
[
"36",
"14"
],
[
"13",
"20"
],
[
"12",
"13"
],
[
"13",
"27"
],
[
"7",
"13"
],
[
"1",
"13"
],
[
"21",
"13"
],
[
"35",
"13"
],
[
"13",
"15"
],
[
"37",
"3"
],
[
"21",
"37"
],
[
"54",
"37"
],
[
"11",
"37"
],
[
"37",
"27"
],
[
"1",
"37"
],
[
"37",
"14"
],
[
"22",
"37"
],
[
"15",
"17"
],
[
"11",
"15"
],
[
"15",
"27"
],
[
"1",
"15"
],
[
"15",
"54"
],
[
"41",
"15"
],
[
"40",
"15"
],
[
"23",
"1"
],
[
"40",
"23"
],
[
"25",
"23"
],
[
"24",
"23"
],
[
"41",
"23"
],
[
"23",
"3"
],
[
"23",
"9"
],
[
"18",
"23"
],
[
"41",
"27"
],
[
"27",
"54"
],
[
"40",
"27"
],
[
"27",
"18"
],
[
"27",
"19"
],
[
"7",
"3"
],
[
"33",
"3"
],
[
"32",
"3"
],
[
"2",
"3"
],
[
"3",
"54"
],
[
"41",
"29"
],
[
"40",
"29"
],
[
"29",
"28"
],
[
"2",
"29"
],
[
"10",
"29"
],
[
"26",
"29"
],
[
"12",
"29"
],
[
"29",
"22"
],
[
"25",
"34"
],
[
"34",
"24"
],
[
"10",
"34"
],
[
"34",
"16"
],
[
"11",
"34"
],
[
"48",
"34"
],
[
"34",
"17"
],
[
"14",
"24"
],
[
"14",
"9"
],
[
"33",
"14"
],
[
"25",
"14"
],
[
"7",
"14"
],
[
"14",
"17"
],
[
"21",
"17"
],
[
"48",
"17"
],
[
"32",
"17"
],
[
"17",
"16"
],
[
"12",
"17"
],
[
"28",
"1"
],
[
"28",
"25"
],
[
"28",
"21"
],
[
"28",
"43"
],
[
"11",
"28"
],
[
"28",
"9"
],
[
"54",
"12"
],
[
"54",
"33"
],
[
"54",
"43"
],
[
"54",
"25"
],
[
"16",
"25"
],
[
"16",
"33"
],
[
"16",
"43"
],
[
"7",
"16"
],
[
"16",
"18"
],
[
"19",
"24"
],
[
"19",
"12"
],
[
"19",
"48"
],
[
"11",
"19"
],
[
"10",
"19"
],
[
"19",
"1"
],
[
"2",
"43"
],
[
"43",
"18"
],
[
"40",
"43"
],
[
"7",
"43"
],
[
"32",
"43"
],
[
"18",
"48"
],
[
"18",
"10"
],
[
"18",
"2"
],
[
"18",
"20"
],
[
"25",
"7"
],
[
"26",
"25"
],
[
"32",
"9"
],
[
"9",
"48"
],
[
"9",
"22"
],
[
"9",
"2"
],
[
"9",
"10"
],
[
"41",
"20"
],
[
"20",
"22"
],
[
"20",
"21"
],
[
"20",
"10"
],
[
"20",
"40"
],
[
"20",
"32"
],
[
"10",
"41"
],
[
"35",
"10"
],
[
"22",
"33"
],
[
"22",
"7"
],
[
"35",
"22"
],
[
"22",
"32"
],
[
"48",
"35"
],
[
"48",
"40"
],
[
"48",
"41"
],
[
"24",
"41"
],
[
"24",
"2"
],
[
"24",
"21"
],
[
"24",
"12"
],
[
"33",
"32"
],
[
"33",
"11"
],
[
"33",
"35"
],
[
"26",
"32"
],
[
"21",
"7"
],
[
"26",
"21"
],
[
"1",
"26"
],
[
"1",
"35"
],
[
"2",
"40"
],
[
"2",
"26"
],
[
"35",
"26"
],
[
"26",
"11"
],
[
"12",
"11"
]
]
const totalRounds = 8;
matchups.forEach((matchup) => {
matchup.sort((homeTeam, awayTeam) => {
const homeMatch = matchups.filter((m) => m[0] === homeTeam);
return homeMatch.length > (totalRounds / 2 ) ? 1 : -1;
});
});
const home = _.groupBy(matchups, m=> m[0])
const away = _.groupBy(matchups, m=> m[1])
console.log("home", home)
console.log("away", away)
console.log("combined",_.mergeWith(home,away, ((objValue,srcValue)=>{
if(Array.isArray(objValue)){
return objValue.concat(srcValue);
}
})))
2
Answers
Here’s an example for a 5-team pool:
Consider a Home/away match table for teams from A to E:
which means for instance that Team A plays home versus Team B and C, and away versus Team D and E.
I have arbitrary filled the home/away match matrix, but it is consistent with your rule: 2 home games and 2 away games for each team (in this 5-team pool example).
Now, if you add some randomness between your array of
[Team 1, Team 2, ...]
and the array of[Team A, Team B, ...]
, you would end up with a randomized championship, with the appropriate amount of home games and away games.I can add more details if this is not crystal clear.
EDIT:
I am unsure if all 9 teams of each pool must play with each other only once, or if each team of the 36 listed must play against 8 random opponents, avoiding any second encounter.
Solve this via max-flow-min-cut.
Create the network like this:
Nodes: Source, Sink, 1 per team, 1 per match.
Arcs:
Now, find the max flow through this network using max-flow-min-cut. Since all capacities are integers, we can find an integer solution (where all flows are integers). Interpret a flow from a team to a match as saying that team is playing at home in that match.
If a solution exists, it corresponds to a max flow of 144, 1 per match, and the max-flow-min-cut algorithm will find it.