Foros del Web » Programando para Internet » Javascript »

Programa para equipos

Estas en el tema de Programa para equipos en el foro de Javascript en Foros del Web. No es muy claro el titulo, no se como titularlo. La idea es armar un programa, que tenga cierta cantidad de nombres de personas, con ...
  #1 (permalink)  
Antiguo 07/04/2015, 13:02
 
Fecha de Ingreso: diciembre-2011
Mensajes: 34
Antigüedad: 12 años, 3 meses
Puntos: 0
Programa para equipos

No es muy claro el titulo, no se como titularlo.

La idea es armar un programa, que tenga cierta cantidad de nombres de personas, con un puntaje del 1 al 10, lo cual de esa lista pueda seleccionar a 10 personas, luego al correr el programa, que automaticamente lo divida en 2 grupos, y que la suma de cada grupo, entre si, de casi similar.

Osea, selecciono 10 nombres, y la suma de los grupos da A=43; B=45, necesito que me muestre los nombres, como fueron dividos.

Mas que nada necesitaria el algoritmo matematico, la cuenta que tendria que hacer para que sume y pruebe hasta que den parecido las dos sumas.

Gracias.

El fin del programa, es para armar equipos de futbol entre amigos, siempre estamos 10 minutos viendo quienes somos y repartiendonos para que salga parejo el partido. Entonces la idea es tener un puntaje para cada uno, y correr el programa con los presentes y probar si resulta XD.
  #2 (permalink)  
Antiguo 07/04/2015, 13:37
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Programa para equipos

Interesante.

No lo he comprobado pero intuyo que para obtener el resultado óptimo deberías ordenar las personas según su puntuación de mayor a menor.

Luego deberías ir cogiendo repetidamente la persona con mayor puntuación y ponerla en el grupo que la suma sea de menor puntuación hasta que hayas repartido todas la personas en los dos grupos.

Edit: no es el algoritmo optimo. Por ejemplo hay las siguientes puntuaciones
51,49,35,32,31
Según mi algoritmo quedaría:
Grupo A: 51, 32, 31
Grupo B: 49, 35

Cuando
Grupo A: 51, 49
Grupo B: 35, 32, 31
es una repartición mejor.

Supongo que habrá que usar algún algoritmo de grafos.
Un saludo!
__________________
github.com/xgbuils | npm/xgbuils

Última edición por Pantaláimon; 07/04/2015 a las 13:44
  #3 (permalink)  
Antiguo 07/04/2015, 15:16
 
Fecha de Ingreso: diciembre-2011
Mensajes: 34
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Programa para equipos

Tendria que ser un loop que sume 5 y 5 y el resultado de las dos sumas los reste entre si, cuando da en un rango de -5 a 5, ya estaria "equilibrado".

Calculo que una pc no tardaria en probar todas las combinaciones hasta que de el resultado. Tengo las ideas pero muy incompletas.

Necesito armar la lista primero, con 20 elementos. (a, b, c, d, e, f, g, h, i, j, k, l..etc) cada elemento asignarle un valor, del 1 al 10.

Cuando selecciono 10 que empieze a sumar a+b+c+d+e y f+g+h+i+j, el resultado lo resta entre si, si da -5 -4 -3 -2 -1 0 1 2 3 4 5 que muestre que sumas hizo, si no, que entre de nuevo al loop y sume, no se b+c+d+e+f y a+g+h+i+j y asi.

¿lo ven posible?
  #4 (permalink)  
Antiguo 07/04/2015, 15:44
 
Fecha de Ingreso: diciembre-2011
Mensajes: 34
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Programa para equipos

Si me dan una mano, paso a paso, creo que puedo llegar a resolverlo.
Lo primero que necesito es armar la lista de los elemtos con el valor oculto, poder seleccionar 10, y apretar un boton que me vaya a otra pagina, sacar de la url los elemtos con los valores ocultos.

Opcion 1 []
Opcion 2 []
Opcion 3 []
Opcion n []
Opcion .. []

"calcuclar >>"

opcion 2 = 4
opcion 3 = 8
opcion n = n

Si me pueden facilitar eso, de ahi, yo guardo todo un variable diferentes y veo como hago el loop.
  #5 (permalink)  
Antiguo 07/04/2015, 18:25
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Programa para equipos

Se me ocurre algo como esto:

