Atascado en algoritmo de ponderación

RaymaN

Hola, estoy atascado tratando de repartir unos elementos entre distintas categorías, llevo ya bastantes horas y creo que toca pedir ayuda xD

Tengo una lista de elementos (por ejemplo fruta), ordenados por una determinada propiedad (por ejemplo precio). Necesito dividirlas en 5 categorías ponderadas por precio y luego repartirlas entre varias cajas según su color.

La repartición ponderada la tengo hecha. Si tengo 100 frutas, la primera categoría contendrá las 20 más caras, la siguiente 40, la siguiente 80 y así. No es exactamente el doble pues depende del total pero la repartición la tengo correctamente.

Cada caja debe recibir una cantidad exacta en cada una:

  • Caja frutas rojas: 2 frutas
  • Caja frutas verde: 4 frutas
  • Caja frutas amarillas: 6 frutas
  • Caja frutas azules: 3 frutas

Estas frutas deben ser de las siguientes categorías:

  • Categoría 1: 1 fruta
  • Categoría 2: 2 frutas
  • Categoría 3: 3 frutas
  • Categoría 4: 4 frutas
  • Categoría 5: 5 frutas

El fallo en el algoritmo que tengo ahora es que si he agotado las frutas de categoría 1 en la caja verde y todas las frutas rojas son de categoría 1, no podré tener ninguna roja.

No sé si se entiende muy bien. Si no es así, intentaré hacer un dibujo más claro, pero a esta hora no se me ocurre mejor explicación xD

Gracias!

Edito: he puesto colores en vez de numeración para que se entienda algo mejor.

eXtreM3

No entiendo una cosa, arriba pones que una vez divides las frutas en las 5 categorías, las repartes aleatoriamente por las 4 cajas. Sin embargo debajo indicas que cada caja debe recibir una cantidad exacta de frutas.

Una fruta, independientemente de su precio, puede estar en cualquier caja?

1 respuesta
JuAn4k4

No se entiende nada, por mucho que lo leas.

Tienes 100 frutas ordenadas por precio.
¿ Qué tienes que hacer con ellas ?
¿ Cómo categorizas las frutas ?
¿ Que significa ponderar para ti ? Porque creo que no significa lo mismo que para mi.
¿ Para qué sirve la numeración del 1 al 4 ? ¿ Es esto el peso (ponderación) de la fruta ?

1) Categorizar ¿ Cómo ?
2) Poner en cajas ¿ Qué son las cajas ? ¿ Qué significan ? ¿ Cómo ?

2 respuestas
HeXaN

Yo por más que lo leo sólo puedo pensar en la mochila 0/1 xD

E

No sé si lo entendí bien. Que tal si primero lees todas las frutas, las almacenas en una variable auxiliar ya ordenadas por precio y luego las repartes?

1 respuesta
eXtreM3

#3

  • Todas las frutas han de meterse en alguna caja.
  • Las frutas se meten en las categorías de forma ponderada por "precio". Eso dice que ya lo tiene hecho, así que nos lo saltamos.
  • Ponderar es igual para todo el mundo xD, un elemento con más peso (en este caso precio) tiene más importancia sobre la media global que uno con menos peso (precio). Imagino que estamos de acuerdo aquí todos.
  • La numeración del 1 al 4 en las cajas es porque es un número cerrado de cajas, son 4 cajas en total, aunque haya 4 millones de frutas a distribuir en esas cajas.

Eso es lo que yo he entendido, y aparte mi duda de #2

A ver si se levanta, que por lo visto se tiró hasta las tantas programando :D x'D

1 respuesta
RaymaN

Aquí estoy de nuevo, pensé que no contestaría nadie xD

He editado #1 con cajas según el color de fruta y no numeradas para que se entienda mejor. La ponderación es para que la repartición sea lo más equitativa posible, pues el proceso debe repetirse hasta agotar las frutas.

#2 sí, el precio solo sirve para elegir su categoría, luego puede caer en cualquier caja.

#3 tengo que repartirlas según su color. Se categorizan según el precio. Las más caras son categoría 1 y solo hay 20, las siguientes son categoría 2 y hay 40, y así hasta categoría 5 que es donde más hay.
Luego, de cada categoría cojo 1, 2, 3, 4 y 5 (15 en total) frutas respectivamente, y han de rellenar las cajas de forma exacta: 2, 4, 6 y 3 (15 en total).

#5 eso ya lo hago pero entra en juego la ponderación y la aleatoriedad xD

1 respuesta
JuAn4k4

#6 Eso no es ponderar, ponderar es asignar más peso a unos items que a otros, o no según un criterio que no tiene que ver con el valor (precio).

Media ponderada donde todo tiene el mismo peso (sin ponderar vaya..)
[pera=1e, fresa=2e, melocoton=3e] =>

1+2+3 / 3 = 2

Media ponderada donde las frutas verdes pesan 3, las rojas valen 2 y las naranjas 1:
[pera=1e, fresa=2e, melocoton=3e] =>

(3*1 + 2*2 + 1*3) / 6 =1,6

Ahora te releo, intento entender el problema y edito.

