Prade Act 22
Prade Act 22
ESTRUCTURAS DE DATOS
AVANZADAS
ÍNDICE
Theory demonstration 3
Ejemplos de ejecución 7
Memoria de práctica 1
Código fuente 9
Memoria de práctica 2
Theory demonstration
The spatial cost is O(n) since the elements passed to the problem must be stored. A list
has been chosen to store the objects over which subsequent iterations are made both for sort-
ing and for selecting the objects.
La explicación matemática se basa en suponer que hay una solución factible cualquiera
del problema: Y =( y 1 , y 2 , . .. , y n ) que se compara con la solución del algoritmo voraz:
X =( x 1 , x 2 , .. . , xn ). Si demostramos que el valor de la solución X: V ( X) es mayor o igual que
el valor de la solución Y: V (Y ), se deduce que X es óptima. Entendemos lo siguiente:
tal que x j <1. Esto significa que metemos los objetos enteros hasta llegar a uno que
Memoria de práctica 3
tenemos que fraccionar, 0< x j< 1, para no pasarnos del límite de la mochila. Lo cual a su vez
implica que no se podrá introducir más objetos después del fraccionado, x i=0 para i> j .
• Como Y es una solución factible, el peso total debe ser menor o igual al límite, por tanto:
n
∑ ( x i− y i) vi ≥ 0; Sea:
i=1
n n vi
V ( X)−V (Y )= ∑ (x i− y i)v i = ∑ (x i− y i) p i
i=1 i=1 pi
Consideramos que, mientras los objetos hayan sido ordenados de forma descendiente en
relación a su valor por unidad de peso, para índices i menores que j las fracciones escogidas
de los objetos en la solución X serán mayores o iguales a las escogidas en la solución Y, que
expresamos: x i− y i ≥0 ; para índices i mayores que j se produce el caso opuesto: x i− y i ≤0 . En
todos los casos (x i− y i )(v i / pi )≥(x i− y i)(v j / p j ) por lo que:
n v j vi n
V ( X)−V (Y )≥ ∑ (x i− y i) pi = ∑ (x − y ) p
i=1 p j pi i=1 i i i
Como los valores y pesos de los objetos son positivos, el valor por unidad de peso es
positivo, quedando así:
n n n
V ( X)−V (Y )≥ ∑ ( x i− y i) pi= ∑ x i p i− ∑ y i pi
i=1 i=1 i=1
Como dijimos antes, el peso total en la mochila de la solución Y es menor que el límite y
en la solución X el peso total es exactamente igual al límite por tanto:
n n
∑ x i p i− ∑ y i p i ≥ 0
i=1 i=1
De esta manera demostramos que ninguna solución factible tiene un valor mayor que el
de la solución X y por tanto X es una solución óptima.
Memoria de práctica 4
más complejo que en la versión del problema donde se eligen los objetos enteros; que
requiere construir una tabla donde las columnas van desde 0 hasta el peso máximo de la
mochila, y en las filas representamos los objetos. Se busca la solución siguiendo:
• El método de ramificación y poda consiste en tener un árbol con las posibles soluciones al
problema, recogiendo soluciones parciales y eliminando aquellas que no satisfacen los
criterios. Al igual que el método de programación dinámica, se recorre un árbol de
posibles combinaciones de objetos, la diferencia está en que en este método se eliminan las
ramas que no cumplen con unas cotas decididas además de aquellas que no son posibles.
La poda se consigue cuando el algoritmo evalúa el nodo de la rama actual y comprueba
que no cumple con las cotas, por tanto “poda” o deja de recorrer esa rama.
Primero hay que decidir una heurística a seguir para solucionar el problema, en base a la
cual se definen la cota superior en inferior. En el caso del problema planteado, se utiliza
como heurística la búsqueda del objeto con mayor valor por unidad de peso, las cotas se
definen al principio (por ejemplo cota inferior a 0 y superior a la suma de todos los
Memoria de práctica 5
valores) y por cada nodo del árbol que se evalúa comprobamos que aporte una solución
mejor que la cota inferior, se actualiza su valor y se comprueba que no supere la cota
superior. El algoritmo irá recorriendo las ramas que apunten a una solución óptima y
llegará a una solución recorriendo un número reducido de ramas.
Rápidamente vemos que este método no es óptimo, siendo el uso más común en el caso
del problema de la mochila con objetos indivisibles, dado que el método de ramificación y
poda sólo se plantea cuando no hay una solución posible con el algoritmo voraz.
Ejemplos de ejecución
• nº de objetos -> 10
• Objetos (peso, valor) -> { (1, 5), (3, 7), (4, 6), (2, 4), (4, 5), (3, 2), (1, 4), (2, 5), (3, 5), (4,
7) }
• nº de objetos -> 5
Memoria de práctica 6
• Objetos (peso, valor) -> { (1000, 200), (2000, 600), (3000, 900), (1500, 300), (2500, 500)
}
20 1.0 74.0
21 1.0 74.0
21 1.0 73.0
20 1.0 69.0
21 1.0 72.0
21 1.0 71.0
21 1.0 66.0
22 1.0 68.0 No tiene problema con gran número de datos,
22 1.0 68.0 sigue consiguiendo el resultado óptimo en un tiempo
20 0.55 33.55 bastante corto.
668.55
Memoria de práctica 7
Código fuente
Clase mochila_voraz.java:
import java.io.File;
/**
* mochila_voraz
*/
public class mochila_voraz {
static String msg = "SINTAXIS: mochila-voraz [-t][-h] [fichero
entrada]" +
"\n-t Traza del algoritmo"
+
"\n-h Muestra este men-
saje" +
"\n[fichero de entrada] nombre del fichero de
entrada" +
"\n[fichero de salida] nombre del fichero de
salida";
switch (args.length) {
case 0:
data.setFromInputs();
result.setItems(data.getItems());
result.getResult(data.getMaxW(), false, "");
break;
case 1:
if (args[0].equals("-h")) {
System.out.println(msg);
break;
}
if (args[0].equals("-t")) {
data.setFromInputs();
Memoria de práctica 8
result.setItems(data.getItems());
result.getResult(data.getMaxW(), true, "");
} else {
if (new File(args[0]).exists()) {
data.setFromFile(args[0]);
result.setItems(data.getItems());
result.getResult(data.getMaxW(), false, "");
} else {
data.setFromInputs();
result.setItems(data.getItems());
result.getResult(data.getMaxW(), false,
args[0]);
}
}
break;
case 2:
if (args[0].equals("-t")) {
if (new File(args[1]).exists()) {
data.setFromFile(args[1]);
result.setItems(data.getItems());
result.getResult(data.getMaxW(), true, "");
} else {
data.setFromInputs();
result.setItems(data.getItems());
result.getResult(data.getMaxW(), true,
args[1]);
}
} else {
data.setFromFile(args[0]);
result.setItems(data.getItems());
result.getResult(data.getMaxW(), false,
args[1]);
}
break;
case 3:
data.setFromFile(args[1]);
result.setItems(data.getItems());
result.getResult(data.getMaxW(), true, args[2]);
break;
default:
System.err.println(
"Utilice -h para ver como ejecutar el
programa");
break;
}
}
}
Clase ResultData.java:
Memoria de práctica 9
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
Memoria de práctica 10
beneficioTotal += beneficioFraccion[contadorObj] ;
contadorObj++;
} else {
fraccionObjeto[contadorObj] = (float) (maxW -
pesoAcumulado) /
items.get(contadorObj).peso;
beneficioFraccion[contadorObj] =
items.get(contadorObj).valor *
fraccionObjeto[contadorObj];
pesoAcumulado = maxW;
beneficioTotal += beneficioFraccion[contadorObj] ;
if (traza) {
System.out.println(
"\n* El peso del objeto evaluado es: " +
items.get(contadorObj).peso +
", no podemos meterlo entero por tanto
introducimos una fraccion."
);
System.out.println(
" Con " + fraccionObjeto[contadorObj] +
" parte del objeto llenamos la mochila,
añadimos el valor equivalente " +
"a esa fraccion: \"" +
beneficioFraccion[contadorObj] +
"\".\n Alcanzamos el maximo " +
"valor que se puede introducir en la
mochila: \"" + beneficioTotal +
"\" y resolvemos el problema."
);
}
contadorObj++;
}
if (traza) {
System.out.println(
"\n- Peso de la mochila en la iteracion \"" +
contadorObj + "\": " + pesoAcumulado
);
}
}
if (fileName == "") {
if (traza) System.out.println("\nImprimimos los
resultados en consola:");
printResult(fraccionObjeto, beneficioFraccion,
beneficioTotal, contadorObj);
} else {
if (traza) System.out.println("\nIntroducimos los
resultados en el archivo" +
fileName);
resultToFile(fileName, fraccionObjeto,
beneficioFraccion, beneficioTotal, contadorObj);
}
}
Memoria de práctica 11
for (int i = 0; i < limit; i++) {
System.out.println(items.get(i).peso + " " + frac[i] + "
" + bfrac[i]);
}
System.out.println(btotal);
}
Memoria de práctica 12
Clase Item.java:
Clase ObjectData.java:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
Memoria de práctica 13
num = sc.nextInt();
int value;
int weight;
System.out.println(
"\nAhora introduzca el peso y el valor de cada
objeto por separado");
for (int i = 0; i < num; i++) {
System.out.print("peso " + (i + 1) + ": ");
weight = sc.nextInt();
System.out.print("valor " + (i + 1) + ": ");
value = sc.nextInt();
items.add(new Item(weight, value));
}
System.out.print("Por ultimo introduzca el peso maximo de la
mochila: ");
maxW = sc.nextInt();
sc.close();
}
Memoria de práctica 14