Esta clase genera un arreglo (tabla) conteniendo los cruces para una liga, donde todos los equipos se deben cruzar entre si. Ejemplo si tenemos 10 equipos se generara una matriz de 9 filas (Cantidad de Fechas necesarias) por 5 columnas (partidos por fechas), cada elemento contendrá una sub-matriz con los dos equipos que se enfrentaran, el siguiente cuadro muestra una representación de la matriz que se obtendrá.
Cerro
Peñarol
River Plate
Racing
Liverpool
Defensor SP.
Danubio
Wanderers
Nacional
Rampla Jrs
Rampla Jrs
Peñarol
Wanderers
Nacional
Defensor SP.
Danubio
Racing
Liverpool
Cerro
River Plate
River Plate
Peñarol
Liverpool
Cerro
Danubio
Racing
Nacional
Defensor SP.
Rampla Jrs
Wanderers
Wanderers
Peñarol
Defensor SP.
Rampla Jrs
Racing
Nacional
Cerro
Danubio
River Plate
Liverpool
Liverpool
Peñarol
Danubio
River Plate
Nacional
Cerro
Rampla Jrs
Racing
Wanderers
Defensor SP.
Defensor SP.
Peñarol
Racing
Wanderers
Cerro
Rampla Jrs
River Plate
Nacional
Liverpool
Danubio
Danubio
Peñarol
Nacional
Liverpool
Rampla Jrs
River Plate
Wanderers
Cerro
Defensor SP.
Racing
Racing
Peñarol
Cerro
Defensor SP.
River Plate
Wanderers
Liverpool
Rampla Jrs
Danubio
Nacional
Nacional
Peñarol
Rampla Jrs
Danubio
Wanderers
Liverpool
Defensor SP.
River Plate
Racing
Cerro

Código de la Clase:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<?php
/**
 * Clase Fixture.
 * Genera una tabla de cruces para un torneo tipo Single Round Robin. o de
 * liguilla.
 *
 * @author      Marcelo Castro
 * @package     Fixture creado en el projecto opet
 * @copyright   2011 - ObjetivoPHP
 * @license     Gratuito (Free) http://www.opensource.org/licenses/gpl-license.html
 * @author      Marcelo Castro (ObjetivoPHP)
 * @link        objetivophp@******.*****
 * @link        http://objetivophp.com
 * @version     0.0.1 (19/02/2011 - 21/02/2011)
 */
class Fixture
{
    /**
     * Cantidad de equipos participantes en el torneo.
     * @var integer
     */
    private $_cantidadEquipos   = 10;
 
    /**
     * Cantidad de equipos utilizados para armar el fixture.
     * Puede haber uno mas en caso de ser impar el numero de equipos.
     * @var integer
     */
    private $_equiposFixture;
 
    /**
     * Cantidad de fechas que contendra el torneo.
     * @var integer
     */
    private $_fechas;
 
    /**
     * Cantidad de partidos que se jugaran por fecha.
     * @var integer
     */
    private $_partidosXFechas;
 
    /**
     * Guarda la matriz del fixture, incluye el equipo ficticio en caso de que
     * sea necesario.
     * @var array
     */
    private $_fixture           = array();
 
    /**
     * Contiene los nombres de los equipos o en su defecto los numeros, que se
     * le otorgaron a cada uno.
     * @var array
     */
    private $_equipos           = array();
 
    /**
     * Contiene si se seudo-aleatoriza la tabla de cruces o no.
     * @var boolean
     */
    private $_aleatorio         = true;
 
    /**
     * Contiene que debe de ponerse cuando un cuadro queda libre, caso
     * de cantidad de cuadros impares.
     * @var string
     */
    private $_libre             = 'libre';
 
    /**
     * Metodo __construct.
     * @param   mixed     $equipos    Cantidad de equipos o arreglo con los nombres.
     * @return  void
     */
    public function __construct($equipos = null)
    {
        if (is_array($equipos)) {
            $this->_cantidadEquipos = count($equipos);
            $this->_equipos         = $equipos;
        } else {
            $this->_cantidadEquipos =  is_int($equipos)? $equipos : 10;
            for ($f = 0; $f <= $this->_cantidadEquipos; $f++) {
                $this->_equipos[$f] = $f+1;
            }
        }
 
        $this->_partidosXFechas = ceil($this->_cantidadEquipos /2 );
        $this->_equiposFixture  = $this->_cantidadEquipos +  $this->_cantidadEquipos % 2;
        $this->_fechas          = $this->_partidosXFechas * 2 - 1 ;
    }
 
    /**
     * Configura si se aleatoriza la tabla de cruces.
     * @param   boolean     $aleatorio
     * @return  void
     */
    public function setAleatorio($aleatorio = true)
    {
        $this->_aleatorio   = ($aleatorio)? true : false;
    }
 
    /**
     * Asigna el comentario para fecha libre.
     * @param   string  $cometario
     * @return  void
     */
    public function setFechaLibre($comentario)
    {
        $this->_libre = $comentario;
    }
 