Código Javascript:
Ver original
  1. var todos = [5, 2, 3, 8, 4, 7, 5, 9, 6, 2],
  2.     grupo1 = [], grupo2 = [], tot1 = 0, tot2 = 0;
  3.  
  4. grupo1.push(Math.max.apply(null, todos)); //Obtengo el valor mayor y lo inserto en 'grupo1'
  5. tot1 += Math.max.apply(null, todos); //Acumulo el valor en 'tot1'
  6. todos.splice(todos.indexOf(Math.max.apply(null, todos)), 1); //Y lo quito de 'todos'
  7.  
  8. grupo2.push(Math.max.apply(null, todos)); //Obtengo el nuevo valor mayor y lo inserto en 'grupo2'
  9. tot2 += Math.max.apply(null, todos); //Acumulo el valor en 'tot2'
  10. todos.splice(todos.indexOf(Math.max.apply(null, todos)), 1); //Y lo quito de 'todos'
  11.  
  12. for (var i = 0, l = todos.length; i < l; i++){
  13.     r = tot1 - tot2;
  14.     if (r <= 5 && r >= -5){
  15.         if (tot1 > tot2){
  16.             grupo2.push(todos[i]);
  17.             tot2 += todos[i];
  18.         }
  19.         else{
  20.             grupo1.push(todos[i]);
  21.             tot1 += todos[i];
  22.         }
  23.     }
  24.     else{
  25.         if (tot1 > tot2){
  26.             grupo2.push(todos[i]);
  27.             tot2 += todos[i];
  28.         }
  29.         else{
  30.             grupo1.push(todos[i]);
  31.             tot1 += todos[i];
  32.         }
  33.     }
  34. }
  35.  
  36. console.log(grupo1, grupo2); //[9, 2, 3, 7, 6] [8, 5, 4, 5, 2] | tot1 - tot2 = 3

Trabajando con los rangos que estableciste en uno de tus comentarios, la adición de elementos a un array u otro dependerá ya sea de si la diferencia se encuentra dentro del rango. Quizá pueda hacerse esto de una manera más eficiente, esta es solo una primitiva y básica idea.

Edito: Repensando el algoritmo, creo que es mejor empezar por tomar a los dos mayores valores del array inicial, colocarlos en los arrays y a partir de ahí empezar la selección. Como cuando los dos mejores son los que forman a los equipos en un partido de fútbol entre amigos (al menos así jugábamos ).

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 07/04/2015 a las 20:07 Razón: Mejora
  #6 (permalink)  
Antiguo 07/04/2015, 21:39
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: Programa para equipos

buenas...
la naturaleza del tema me resulta un ejercicio interesante, asi que no pude evitar intentarlo. solo que lo hice en lapiz y papel con diferentes secuencias tratando de buscar un patron. mas o menos este es el modelo que tengo:
  • reparte todos los numeros en dos grupos. puede ser aleatorio, secuencial, de uno en uno, u otro metodo. no importa el metodo, pues el objetivo principal no es darle un orden a los grupos.
  • intercambia (swap) los valores de la misma posicion en ambos arrays, moviendo el numero mayor hacia el array que la suma sea menor.
  • repites el proceso de intercambio con el resto de las posiciones hasta que la diferencia de ambos arrays se aproxime al limite de lo que se considera "estable". en tu ejemplo, -5 a 5.

no digo que sea el mejor metodo, pero quizas sea bastante razonable. la diferencia con el metodo de alexis es que su algoritmo desde un principio va asignando los valores en condicion de la suma computada. tampoco parte de la premisa de balancear la carga asignando los numeros mayores en distintos grupos. si bien entiendo el argumento valido de que los valores mayores (mejores del equipo) son la base del grupo, en teoria los grupos se balancean cuando la suma son lo suficiente similar.

luego de tenerlo funcionando y para complicar mas el ejercicio, lo interesante seria generalizar el algoritmo para que dado X numeros, los reparta en partes iguales para X numero de grupos.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #7 (permalink)  
Antiguo 08/04/2015, 06:27
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Programa para equipos

Backtracking puro, sobre un algoritmo óptimo de selección general (cualquier número de equipos, cualquier diferencia máxima de tamaño de equipo).

Se puede mejorar mucho, haciendo ramificación y poda. Pero como las operaciones que realiza son sencillas, para 20 elementos no tiene demasiado coste de tiempo (2 segundos, por lo menos en una cpu i5).
A partir de ahí empieza a dispararse el tiempo, por lo que para meter mas elementos se estaría obligado a podar.

