I’m having a problem writing an algorithm to return all possible valid matchups for a set of 32 teams. The rules are:
- The schedule is for only one game per pair of teams. This does not need to be a round robin as the teams do not all play each other. The algorithm needs to be all valid possibilities of the 16 games between the 32 teams, but not have any duplicated schedules (with games in different indexes, for example)
- Home/away does not matter and is not applicable here
- Each team only has a subset of 14 other teams that they are eligible to play.
- Teams must have an opponent. If a version of the schedule does not end up with all teams having a match, it is invalid and shouldn’t be returned.
The actual data for the teams and allowable opponents for each team is below:
[
{
"id": 1,
"opponents": [
8,
25,
28,
2,
20,
23,
19,
13,
10,
4,
21,
14,
32,
7,
],
},
{
"id": 2,
"opponents": [
20,
21,
32,
18,
25,
28,
31,
22,
23,
8,
30,
11,
1,
12,
],
},
{
"id": 3,
"opponents": [
26,
6,
29,
5,
24,
15,
12,
23,
13,
10,
9,
17,
31,
22,
],
},
{
"id": 4,
"opponents": [
14,
23,
19,
8,
18,
1,
31,
10,
30,
11,
25,
28,
26,
20,
],
},
{
"id": 5,
"opponents": [
10,
24,
9,
16,
22,
6,
29,
11,
26,
3,
27,
7,
19,
28,
],
},
{
"id": 6,
"opponents": [
26,
3,
29,
13,
10,
9,
17,
14,
5,
24,
15,
12,
18,
27,
],
},
{
"id": 7,
"opponents": [
16,
22,
27,
5,
24,
15,
12,
1,
26,
13,
10,
9,
17,
20,
],
},
{
"id": 8,
"opponents": [
25,
1,
28,
2,
20,
23,
19,
12,
9,
4,
21,
14,
32,
22,
],
},
{
"id": 9,
"opponents": [
5,
10,
24,
26,
3,
27,
7,
31,
16,
22,
6,
29,
23,
8,
],
},
{
"id": 10,
"opponents": [
5,
24,
9,
26,
3,
27,
7,
30,
16,
22,
6,
29,
4,
1,
],
},
{
"id": 11,
"opponents": [
30,
18,
31,
4,
2,
20,
14,
29,
21,
32,
23,
19,
5,
17,
],
},
{
"id": 12,
"opponents": [
13,
17,
15,
16,
22,
6,
29,
2,
31,
26,
3,
27,
7,
8,
],
},
{
"id": 13,
"opponents": [
17,
15,
12,
26,
3,
27,
7,
20,
30,
16,
22,
6,
29,
1,
],
},
{
"id": 14,
"opponents": [
4,
23,
19,
8,
18,
1,
31,
24,
30,
11,
25,
28,
6,
21,
],
},
{
"id": 15,
"opponents": [
13,
17,
12,
16,
22,
6,
29,
21,
18,
26,
3,
27,
7,
25,
],
},
{
"id": 16,
"opponents": [
22,
27,
7,
13,
10,
9,
17,
28,
29,
5,
24,
15,
12,
32,
],
},
{
"id": 17,
"opponents": [
13,
15,
12,
26,
3,
27,
7,
32,
11,
16,
22,
6,
29,
28,
],
},
{
"id": 18,
"opponents": [
30,
11,
31,
21,
32,
23,
19,
6,
4,
2,
20,
14,
24,
15,
],
},
{
"id": 19,
"opponents": [
4,
14,
23,
30,
11,
25,
28,
5,
8,
18,
1,
31,
29,
32,
],
},
{
"id": 20,
"opponents": [
2,
21,
32,
18,
25,
28,
31,
7,
4,
8,
30,
11,
1,
13,
],
},
{
"id": 21,
"opponents": [
2,
20,
32,
8,
30,
11,
1,
27,
14,
18,
25,
28,
31,
15,
],
},
{
"id": 22,
"opponents": [
16,
27,
7,
13,
10,
9,
17,
8,
3,
5,
24,
15,
12,
2,
],
},
{
"id": 23,
"opponents": [
4,
14,
19,
30,
11,
25,
28,
9,
8,
18,
1,
31,
3,
2,
],
},
{
"id": 24,
"opponents": [
5,
10,
9,
16,
22,
6,
29,
18,
26,
3,
27,
7,
14,
25,
],
},
{
"id": 25,
"opponents": [
8,
1,
28,
4,
21,
14,
32,
15,
24,
2,
20,
23,
19,
27,
],
},
{
"id": 26,
"opponents": [
3,
6,
29,
5,
24,
15,
12,
4,
13,
10,
9,
17,
30,
7,
],
},
{
"id": 27,
"opponents": [
16,
22,
7,
5,
24,
15,
12,
25,
6,
13,
10,
9,
17,
21,
],
},
{
"id": 28,
"opponents": [
8,
25,
1,
4,
21,
14,
32,
17,
5,
2,
20,
23,
19,
16,
],
},
{
"id": 29,
"opponents": [
26,
3,
6,
13,
10,
9,
17,
19,
5,
24,
15,
12,
11,
16,
],
},
{
"id": 30,
"opponents": [
11,
18,
31,
4,
2,
20,
14,
26,
21,
32,
23,
19,
10,
13,
],
},
{
"id": 31,
"opponents": [
30,
11,
18,
21,
32,
23,
19,
3,
4,
2,
20,
14,
9,
12,
],
},
{
"id": 32,
"opponents": [
2,
20,
21,
8,
30,
11,
1,
16,
19,
18,
25,
28,
31,
17,
],
},
]
I’m thinking there probably is a recursive solution that would be elegant for this, but I really am having a problem wrapping my head around it or finding the appropriately named algorithm that already exists.
I will be implementing this using javascript but obviously the algorithm is language independent. But any examples specifically in javascript/using javascript operators etc would help.
2
Answers
This can be accomplished by creating a nested loop that takes every pairing of a team and its opponent and adds it to the schedule if that pairing is not already included on the schedule. Here’s an example:
EDIT:
In response to your comment below, here’s a version of the above code that creates a new permutation for each element in the array:
The following code iterates over all possible combinations. There is a slight error, that combinations may be output several times consecutively, so you can either fix the bug, or check consecutively answers for equality.
The programming concept for this algorithm is called
Backtracking
, which I apply to a (sorted) list of possible matches.