    /**
     * Metodo tablaDeCruces.
     * Genera una matriz con los cruces correspondientes entre los equipos.
     * @return void
     */
    public function tablaDeCruces()
    {
        $fixture   = array();
        if ($this->_aleatorio) {
            shuffle($this->_equipos);
        }
 
        if ($this->_cantidadEquipos % 2) {
            $this->_equipos[$this->_equiposFixture-1] = $this->_libre;
        }
 
        // Lleno el indice A de cada elemento con numeros del numero 1
        // hasta llegar al maximo de fechas y vuelvo a comenzar en 1.
        // El ultimo numero puesto debe ser el maximo de fechas.-
        $datos      = $this->_partidosXFechas * $this->_fechas;
        for ($f = 1; $f <= $datos; $f++) {
 
            $col        = $f % $this->_partidosXFechas;
            $col        = ($col != 0)? $col : $this->_partidosXFechas;
            $fila       = ceil ($f / $this->_partidosXFechas);
            $auxiliar   = $f % $this->_fechas;
            if ($auxiliar == 0) {
                $auxiliar = (int) $this->_fechas;
            }
            $fixture[$fila][$col]['A'] = $this->_equipos[$auxiliar-1];
        }
 
        // Lleno el primer elemento de cada fila con el ultimo equipo
        // o el equipo ficticio, si la cantidad de equipo es impar.
        for ($f = 1; $f<= $this->_fechas; $f++) {
            $fixture[$f][1]['B']    = $this->_equipos[$this->_equiposFixture-1];
        }
 
        // Lleno el indice B de cada elemento empezando del maximo de fechas
        // hasta 1 y vuelvo a empezar salteo la primer columna que ya fue completada
        // en el ciclo anterior
        $indice = $this->_fechas;
        for ($f = 1; $f <= $this->_fechas; $f++) {
            for ($c = 2; $c <= $this->_partidosXFechas; $c++) {
                $fixture[$f][$c]['B']   = $this->_equipos[$indice - 1];
                if (--$indice == 0) {
                    $indice = $this->_fechas;
                }
            }
        }
        $this->_fixture     = $fixture;
    }
 
    /**
     * Retorna el arreglo de todos los cruces.
     * @return array 
     */
    public function getCruces()
    {
        return $this->_fixture;
    }
 
    /**
     * Metodo verCuadro.
     * Muestra la tabla de cruces en una tabla HTML, es solo a efectos demostrativos
     * @return  HTML
     */
    public function verCuadro()
    {
        echo "<table border=1>\n";
        for ($f = 1; $f <= $this->_fechas; $f++) {
            echo "<tr>\n";
            for ($c = 1; $c <= $this->_partidosXFechas; $c++) {
                echo "<td>";
                echo utf8_decode($this->_fixture[$f][$c]['A']);
                echo '</br>' . utf8_decode($this->_fixture[$f][$c]['B']);
                echo "</td>\n";
            }
            echo "</tr>\n";
        }
        echo "</table>";
    }
}

Método de Uso:
Como siempre por tratarse de una clase lo primero que debemos hacer es instanciarla,

$objFix     = new Fixture($equipos);
La variable $equipos, puede tomar dos tipos de datos, o puede ser un entero o puede ser un arreglo, si es un entero este sera tomado como la cantidad de equipos que participaran en el torneo. Si es un arreglo cada elemento del mismo debe ser el nombre de un equipo participante en el torneo y se tomara el tamaño del arreglo como la cantidad de equipos participantes.
// Primera forma pasamos un entero.
$equipos    = 10;
// Segunda forma pasamos un arreglo con los datos
$equipos    = array('Peñarol',
                    'Nacional',
                    'Liverpool',
                    'River Plate',
                    'Defensor SP.',
                    'Rampla Jrs',
                    'Wanderers',
                    'Cerro',
                    'Racing',
                    'Danubio');
// La definicion de la variable $equipos debe ser realizada antes de la instancia.

Configuraciones:

Solo tenemos dos métodos de configuración, setAleatorio y setFechaLibre.
setAleatorio solo recibe un parámetro de tipo boolean, donde si este es true generara la tabla en una forma seudo-aleatoria en realidad lo que realiza es un mezclado de los equipos pero no de la solución de cruces que siempre sera la misma. Por defecto se asume true
$objFix->setAleatorio(true);
// No es necesario para true pero es a modo de ejemplo.

setFechaLibre recibe un string (cadena de caracteres), que representa el comentario que se pondrá cuando un equipo tenga fecha libre.

$objFix->setFechaLibre('Libre');

Eso es lo único que podemos configurar.
Luego de realizar o no dicha configuración ejecutamos el método que genera la matriz de cruces.

$objFix->tablaDeCruces();

Por ultimo tenemos el método de captura de los resultados, para ello contamos con getCruces(), que nos retornara el arreglo o matriz con los emparejamientos de cuadros.

$cruces     = $objFix->getCruces();

Por ultimo mencionare el método tablaDeCruces() que en realidad esta puesto solo para ver en formato HTML la tabla de cruces, pero no debería formar parte de la clase.

Espero a alguien le sea de utilidad.