http://jsfiddle.net/marlanga/1aqzp30q/

Código Javascript:
Ver original
  1. Array.prototype.sum = function() {
  2.     return this.length ? this.reduce(
  3.         function(a, b) {
  4.             return a + b;
  5.         }
  6.     ) : 0;
  7. }
  8.  
  9. function Equipo(){
  10.     this.miembros = [];
  11. }
  12.  
  13. Equipo.prototype.pop = function() {
  14.     return this.miembros.pop();
  15. }
  16.  
  17. Equipo.prototype.push = function(miembro) {
  18.     this.miembros.push(miembro);
  19. }
  20.  
  21. Equipo.prototype.sumar = function() {
  22.     return this.miembros.sum();
  23. }
  24.  
  25. Equipo.prototype.length = function() {
  26.     return this.miembros.length;
  27. }
  28.  
  29. Equipo.prototype.clonar = function() {
  30.     var clon = new Equipo();
  31.     for (var i = 0, n = this.miembros.length; i < n; i++) {
  32.         clon.push(this.miembros[i]);
  33.     }
  34.     return clon;
  35. }
  36.  
  37. function RyP(disponibles, numero_equipos, cantidad_miembros_diferencia) {
  38.     this.disponibles = disponibles;
  39.     this.equipos=[];
  40.     this.nEquipos = numero_equipos;
  41.     this.cantidad_miembros_diferencia = cantidad_miembros_diferencia;
  42.  
  43.     this.mejor_solucion = {
  44.         diferencia : Infinity,
  45.         equipos : null
  46.     };
  47.  
  48.     this.crearEquipos();
  49. }
  50.  
  51. RyP.prototype.crearEquipos = function() {
  52.     for(var i = 0; i < this.nEquipos; i++) {
  53.         this.equipos.push(new Equipo());
  54.     }
  55. }
  56.  
  57. RyP.prototype.exec = function() {
  58.     if (this.disponibles.length === 0) {
  59.         this.comparaSolucion();
  60.     } else {
  61.         var miembro = this.disponibles.pop();
  62.         for(var i = 0; i < this.nEquipos; i++) {
  63.             this.equipos[i].push(miembro);
  64.             this.exec();
  65.             this.equipos[i].pop();
  66.         }
  67.         this.disponibles.push(miembro);
  68.     }
  69. }
  70.  
  71. RyP.prototype.comparaSolucion = function() {
  72.     if (this.maximaDiferenciaCantidadMiembros() > this.cantidad_miembros_diferencia) return;
  73.     var diff = this.maximaDiferenciaPesoEquipo();
  74.     if (diff >= this.mejor_solucion.diferencia) return;
  75.  
  76.     this.mejor_solucion.diferencia = diff;
  77.     var clon_equipos = [];
  78.     for(var i = 0; i < this.nEquipos; i++) {
  79.         clon_equipos.push(this.equipos[i].clonar());
  80.     }
  81.     this.mejor_solucion.equipos = clon_equipos;
  82. }
  83.  
  84. RyP.prototype.maximaDiferenciaCantidadMiembros = function() {
  85.     return this.maximaDiferencia();
  86. }
  87.  
  88. RyP.prototype.maximaDiferenciaPesoEquipo = function() {
  89.     return this.maximaDiferencia(true);
  90. }
  91.  
  92. RyP.prototype.maximaDiferencia = function(condicion) {
  93.     var menor = condicion ? this.equipos[0].sumar() : this.equipos[0].length();
  94.     var mayor = menor;
  95.  
  96.     for(var i = 1; i < this.nEquipos; i++) {
  97.         var length = condicion ? this.equipos[i].sumar() :  this.equipos[i].length();
  98.         menor = Math.min(length, menor);
  99.         mayor = Math.max(length, mayor);
  100.     }
  101.  
  102.     return Math.abs(mayor - menor);
  103. }
  104.  
  105.  
  106.  
  107. var miembros = [51,49,35,32,31];
  108. var numero_equipos = 2;
  109. var diferencia_maxima_cantidad_miembros_por_equipo = 1;
  110. var resolvedor = new RyP(miembros,numero_equipos, diferencia_maxima_cantidad_miembros_por_equipo);
  111. resolvedor.exec();
  112. console.log(resolvedor.mejor_solucion);

Última edición por marlanga; 08/04/2015 a las 06:34

Etiquetas: calculadora, promedio, suma
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:35.