#7 Sigo sin entenderte:

El fallo en el algoritmo que tengo ahora es que si he agotado las frutas de categoría 1 en la caja verde y todas las frutas rojas son de categoría 1, no podré tener ninguna roja.

¿ Como que no tienes ninguna roja ?

Algo raro haces, te explico como lo haría yo:

Tienes la lista ordenada por precio de frutas.
Tienes las 5 cajas de categoría vacias.
Tienes las 5 cajas de colores vacias.

Clases:
Caja [ tamaño = N , name = "..." ]

List<Caja> categorias = [ new Caja(10, "Categoría 1"), new Caja (20, "Categoria 2"), .... ];
Map<Color, Caja> colores = < 
"Verde" -> new Caja(100, "Caja Verde"), 
"Rojo" -> new Caja(100, "Caja Roja"), ... >;

//Recorres las frutas, rellenando las cajas de categoría:
  int categoriaIdx = 0;
foreach( fruta in frutas) {
  if (categorias[categoriaIdx].estaLlena()) {
   categoriaIdx++;
  }
  categorias[categoriaIdx].add(fruta); // Añadir a la categoría

  if (colores.get(fruta.color).estaLlena()) {
    // No se si quieres poder tener varias cajas del mismo color. en ese caso seria Map<Color, List<Caja>>
  } else {
     colores.get(fruta.color).add(fruta); // Añadir a la caja de color, si es una lista de cajas sería algo diferente..
  }
}
1 respuesta
Kiroushi

Entiendo que tu fruta es un objeto del tipo:

{
  precio: 1,
  color: "rojo"
}

?

1 respuesta
RaymaN

#8 bueno, quizá no es una definición exacta de ponderar pero me refería a repartir las frutas según su precio en 5 categorías de mayor a menor de forma exponencial.

El fallo es que, de la categoría 1 (las más caras) solo puedo coger una fruta de forma aleatoria. Si esta resulta ser verde, y todas las frutas rojas son de categoría 1, la caja de frutas rojas quedará vacía, pues no hay de categoría 2, 3, 4 o 5.

#9 sí.

1 respuesta
Kiroushi

#10 Pero es que es completamente normal que ocurra eso, no es fallo de diseño del algoritmo si no de planteamiento del problema.

Si las 20 frutas más caras son verdes, jamás vas a poder meter frutas de categoría 1 en las cajas de otro color.

¿Estás seguro de que estás planteando bien?

1 respuesta
RaymaN

#11 a ver, el planteamiento inicial me parecía correcto, normalmente son unas 500 frutas a repartir entre varias personas (máximo 20). Cuando van quedando menos empiezan a aparecer problemas así. Mi pregunta es sí podría controlar esto de alguna forma sin que afecte a la aleatoriedad de la repartición y que siga siendo equilibrada.

Kiroushi

Vamos a suponer que tienes 15 frutas.

Quieres repartirlas tal que así:

  • Categoría 1: 1 fruta
  • Categoría 2: 2 frutas
  • Categoría 3: 3 frutas
  • Categoría 4: 4 frutas
  • Categoría 5: 5 frutas

Como las ordenas por precio, no tienes problema porque puedes encajarlas de mayor a menor.

Ahora bien, vamos con los colores. Digamos que los colores son tal que:

  • Categoría 1: 1 fruta (rojo)
  • Categoría 2: 2 frutas (rojo, verde)
  • Categoría 3: 3 frutas (rojo, amarillo, amarillo)
  • Categoría 4: 4 frutas (azul, amarillo, verde, verde)
  • Categoría 5: 5 frutas (verde, amarillo, azul, azul, rojo)

Quieres repartir en las cajas con la siguiente distribución:

  • Caja frutas rojas: 2 frutas
  • Caja frutas verde: 4 frutas
  • Caja frutas amarillas: 6 frutas
  • Caja frutas azules: 3 frutas

Pero aquí se ve perfectamente que no podrías hacer coincidir ambas por las diferencias de proporciones entre piezas por caja de color, y por cantidad de frutas.

¿Podrías describir qué querrías hacer en este caso que he puesto?

1 respuesta
RaymaN

#13 el supuesto está bien planteado pero como ya dije, son 500 frutas entre máximo 20 personas, los casos problemáticos empiezan a aparecer cuando ya hay 16 o 17 personas bien repartidas.

De cualquier forma necesitaba algo urgente y decidí utilizar otra solución, olvidándome de categorías:

  • Ordeno las frutas de mayor a menor precio y las separo por color.
  • Divido cada lista de color entre el número de frutas que debe tener cada caja.

Por ejemplo, 100 frutas, 25 de cada color:

  • Rojas: 2 segmentos de 12 y 13 frutas.
  • Verdes: 4 segmentos de 6, 6, 6 y 7.
  • Amarillas: 6 segmentos de 4, 4, 4, 4, 4 y 5.
  • Azules: 3 segmentos de 8, 8 y 9.

Finalmente meto en cada caja una fruta de cada segmento.

Usuarios habituales

  • RaymaN
  • Kiroushi
  • JuAn4k4
  • eXtreM3
  • elraro
  • HeXaN