Avoid more than one duplicate opponent OK, I'm not sure if I can explain this:


*

*I have 12 players

*I want that each player play 3 times

*Each game is of 3 vs 3 players

*In each game each player plays with 2 different team members (no duplicate team members in the 3 matches)


I want that during the tournament each player avoid having more than one duplicate opponent (or none if possible)
Can you help me?
 A: Here's a near-solution using the Z3 SMT solver.
We represent our search space as a $12 \times 3 \times 2 \times 2$ array of 1's and 0's.  $X[p][r][g][t] = 1$ if player $p$ is on team $t$ of game $g$ in round $r$, and otherwise equals $0$.  We then require the following constraints:


*

*Each player plays once per round.

*Each team has exactly three players.

*No two players play together (on the same team) more than once.


We'd like to also satisfy:


*

*Each player has at least eight distinct opponents.


But I've had the solver running for a while with that constraint and haven't gotten a solution back yet.  So we settle for:


*

*Each player has at least seven distinct opponents.

*No two players play against each other more than twice.


Which gives this solution:


*

*Round 0, game 0: [1, 9, 10] vs. [0, 4, 6]

*Round 0, game 1: [2, 3, 8] vs. [5, 7, 11]

*Round 1, game 0: [0, 7, 10] vs. [2, 5, 6]

*Round 1, game 1: [8, 9, 11] vs. [1, 3, 4]

*Round 2, game 0: [4, 5, 9] vs. [1, 2, 7]

*Round 2, game 1: [6, 8, 10] vs. [0, 3, 11]


Here's the source code:
from z3 import *

X = [ [ [ [ Int("x_%s_%s_%s_%s" % (p,r,g,t)) 
            for t in range(2) ]
          for g in range(2) ]
        for r in range(3) ]
      for p in range(12) ]

# Each cell is 0 or 1
bits_c = [ Or(X[p][r][g][t] == 0, X[p][r][g][t] == 1)
           for t in range(2)
           for g in range(2)
           for r in range(3)
           for p in range(12) ]

# Each player plays once per round.
distinct_c = [ Sum([ X[p][r][g][t] 
               for t in range(2) for g in range(2) ]) == 1
               for r in range(3) for p in range(12) ]


# Each team has three players.
teamsize_c = [ Sum([ X[p][r][g][t] 
                     for p in range(12) ]) == 3
               for g in range(2)
               for r in range(3)
               for t in range(2) ]

# No two players play together more than once.
teammates_c = [ Sum( [X[p][r][g][t] * X[q][r][g][t]
                      for t in range(2)
                      for g in range(2)
                      for r in range(3)]) <= 1
                for p in range(12)
                for q in range(p) ]

# No two players play against each other more than twice.
opponents2_c = [ Sum( [X[p][r][g][0] * X[q][r][g][1] + 
                      X[p][r][g][1] * X[q][r][g][0]
                      for g in range(2)
                      for r in range(3)]) <= 2
                for p in range(12)
                for q in range(p) ]


# Each player has at least seven opponents.
opponents7_c = [ Sum( [ If(X[p][0][0][0] * X[q][0][0][1] +
                           X[p][0][0][1] * X[q][0][0][0] +
                           X[p][0][1][0] * X[q][0][1][1] +
                           X[p][0][1][1] * X[q][0][1][0] +
                           X[p][1][0][0] * X[q][1][0][1] +
                           X[p][1][0][1] * X[q][1][0][0] +
                           X[p][1][1][0] * X[q][1][1][1] +
                           X[p][1][1][1] * X[q][1][1][0] +
                           X[p][2][0][0] * X[q][2][0][1] +
                           X[p][2][0][1] * X[q][2][0][0] +
                           X[p][2][1][0] * X[q][2][1][1] +
                           X[p][2][1][1] * X[q][2][1][0] > 0,
                           1, 0) for q in range(12)]) >= 7
                 for p in range(12) ]

s = Solver()
s.add(bits_c + distinct_c + teamsize_c + 
      teammates_c + opponents2_c + opponents7_c)
if s.check() == sat:
    m = s.model()
    r = [ [ p for p in range(12)
            if str(m.evaluate(X[p][r][g][t])) == "1" ]
          for r in range(3)
          for g in range(2)
          for t in range(2)
          ]
    print_matrix(r)
else:
    print "no solution"

