Fixture todos contra todos en C
#1
Posted 07 June 2012 - 12:18 AM
Tengo la necesidad de realizar un sistema que gestione un torneo de fútbol con el sistema todos contra todos.
Me tope con el problema a la hora de generar el fixture teniendo en cuenta que el numero de equipos es indeterminado.
¿Me podrian orientar de que forma lo podria realizar?
Utilizo Dev C++ como compilador
#2
Posted 07 June 2012 - 01:06 AM
"Equipos" equipos es un array que va desde 1 hasta N
for i = 1 to N-1 for j = i + 1 to N Enfrentar a Equipos[i] contra Euipos[j]
#3
Posted 07 June 2012 - 11:36 AM
Te respondo en seudocodigo:
"Equipos" equipos es un array que va desde 1 hasta N
delphi
for i = 1 to N-1 for j = i + 1 to N Enfrentar a Equipos[i] contra Euipos[j]
eso te arma una matriz, si a su vez, la armas de registros podes tambien guardar los resultados de los partidos u otras datos de necesites.
también podría ser así:
for i = 1 to N for j = 1 to N Enfrentar a Equipos[i] contra Euipos[j]
donde la diagonal principal, representa un equipo contra si mismo por lo que debe omitirse.
#4
Posted 07 June 2012 - 12:09 PM
Concretamente una matriz triangulareso te arma una matriz,
también podría ser así:
delphi
for i = 1 to N for j = 1 to N Enfrentar a Equipos[i] contra Euipos[j]
donde la diagonal principal, representa un equipo contra si mismo por lo que debe omitirse.
Considero que es preferible la versión triangular ya que es mucho más clara y no introduce redundancia. Es más, mucho más oportuna si efectivamente se arma una matriz triangular ya que directamente no solo nos ahorramos la redundancia sino memoria.
Para declarar una matriz triangular basta algo como:
// Toda matriz triangular es una matriz cuadrada // Esta es una matriz triangular superior SetLength(Matriz, N); for j := Low(Matriz) to High(Matriz) do SetLength(Matriz[j], N - j);
De este modo en Matriz(0) hay N columnas, en (1) tenemos N-1, en (2), N-2, y así hasta llegar a (N-1) con 1.
Saludos,
#5
Posted 07 June 2012 - 11:54 PM
Quiero mostrarles lo que hice de modo "genérico"y saber si fue mas o menos lo que me quisieron explicar.
Dejo el código. Estoy trabajando en C.
#include <stdio.h> #include <conio.h> int main() { int vec[8]; printf("Cargar equipos\n\n"); for (int i=0; i<8; i++) { printf("Equipo %d: ", i+1); scanf("%d", &vec[i]); } printf("\n\nFixture\n\n"); for (int i=0; i<8; i++) { for (int j=i+1; j<8; j++) { printf("[%d vs %d]\n", vec[i], vec[j]); } printf("\n"); } getch(); }
Este seria el resultado después de la ejecución.
Defino un vector de 8 posiciones para tomar como base solo 8 equipos en este caso. A los equipos los llamo "1, 2, 3, ... 8"
Fixture
[1 vs 2]
[1 vs 3]
[1 vs 4]
[1 vs 5]
[1 vs 6]
[1 vs 7]
[1 vs 8]
[2 vs 3]
[2 vs 4]
[2 vs 5]
[2 vs 6]
[2 vs 7]
[2 vs 8]
[3 vs 4]
[3 vs 5]
[3 vs 6]
[3 vs 7]
[3 vs 8]
[4 vs 5]
[4 vs 6]
[4 vs 7]
[4 vs 8]
[5 vs 6]
[5 vs 7]
[5 vs 8]
[6 vs 7]
[6 vs 8]
[7 vs 8]
NOTA: La idea del algoritmo es que los equipos se enfrenten una única vez en todo el torneo. Es decir que si en la fecha 1, el equipo A y B se enfrentaron, ya no pueden enfrentarse en las demás fechas.
Vi un procedimiento que se hace y se toma una lista con los nombres de los equipos divida en 2, se pone las dos listas una a lado de la otra y se deja al primer equipo de la lista de la izquierda como fijo y los demás van rotando en sentido horario.
Aquí el link.
http://blogs.monogra...es-automaticos/
¿Para realizar algo de esta forma, definiria una matriz de dos columnas y de filas igual a la cantidad de equipos divida en 2?
Gracias por su ayuda!
#6
Posted 08 June 2012 - 07:39 AM
¡Cierto! Estoy el foro de C y otros, se me había olvidado
GUN10 como está pensado, el sólo hecho de haber producido una salida del tipo matricial triangular garantiza de que sea un torneo Todos contra todos o también conocido Round Robin.
Eso que te comentamos es sólo la primera aproximación y genera la combinatoria de los enfrentamientos. Como ha recalcado Nikolas si cada posición de esta matriz fuera del tipo record se puede armar una estructura de modo que almacene información relevante, como ser la fecha en la que juegan, el resultado del partido, etc.
Asi como ha sido presentada la matriz, no puede decidir las fechas.
El algoritmo que sigue el artículo que nos enlazaste se ve interesante y tiene su lógica; aunque no lo he probado.
Respecto a tu pregunta, efectivamente, debes generar dos listas. Cada una con la mitad de los participantes. En caso de que sea una cantidad impar funciona igual, ya que se ha agregado este equipo llamado "libre" previamente y la división es exacta. De este modo en una de las dos listas quedará el equipo "libre" que al combinarse con el equipo de la otra lista dará como resultado que en dicha fecha ese equipo descanse. ¿Se entiende?
Es decir:
Cantidad Par:
Lista1 - Lista2
equipo1 - equipo2
equipo3 - equipo4
equipo5 - equipo6
....
equipoN-1 - equipoN
Cantidad Impar:
Lista1 - Lista2
equipo1 - equipo2
equipo3- equipo4
equipo5 - equipo6
...
equipoN - LIBRE
La forma interna en como lo manejes es de menos, aunque la idea de utilizar una matriz (N|N+1 x 2) es una buena idea.
Ahora bien si tu tienes por objetivo además que el fixture contemple cosas como: rotar de local - visitante, la distancia que hay de un equipo a otro para que los viajes sean más amenos y no tengan que desplazarse demasiado tanto tiempo, o la de distribuir de la mejor manera a los enfrentamientos entre los equipos chicos contra los grandes y otras cosas allí ya juegan otros tipos de cosas.
Justamente ayer vi en Proyecto G, un programa que se transmite por un canal educativo del gobierno (que es uno de sus pocos aciertos) este tema. Existe una fórmula matemática (que se basa en el concepto de combinatoria), que facilita estas cosas aunque aclararon que no se puede garantizar de que el fixture sea "perfecto". No he tomado nota de las fórmulas pero quien sabe, a lo mejor se puede encontrar algo buscando.
Recuerdo que mencionaron que el gobierno chileno había desarrollado ese modelo matemático por el año 2007, quizá eso ayude a filtrar la búsqueda.
En el caso del torneo argentino, al menos hasta hace 2 años para la 1ra división (A), se tenía una plantilla de un fixture predefinida de los equipos grandes con huecos vacios. Luego se "sacuden" la lista de los equipos chicos y se deja que vayan "cayendo". A medida que caen, se los ubica en los huecos y ¡Da, dá! tienes el fixture hecho.
Saludos,
#7
Posted 20 June 2012 - 07:00 AM
En el ejemplo que me pones, lista 1 y lista 2 serian 2 vectores independientes donde cada uno tendría una mitad de la cantidad de equipos?
Suponiendo que tengo 8 equipos, lista 1 tendría los equipos del 1 al 4 y lista 2 los equipos del 5 al 8 ?
Tengo que armar el fixture a partir de equipos cargador en un archivo!
#8
Posted 20 June 2012 - 02:05 PM
Si son 2 vectores independientes o una matriz que almacene en la columna 1 la lista 1, y en la 2da la lista 2 es un detalle menor.
Se puede hacerlo a como te guste o consideres más oportuno y fácil para ti.
Pero recuerda y ten presente que, a como está detallado el algoritmo en dicho sitio, que se rotan los equipos. Lo que puede sugerir que lo más óptimo sería mantener una matriz; aunque nada impide, si uno se da las mañas, implementar estas rotaciones sobre los 2 vectores.
El ejemplo y el orden de los equipos en cada lista que puse es algo elemental. En el artículo dice que se pueden ordenar por azar. De aplicar esta forma no necesariamente en la lista 1 estarán los equipos del 1 al N/2 sino que pueden, y de hecho lo estarán, desordenados.
Considero que estas preguntas y detalles son consideraciones menores. Mientras implementes las rotaciones adecuadamente y mantengas bien controlados a cada lista a medida que rotan lo demás es secundario.
Y fíjate que no interesa si los equipos lo lees desde un archivo o lo ingresas manualmente, etc. Repito: mientras mantengas bien ordenado la lista/matriz y las rotaciones en como se llene o de donde salgan los equipos, y/o si se meten ordenados o desordenados es algo independiente del procedimiento. Eso ya es una cuestión secundaria.
El algoritmo descripto en ese artículo es uno de entre muchos.
Yo de C no se por lo que en lo que hace a código no puedo ayudarte, lo siento.
Saludos,
#9
Posted 20 June 2012 - 07:44 PM
Al final en la busqueda, encontre este foro en el que explican como se podia realizar un fixture con el sistema todos contra todos.
Aplique lo que dice ahi y me funciono tanto para equipos impares como pares.
Creo un vector en el que guardo todos los equipos y a partir de el creo las dos matrices que se detallan.
No era tan complicado como lo veia!
Gracias por su ayuda
#10
Posted 20 June 2012 - 08:28 PM
Me alegro de que gracias a nuestras orientaciones hayas logrado llegar a buen puerto.
Si no es mucha molestia, sería muy oportuno que nos comentes tu solución.
Recuerda que este foro se construye con el aporte de todos y puede que alguien más con tu misma (o parecida) duda se pase por aquí; y esto puede resultarle de interés, o a modo de guía, en como proceder.
Saludos,
#11
Posted 22 June 2012 - 08:21 AM
Les cuento mas o menos como lo hice.
El algoritmo que se aplica es el siguiente.
Teniendo un numero "x" de equipos por ejemplo 6, lo que hago disponerlos de la siguiente manera considerando a la cantidad de equipos menos 1, es decir los equipos desde el 1 hasta el 5.
1 2 3
4 5 1
2 3 4
5 1 2
3 4 5
La cantidad de columnas me lo indica la cantidad de equipos divida en dos. En este caso 3 columnas si considero 6 equipos.
La cantidad de filas me lo determina la cantidad de equipos menos uno. Para el ejemplo, 5 filas.
Ahora a la primer columna le agrego el equipo restante que seria el equipo numero 6. Entonces quedaria
1-6 2 3
4-6 5 1
2-6 3 4
5-6 1 2
3-6 4 5
Y por ultimo a partir de la segunda columna voy formando las demas "parejas" que faltan con los equipos de forma descendente, desde el ultimo (sin considerar al equipo 6 que ya fue agregado) hasta el primero.
1-6 2-5 3-4
4-6 5-3 1-2
2-6 3-1 4-5
5-6 1-4 2-3
3-6 4-2 5-1
De esta manera ya quedaria armado el fixture donde cada fila correspondería a la fecha y cada columna (que seria cada pareja que hay en esa fila) a los partidos.
Siguiendo el ejemplo
[table]
[tr]
[td]FECHA 1[/td]
[td]1vs6[/td]
[td]2vs5[/td]
[td]3vs4[/td]
[/tr]
[tr]
[td]FECHA 2[/td]
[td]4vs6[/td]
[td]5vs3[/td]
[td]1vs2[/td]
[/tr]
[tr]
[td]FECHA 3[/td]
[td]2vs6[/td]
[td]3vs1[/td]
[td]4vs5[/td]
[/tr]
[tr]
[td]FECHA 4[/td]
[td]5vs6[/td]
[td]1vs4[/td]
[td]2vs3[/td]
[/tr]
[tr]
[td]FECHA 5[/td]
[td]3vs6[/td]
[td]4vs2[/td]
[td]5vs1[/td]
[/tr]
[/table]
Para el caso en el que el numero de equipos es impar, lo que hago es agregar un equipo mas, que vendria a ser un equipo ficticio y cuando un equipo se enfrenta a el significaria que ese equipo, en esa fecha queda libre (no juega).
Vi muchas formas para crear el fixture y por ahi ma aleatorias a la hora de determinar los enfrentamientos, agregando partidos de local, de visitante pero este algoritmo me parecio interesante y facil de implementar. Ademas cumple con los requisitos de que los enfrentamientos sean de "todos contra todos" y que no haya enfrentamientos repetidos.
A la hora de codificar, lo que hice fue generar dos matrices
[table]
[tr][td]Matriz 1
1 2 3
4 5 1
2 3 4
5 1 2
3 4 5[/td]
[td] [/td]
[td]Matriz 2
6 5 4
6 3 2
6 1 5
6 4 3
6 2 1[/td][/tr]
[/table]
Combinandolas posicion a posicion voy formando los enfrentamientos considerando la fila en la que estoy parado para poder tener en cuenta la fecha a la que pertecen los partidos.
Me parecio mas facil trabajar con dos matrices pero quizas se lo puede resolver utilizando solo una.
Espero que se haya entendido, saludos !!
#12
Posted 02 December 2016 - 09:24 PM
#include<iostream> #include<cstdlib> #include<string> using namespace std; int main() { string equipo[30]; int n; cout << "--------------> SOCCER APP <----------------" << endl; cout << endl; cout << "** Si el numero de equipos a agregar es impar anadir un (equipo fantasma) **" << endl; cout << "** Este mostrara el equipo que descansara una de las jornadas **" << endl; cout << endl; cout << "Ingrese un numero par de equipos: " << endl; cin >> n; if (n % 2 == 0) { for (int x = 0; x < n; x++) { getline(cin, equipo[x]); cout << "Ingrese el nombre del equipo" << " " << x + 1 << ":" << endl; cin.ignore(256, '\n'); } for (int x = 0; x < n; x++) { for (int j = x + 1; j < n; j++) { cout << equipo[x] << " vs " << equipo[j] << endl; } cout << "\n"; } } else { cout << "El numero de equipos seleccionados es impar NO se puede contiinuar :(" << endl; } system("pause"); }
Estoy utilizando c++
#13
Posted 03 December 2016 - 10:56 AM
Bienvenido, Ronny.
Este hilo es muy antiguo. Deberías abrir otro exponiendo claramente cual es el problema con precisión y tus dudas al respecto.
Saludos.